gpt4 book ai didi

python - 在 numpy 中查找第一个非零行

转载 作者:太空宇宙 更新时间:2023-11-03 14:37:18 26 4
gpt4 key购买 nike

假设我们有像a 这样的数组,我们想在其中找到第一个非零行。 a 可以很大,即单 channel 图像。

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

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

在 numpy 中最快最优雅的方法是什么?

现在我是这样做的:

row_idx = np.argmin(np.sum(a, axis=1)==0)

最佳答案

这是一个非常快速但只适用于连续数组的方法(见下页)。它使用 View 转换来 bool 并利用短路。在下面的比较中,我冒昧地修正了其他答案,因此它们可以正确处理全零输入。

结果:

                                pp    galaxyan  WeNYoBen1  WeNYoBen2
contiguous small sparse 1.863220 1.465050 3.522510 4.861850
large dense 2.086379 865.158230 68.337360 42.832701
medium 2.136710 726.706850 71.640330 43.047541
sparse 11.146050 694.993751 71.333189 42.406949
non cont. small sparse 1.683651 1.516769 3.193740 4.017490
large dense 55.097940 433.429850 64.628370 72.984670
medium 60.434350 397.200490 67.545200 51.276210
sparse 61.433990 387.847329 67.141630 45.788040

代码:

import numpy as np

def first_nz_row(a):
if a.flags.c_contiguous:
b = a.ravel().view(bool)
res = b.argmax()
return res // (a.shape[1]*a.itemsize) if res or b[res] else a.shape[0]
else:
b = a.astype(bool).ravel()
res = b.argmax()
return res // a.shape[1] if res or b[res] else a.shape[0]

def use_nz(a):
b = np.nonzero(a)[0]
return b[0] if b.size else a.shape[0]

def any_max(a):
b = a.any(1)
res = b.argmax()
return res if res or b[res] else a.shape[0]

def max_max(a):
b = a.max(1).astype(bool)
res = b.argmax()
return res if res or b[res] else a.shape[0]

from timeit import timeit


A = [np.random.uniform(-R, 1, (N,M)).clip(0,None)
for R,N,M in [[100,2,2], [10,100,1000], [1000,100,1000], [10000,100,1000]]]
t = 10000*np.array(
[[timeit(f, number=100) for f in (lambda: first_nz_row(a),
lambda: use_nz(a),
lambda: any_max(a),
lambda: max_max(a))]
for a in A] +
[[timeit(f, number=100) for f in (lambda: first_nz_row(a),
lambda: use_nz(a),
lambda: any_max(a),
lambda: max_max(a))]
for a in [a[:,::2] for a in A]])

import pandas as pd
index = "dense medium sparse".split()
index = pd.MultiIndex([['contiguous', 'non cont.'], ['small', 'large'], index], [np.repeat((0,1),4), np.repeat((0,1,0,1,),(1,3,1,3)), np.r_[2, :3, 2, :3]])
t = pd.DataFrame(t, columns="pp galaxyan WeNYoBen1 WeNYoBen2".split(), index=index)
print(t)

关于python - 在 numpy 中查找第一个非零行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56926706/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com