如何从 python 中没有 for 循环的稀疏矩阵中随机 select 每行一个非零元素

How to randomly select one nonzero element per row from a sparse matrix with out for loop in python

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

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

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

numpyarray如:

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

你可以做 arr != 0 这将给出一个 True / False array 的值通过条件所以在我们的例子中,值是 不等于!=)到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 值,我们可以对每个 row 做一个简单的 list comprehension ] 在你的 a array 中。对于每个 row,我们删除 zeros,然后在 array 上执行 random.choice。因此:

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

返回一个 length 3 数组,其中包含 a 中每个 rowrandom non-zero 项。 :)

希望对您有所帮助!

更新

如果你想要arrayrandomnon-zero个号码的indexes,你可以使用.nonzero().

所以如果我们有这个 array:

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

我们可以做到:

arr.nonzero()

给出 non-zero indexestuple 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])

其中 return 是 [x, y, z] 形式的 array,其中 xyzrandom indexesnon-zero 个元素来自其对应的 rows

例如一个结果可能是:

array([1, 4, 2])

并且如果您希望它也 return 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]])

希望这能如你所愿:)