使用np.where相对较快:
>>> a
array([[0, 0, 0, 1, 1, 1, 1],
[0, 0, 0, 1, 1, 1, 1],
[0, 0, 0, 0, 1, 1, 1],
[0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0]])
>>> np.where(a>0)
(array([0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 4, 5]), array([3, 4, 5, 6, 3, 4, 5, 6, 4, 5, 6, 6, 6, 6]))
该代码提供的是包含大于0值的元组坐标。
您还可以使用np.where测试每个子数组:
def first_true1(a):
""" return a dict of row: index with value in row > 0 """
di={}
for i in range(len(a)):
idx=np.where(a[i]>0)
try:
di[i]=idx[0][0]
except IndexError:
di[i]=None
return di
输出:
{0: 3, 1: 3, 2: 4, 3: 6, 4: 6, 5: 6, 6: None}
ie, 第0行: 索引3>0; 第4行: 索引4>0; 第6行: 没有大于0的索引
正如您所怀疑的那样,argmax可能更快:
def first_true2():
di={}
for i in range(len(a)):
idx=np.argmax(a[i])
if idx>0:
di[i]=idx
else:
di[i]=None
return di
如果你能理解在所有零行中没有 None
的逻辑,这种方法会更快:
def first_true3():
di={}
for i, j in zip(*np.where(a>0)):
if i in di:
continue
else:
di[i]=j
return di
这里是使用argmax中的轴版本(根据您的评论建议):
def first_true4():
di={}
for i, ele in enumerate(np.argmax(a,axis=1)):
if ele==0 and a[i][0]==0:
di[i]=None
else:
di[i]=ele
return di
针对速度比较(以您的示例数组为例),我得出以下结果:
rate/sec usec/pass first_true1 first_true2 first_true3 first_true4
first_true1 23,818 41.986 -- -34.5
first_true2 36,377 27.490 52.7
first_true3 64,528 15.497 170.9
first_true4 79,287 12.612 232.9
如果我将其扩展到2000 X 2000的np数组,得到的结果如下:
rate/sec usec/pass first_true3 first_true1 first_true2 first_true4
first_true3 3 354380.107 -- -0.3
first_true1 3 353327.084 0.3
first_true2 11 89754.200 294.8
first_true4 23 43306.494 718.3