无法使用3D遮罩和索引为numpy数组分配值 [英] Cannot assign values to numpy array using 3D masking and indexing

查看:101
本文介绍了无法使用3D遮罩和索引为numpy数组分配值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个作为遮罩的3D阵列.另外,我有一些索引可以对应该保存一些值的位置(数组位置)进行编码.

I have an 3D array that is a mask. 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.

我看不到我在这里想念的东西.我也尝试过numpy.put,但没有运气.

I can not see what I am missing here. I have also tried numpy.put with no luck.

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

推荐答案

使用布尔掩码对数组进行索引时,将提取元素并将其放入一维数组中.这几乎是必须的情况,因为蒙版的选定元素在任何维度上在我们上的分布都不均匀.表达式results[mask] = value等效于results.__setitem__(mask, value):显然是对result的就地修改.但是results[mask][index_keep] = value等效于result.__getitem__(mask).__setitem__(index_keep, value).就地操作发生在完全丢弃的临时阵列上.

When you index an array with a boolean mask, the elements are extracted and placed into a 1-D array. 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. However results[mask][index_keep] = value is equivalent to result.__getitem__(mask).__setitem__(index_keep, value). The in-place operation happens on a temporary array that is completely discarded.

解决方案是使用索引来对想要的对象进行一次对__setitem__的调用.一种方法是将index_keep应用于mask.您首先必须将mask转换为线性索引,例如与 np.flatnonzero :

The solution is to play with the index to get a single call to __setitem__ on the object you want. One way to do that is to apply index_keep to mask. You would first have to convert mask to linear indices, e.g. with np.flatnonzero:

result.ravel()[np.flatnonzero(mask)[index_keep]] = value

只要 ravel 返回一个视图,在大多数情况下应该如此.如果result是连续数组,则它将一直有效.如果result已经是更大数组的子集,它将无法正常工作.

This will work as long as ravel returns a view, which it should in most cases. If result is a contiguous array, this will work all the time. It wont work if result is already a subset of a larger array.

此方法的优势在于,它仅使用单个索引数组,并且适用于任意数量的维度.使用np.where可以进行相同的操作,但是需要更多的临时存储.缺点当然是这种方法仅限于连续数组.

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. The disadvantage is of course that this approach is limited to contiguous arrays.

P.S.您几乎可以肯定不需要复制value.它的元素不会被修改,并且赋值将使副本进入result的适当位置.制作副本只会创建一个不必要的临时数组,该数组将立即丢弃.

P.S. You almost certainly don't need to copy value. Its elements won't be modified, and the assignment will already make the copy into the appropriate locations of result. Making a copy just creates a needless temporary array that will be discarded immediately.

这篇关于无法使用3D遮罩和索引为numpy数组分配值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆