簡體   English   中英

遍歷 Boolean Numpy 數組的 `True` 條目

[英]Iterate over `True` entries of Boolean Numpy array

我想要每個索引i的循環,其中數組X (即Boolean )為True

有沒有比在np.nditer中包裝np.nonzero更有效/pythonic 的東西,如下所示?

for i in np.nditer(np.nonzero(X), flags=['zerosize_ok']):
    myfunction(Y[i],Z2[Z[i]])

這里的問題是它迭代兩次而不是一次,並占用 memory (首先, np.nonzero遍歷X並將其存儲到一個大數組,然后np.nditer遍歷該數組)。

是否有一個命令(可以說有點類似於np.nditer )用於直接有效地迭代 Boolean 數組的True條目,而不首先使用np.nonzero明確列出它們? (遍歷所有條目並使用if語句檢查每個條目的效率可能低於 Numpy 提供的某些迭代器(如果存在)。)

人們投反對票是因為遍歷 numpy 數組的條目是一個很大的問題。 我們使用 numpy 是因為它速度很快,並且可以單獨處理每個元素,而不是一次對整個陣列進行操作,因此您可以獲得 python 級別的性能而不是 numpy/c 性能。

想要通過給出一個包含真假值的數組來排除值是很常見的,這被稱為掩碼。 你可以通過索引到真假數組來做到這一點。 要在 numpy 中做到這一點,您需要使用索引。 例如,您執行np.array([1,2,3])[np.array([True,False,True])] 它給你np.array([1, 3])

所以基本上嘗試以你可以做的方式安排事情

myfunction(Y[mask],Z2[Z[maks]]).

有幾種技術可以做到這一點。 一種方法是僅使用 numpy 函數來創建 myfunction,另一種方法是使用numba.vectorizenumba.guvectorizenumba.njit等裝飾器。

如何使用numpy.vectorise和 boolean 選擇器作為索引?

np.vectorise 接受 function 並返回接受 arrays 的 function 的矢量化版本。 然后,您可以使用選擇器在陣列或其子集上運行 function。

在 numpy 中,您可以使用數字列表使用數組的索引進行子選擇。

numpy .其中 function 返回與某個值或 function 匹配的數組的索引。

把它放在一起:

import numpy as np
import random

random.seed(0) # For repeatability

def myfunction(y, z, z2):
    return y*z2[z]

Y = np.array(range(100))  # Array of any length
Z = np.array(range(len(Y)))  # Must be the same length as Y
Z2 = np.array(range(len(Y))) # Must be constrained to indexes of X, Y and Z
X = [random.choice([True, False]) for toss in range(len(Y))] # Throw some coins

# X is now an array of True/False
# print( "\n".join(f"{n}: {v}" for n, v in enumerate(X)))
print(np.where(X)) # Where gets the indexes of True items

# Vectorise our function
vfunc = np.vectorize(myfunction, excluded={2}) # We exclude {2} as it's the Z2 array

# Do the work
res = vfunc(Y[np.where(X)],Z[np.where(X)],Z2)

# Check our work
for outpos, inpos in enumerate(np.where(X)[0]):
    assert myfunction(Y[inpos], Z[inpos], Z2) == res[outpos], f"Mismatch at in={inpos}, out={outpos}"

# Print the results
print(res)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM