【问题标题】:How to randomly select one nonzero element per row from a sparse matrix with out for loop in pythonpython - 如何在没有for循环的稀疏矩阵中随机选择每行一个非零元素
【发布时间】:2017-10-03 14:56:54
【问题描述】:

我有一个大的稀疏矩阵,它的每一行都包含多个非零元素,例如

a = np.array([[1, 1,0,0,0,0], [2,0, 1,0,2,0], [3,0,4,0,0, 3]])

我希望能够在没有 for 循环的情况下每行随机选择一个非零元素。有什么好的建议吗?作为输出,我对所选元素的索引比它的值更感兴趣。

【问题讨论】:

  • 请添加您尝试过的内容。
  • 我使用了 numpy.nonzero 命令但无法摆脱 for 循环。

标签: python sparse-matrix zero rowwise


【解决方案1】:

numpyarray 如:

arr = np.array([5, 2, 6, 0, 2, 0, 0, 6])

你可以做arr != 0,这将给出一个True/Falsearray的通过条件的值,所以在我们的例子中,这些值不等于 (@987654328 @) 到0。所以:

array([ True,  True,  True, False,  True, False, False,  True], dtype=bool)

从这里,我们可以通过 'index' arr 使用 boolean array arr[arr != 0] 这给了我们:

array([5, 2, 6, 2, 6])

既然我们有办法从numpy array 中删除non-zero 值,我们可以在a array 中的每个row 上执行一个简单的list comprehension。对于每个row,我们删除zeros,然后对array 执行random.choice。因此:

np.array([np.random.choice(r[r!=0]) for r in a])

它会返回一个 length 3 数组,其中包含 a 中每个 row 中的 random non-zero 项。 :)

希望这会有所帮助!

更新

如果您想要randomnon-zero 数字中的indexes array,可以使用.nonzero()

如果我们有这个array:

arr = np.array([5, 2, 6, 0, 2, 0, 0, 6])

我们可以做到:

arr.nonzero()

这给出了indexesnon-zerotuple elements

(array([0, 1, 2, 4, 7]),)

和以前一样,我们可以在list-comprehension 中使用这个和np.random.choice() 来产生随机的indexes

a = np.array([[1, 1, 0, 0, 0, 0], [2, 0, 1, 0, 2, 0], [3, 0, 4, 0, 0, 3]])

np.array([np.random.choice(r.nonzero()[0]) for r in a])

它返回 [x, y, z] 形式的 array,其中 xyzrandom indexesnon-zero 元素来自它们对应的 rows

例如一个结果可能是:

array([1, 4, 2])

如果您希望它也返回 rows,您可以在 a 的长度上添加一个 numpy.arrange() 调用,以获得 arrayrow 数字:

([np.arange(len(a))], np.array([np.random.choice(r.nonzero()[0]) for r in a]))

因此,random 输出示例可能是:

([array([0, 1, 2])], array([1, 2, 5]))

a 为:

array([[1, 1, 0, 0, 0, 0],
       [2, 0, 1, 0, 2, 0],
       [3, 0, 4, 0, 0, 3]])

希望这能满足你的需求:)

【讨论】:

  • 谢谢你,乔,这很有帮助。我对非零元素的索引更感兴趣,因此感兴趣的输出将是非零元素的索引(每行一个非零元素)
  • @aminamollaysa 因为你有一个2 dimensional array 在这里,你喜欢indicies 吗?作为tuples?价值观本身?哦,我知道您是该网站的新手,但如果此答案有帮助,您可以通过投票(小箭头):) 显示
  • 是的,如果我们每行随机选择一个元素,我希望输出是所选元素的索引,例如:输出可以是 [c, d] 其中 c = [0, 1 , 2 ](行索引,其实很明显)d = [0, 4, 2](列索引),简单来说,我只需要列索引,因为我们为每一行选择了一个元素。
  • @aminamollaysa 我现在使用.nonzero() 更新了答案。它现在应该做你想做的事
  • Joe,非常感谢,它超级清晰,非常有帮助。感谢您的宝贵时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-16
  • 1970-01-01
  • 1970-01-01
  • 2018-11-12
相关资源
最近更新 更多