[英]Cannot assign values to numpy array using 3D masking and indexing
I have an 3D array that is a mask. 我有一个3D数组是一个掩码。 Additionally, I have some indices that encode where (array position) some values should be saved.
另外,我有一些索引编码哪些(数组位置)应该保存一些值。
Everything seems to be working fine, except that the output matrix is still empty after assigning the values to the desired positions. 除了在将值分配到所需位置后输出矩阵仍为空时,一切似乎都正常工作。
I can not see what I am missing here. 我看不出我在这里缺少什么。 I have also tried
numpy.put
with no luck. 我也试过
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
When you index an array with a boolean mask, the elements are extracted and placed into a 1-D array. 使用布尔掩码索引数组时,将提取元素并将其放入1-D数组中。 This pretty much had to be the case, since the selected elements of the mask are not evenly space across our within any dimension.
这几乎必须如此,因为蒙版的选定元素在任何维度内都不是均匀的空间。 The expression
results[mask] = value
is equivalent to results.__setitem__(mask, value)
: clearly an in-place modification on result
. 表达式
results[mask] = value
等效于results.__setitem__(mask, value)
:显然是对result
的就地修改。 However results[mask][index_keep] = value
is equivalent to result.__getitem__(mask).__setitem__(index_keep, value)
. 但是
results[mask][index_keep] = value
等于result.__getitem__(mask).__setitem__(index_keep, value)
。 The in-place operation happens on a temporary array that is completely discarded. 就地操作发生在完全丢弃的临时数组上。
The solution is to play with the index to get a single call to __setitem__
on the object you want. 解决方案是使用索引来对所需对象进行
__setitem__
的单次调用。 One way to do that is to apply index_keep
to mask
. 一种方法是将
index_keep
应用于mask
。 You would first have to convert mask
to linear indices, eg with np.flatnonzero
: 您首先必须将
mask
转换为线性索引,例如使用np.flatnonzero
:
result.ravel()[np.flatnonzero(mask)[index_keep]] = value
This will work as long as ravel
returns a view, which it should in most cases. 只要
ravel
返回一个视图,这将在大多数情况下应该工作。 If result
is a contiguous array, this will work all the time. 如果
result
是一个连续的数组,这将一直有效。 It wont work if result
is already a subset of a larger array. 如果
result
已经是更大数组的子集,它将无法工作。
This approach has the advantage that it uses only a single index array, and it works for any number of dimensions. 这种方法的优点是它只使用一个索引数组,并且适用于任意数量的维度。 Using
np.where
could be adapted to do the same, but would require more temporary storage. 使用
np.where
可以适应相同的操作,但需要更多的临时存储。 The disadvantage is of course that this approach is limited to contiguous arrays. 当然,缺点是这种方法仅限于连续的阵列。
PS You almost certainly don't need to copy value
. PS你几乎肯定不需要复制
value
。 Its elements won't be modified, and the assignment will already make the copy into the appropriate locations of result
. 其元素不会被修改,并且赋值已经将副本放入
result
的适当位置。 Making a copy just creates a needless temporary array that will be discarded immediately. 制作副本只会创建一个不必要的临时数组,它将立即被丢弃。
You can use numpy.where
on your mask
, which will allow you to get a view of your results
array to index. 您可以在
mask
上使用numpy.where
,这样您就可以获得results
数组的视图以进行索引。
x, y, z = np.where(mask)
results[x[index_keep], y[index_keep], z[index_keep]] = values
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.