假设我有一个NumPy数组,其形状(50,10000,10000)具有1000个不同的“簇”。例如,只有1s的小音量,2s的另一个小音量等等。我想迭代每个簇来创建一个像这样的掩码:
for i in np.unique(arr)[1:]:
mask = arr == i
#do other stuff with mask
创建每个掩码大约需要15秒,迭代1000个集群需要4个多小时。有没有一种方法可以加速代码,或者这是最好的,因为没有避免迭代遍历数组的每个元素?
编辑:数组的dtype是uint16
答案 0 :(得分:1)
我假设arr
稀疏:
np.unique(arr)[1:]
,所以我假设第一个唯一值为0
在这种情况下,我建议利用scipy.sparse.csr_matrix
from scipy.sparse import csr_matrix
sp_arr = csr_matrix(arr.reshape(1,-1))
这会将您的大密集数组转换为单行压缩稀疏行数组。由于稀疏数组不喜欢2个以上的维度,因此使用了ravelled索引。现在sp_arr
有data
(群集标签),indices
(被碾压的索引)和indptr
(这里很简单,因为我们只有一行)。所以,
for i in np.unique(sp_arr.data): # as a bonus this `unique` call should be faster too
x, y, z = np.unravel_index(sp_arr.indices[sp_arr.data == i], arr.shape)
应该更有效地给出等效坐标
for i in np.unique(arr)[:1]:
x, y, z = np.nonzero(arr == i)
其中x, y, z
是True
中mask
值的索引。从那里你可以重建mask
或处理索引(推荐)。
您也可以使用numpy
完全执行此操作,并且最后仍然有一个布尔掩码,但内存效率会降低一点:
all_mask = arr != 0 # points assigned to any cluster
data = arr[all_mask] # all cluster labels
for i in np.unique(data):
mask = all_mask.copy()
mask[mask] = data == i # now mask is same as before