[英]Find first non-zero row in numpy
假設我們有像a
一樣a
數組,我們想在其中找到第一個非零行。 a
可以很大,即單通道圖像。
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)
這是一個方法(下面的pp),它非常快,但只適用於連續的數組。 它使用視圖轉換來加速並利用短路。 在下面的比較中,我冒昧地修復了其他答案,因此他們可以正確處理全零輸入。
結果:
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)
非零將查找所有項目不為零並返回行/列號
np.nonzero(a)[0][0]
2
我將要做的
a.any(1).argmax()
2
要么
a.max(1).astype(bool).argmax()
2
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.