我有一个作为遮罩的3D阵列。另外,我有一些索引可以对应该保存一些值(数组位置)的位置进行编码。
除了将值分配给所需位置后输出矩阵仍然为空之外,一切似乎都工作正常。
我看不到我在这里想念的东西。我也尝试过numpy.put
,但没有运气。
import numpy as np
# Initialize output matrix (here the results will be stored)
results = np.zeros((67, 67, 45))
# define the mask - where to put the calculated values in the results array
mask = np.random.randint(2, size=(67, 67, 45)).astype(bool)
# store the results only in these positions
index_keep = range(0, 13732)
values = np.ones((13732,))
results[mask][index_keep] = values.copy()
# the results array is still empty
print(results.sum())
#0
答案 0 :(得分:3)
使用布尔掩码对数组进行索引时,将提取元素并将其放置到一维数组中。这几乎是必须的情况,因为蒙版的选定元素在任何维度上在我们上的分布都不均匀。表达式results[mask] = value
等效于results.__setitem__(mask, value)
:显然是对result
的就地修改。但是results[mask][index_keep] = value
等效于result.__getitem__(mask).__setitem__(index_keep, value)
。就地操作发生在完全丢弃的临时阵列上。
解决方案是处理索引,以单次调用所需对象上的__setitem__
。一种实现方法是将index_keep
应用于mask
。您首先必须将mask
转换为线性索引,例如与np.flatnonzero
:
result.ravel()[np.flatnonzero(mask)[index_keep]] = value
只要ravel
返回一个视图(在大多数情况下都应如此),此方法就起作用。如果result
是一个连续的数组,那么它将一直有效。如果result
已经是较大数组的子集,则无法使用。
此方法的优势在于它仅使用单个索引数组,并且可用于任意数量的维。使用np.where
可以做到相同,但需要更多的临时存储。缺点当然是这种方法仅限于连续数组。
P.S。您几乎肯定不需要复制value
。它的元素将不会被修改,并且赋值已经将副本复制到result
的适当位置。制作副本只会创建一个不必要的临时数组,该数组将立即丢弃。
答案 1 :(得分:2)
您可以在numpy.where
上使用mask
,这将使您可以查看results
数组的视图以建立索引。
x, y, z = np.where(mask)
results[x[index_keep], y[index_keep], z[index_keep]] = values