Python 无法使用三维遮罩和索引将值指定给numpy数组
我有一个3D阵列,它是一个遮罩。此外,我还有一些索引,用于编码某些值应该保存的位置(数组位置) 除了将值分配到所需位置后,输出矩阵仍然为空之外,一切似乎都正常工作 我看不出我在这里遗漏了什么。我也试过numpy.put,但运气不好Python 无法使用三维遮罩和索引将值指定给numpy数组,python,numpy,mask,masking,matrix-indexing,Python,Numpy,Mask,Masking,Matrix Indexing,我有一个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 -
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.\uuuuu setitem\uuuuu(mask,value)
:显然是对result
的就地修改。但是,results[mask][index\u keep]=value
相当于result.\uuuuuu getitem\uuuuuuuuuuu(mask)。\uuuuu setitem\uuuuuuuuuuuuuu(index\u keep,value)
。就地操作发生在完全丢弃的临时阵列上
解决方案是使用索引来获得对所需对象的\uuuuu setitem\uuuu
的单个调用。一种方法是将index\u keep
应用于mask
。首先必须将掩码
转换为线性索引,例如:
只要返回一个视图(在大多数情况下应该是这样的),这就可以工作。如果result
是一个连续数组,则该操作将一直有效。如果result
已经是一个较大数组的子集,则它将不起作用
这种方法的优点是,它只使用一个索引数组,并且适用于任意数量的维度。使用np.where
也可以进行调整,但需要更多的临时存储。缺点当然是这种方法仅限于连续数组
另外,您几乎肯定不需要复制
值。它的元素不会被修改,分配将已经将副本复制到result
的适当位置。制作副本只会创建一个不必要的临时数组,该数组将立即被丢弃。您可以在掩码上使用numpy.where
,这将允许您查看要索引的结果
x, y, z = np.where(mask)
results[x[index_keep], y[index_keep], z[index_keep]] = values
results[mask][index\u keep]
是数组的一个副本,这就是为什么您在result
中没有看到任何更改的原因真的吗?在其他情况下,results[mask]=values.copy()
对我有效,但是,results[mask][index\u keep]=values.copy()
失败。那我怎么做呢?太棒了。非常感谢。我接受答案。我知道我返回的副本,但找不到使用这些双索引方法来分配我的值的方法,ravel
主要返回一个视图(:@piRSquared.Yep。它尽最大努力获取指向缓冲区的指针,并适当设置步幅。不过,我不确定它对切片的影响有多大。例如,np.arange(12)。重塑(4,3)[:,::2]。ravel()
不能是视图,但np.arange(12)。重塑(3,4)[:,::2]
可以。我只是不确定它是否会。据我所知,ravel
保证了一个连续的结果,因此它只会在数组开始时是连续的情况下给你一个视图。你可以始终检查arr.ravel()。base是None
vsarr.ravel().base是arr
,用于副本与视图。就答案而言,一个关键组件是布尔索引数组总是触发奇特的索引,从而创建副本。例如,如果第一次订阅使用了切片,则双索引分配会起作用。这对其他读者来说可能不明显。(cc@piRSquared)@我对另一个答案的最后一点评论有帮助吗?对于一个简单的应用程序,这实际上是一种更易于维护和易读的方法
x, y, z = np.where(mask)
results[x[index_keep], y[index_keep], z[index_keep]] = values