按行应用numpy非零?

按行应用numpy非零?,numpy,Numpy,我有一个2d布尔数组,我试图从中提取真值的索引。Numpy的非零函数将我的2d数组分解为x和y位置列表,这是有问题的 在保留行顺序的同时,是否可以找到true元素的列索引 列中的每个真值都在同一行中相互关联,因此将它们拆分为(行索引、列索引)对没有帮助。这可能吗 我在想,沿着轴应用可能有用 我不太明白你想要什么(也许举个例子会有帮助),但有两个猜测: 如果要查看行上是否有任何True,则: np.any(a, axis=1) 将为每行提供一个具有布尔值的数组 或者,如果要逐行获取Trues的索

我有一个2d布尔数组,我试图从中提取真值的索引。Numpy的非零函数将我的2d数组分解为x和y位置列表,这是有问题的

在保留行顺序的同时,是否可以找到
true
元素的列索引

列中的每个真值都在同一行中相互关联,因此将它们拆分为(行索引、列索引)对没有帮助。这可能吗


我在想,沿着轴应用可能有用

我不太明白你想要什么(也许举个例子会有帮助),但有两个猜测:

如果要查看行上是否有任何True,则:

np.any(a, axis=1)
将为每行提供一个具有布尔值的数组

或者,如果要逐行获取
True
s的索引,则

testarray = np.array([
    [True, False, True],
    [True, True, False],
    [False, False, False],
    [False, True, False]])

collists = [ np.nonzero(t)[0] for t in testarray ]
这使得:

>>> collists
[array([0, 2]), array([0, 1]), array([], dtype=int64), array([1])]
如果您想知道第3行的
True
列的索引,那么:

>>> collists[3]
array([1])  

没有一种纯粹基于数组的方法来实现这一点,因为每行上的项数不同。这就是为什么我们需要这些清单。另一方面,性能还不错,我使用10000 x 10000随机布尔数组进行了尝试,完成任务花费了774毫秒。

您可以使用pandas来完成此任务。下面的示例通过使用矢量化操作为您提供了每行非零元素的索引—输入数据中的每列数对应一个

import numpy as np
import pandas as pd

np.random.seed(0)

size = int(1e4), 5
d1 = pd.DataFrame(np.random.randint(5, size=size))

print(d1)

nz = pd.Series(np.count_nonzero(d1, axis=1))

max_nz = nz.max()

dfs = []
for _nz, nzdf in d1.groupby(nz, sort=False):

    nz = np.apply_along_axis(lambda r: np.nonzero(r)[0], 1, nzdf)

    mock_result = pd.DataFrame(np.ones(shape=(len(nzdf), max_nz)) - 2, index=nzdf.index)

    for i in range(nz.shape[1]):
        mock_result.iloc[:, i] = nz[:, i]

    dfs.append(mock_result)

result = pd.concat(dfs).sort_index()
print(result)
它会打印出来

      0  1  2  3  4
0     4  0  3  3  3
1     1  3  2  4  0
2     0  4  2  1  0
3     1  1  0  1  4
4     3  0  3  0  2
...  .. .. .. .. ..
9995  0  2  3  1  3
9996  3  3  2  3  1
9997  4  0  3  4  3
9998  4  2  4  0  0
9999  0  3  4  1  2

[10000 rows x 5 columns]
        0    1    2    3    4
0     0.0  2.0  3.0  4.0 -1.0
1     0.0  1.0  2.0  3.0 -1.0
2     1.0  2.0  3.0 -1.0 -1.0
3     0.0  1.0  3.0  4.0 -1.0
4     0.0  2.0  4.0 -1.0 -1.0
...   ...  ...  ...  ...  ...
9995  1.0  2.0  3.0  4.0 -1.0
9996  0.0  1.0  2.0  3.0  4.0
9997  0.0  2.0  3.0  4.0 -1.0
9998  0.0  1.0  2.0 -1.0 -1.0
9999  1.0  2.0  3.0  4.0 -1.0

[10000 rows x 5 columns]

使用这种技术,我可以大大缩短基于行的
scipy.stats.rankdata版本的运行时间。

您希望看到什么输出?数组列表,每行一个?我知道不同列号的问题。我很惊讶列表的性能如此之好。我得检查一下这条路是否够快。