Python 为什么替换numpy数组中的值并不总是有效
我尝试使用以下命令替换/覆盖数组中的值:Python 为什么替换numpy数组中的值并不总是有效,python,arrays,numpy,overwrite,Python,Arrays,Numpy,Overwrite,我尝试使用以下命令替换/覆盖数组中的值: import numpy as np test = np.array([[4,5,0],[0,0,0],[0,0,6]]) test Out[20]: array([[4., 5., 0.], [0., 0., 0.], [0., 0., 6.]]) test[np.where(test[...,0] != 0)][...,1:3] = np.array([[10,11]]) test Out[22]: array([[4.
import numpy as np
test = np.array([[4,5,0],[0,0,0],[0,0,6]])
test
Out[20]:
array([[4., 5., 0.],
[0., 0., 0.],
[0., 0., 6.]])
test[np.where(test[...,0] != 0)][...,1:3] = np.array([[10,11]])
test
Out[22]:
array([[4., 5., 0.],
[0., 0., 0.],
[0., 0., 6.]])
但是,正如在Out22中所看到的,阵列测试尚未修改。因此,我的结论是,不可能简单地覆盖数组的一部分或几个单元格
然而,在其他上下文中,可以覆盖数组中的几个单元格。例如,在以下代码中:
test = np.array([[1,2,0],[0,0,0],[0,0,3]])
test
Out[11]:
array([[1., 2., 0.],
[0., 0., 0.],
[0., 0., 3.]])
test[test>0]
Out[12]:
array([1., 2., 3.])
test[test>0] = np.array([4,5,6])
test
Out[14]:
array([[4., 5., 0.],
[0., 0., 0.],
[0., 0., 6.]])
因此,我有两个问题:
1-为什么第一个命令
test[np.where(test[...,0] != 0)][...,1:3] = np.array([10,11])
不允许修改阵列测试?为什么不允许访问阵列单元并覆盖它们
2-考虑到我的代码需要使用上面的命令选择单元格,我如何使其工作
非常感谢 我给你做一个。这确实有效:
为什么??它是两个因素的组合-numpy
索引和\uuuuuu setitem\uuuuuu
调用
python
解释器有点向后读取行。当它到达=
时,它会尝试调用最左边的\uuuuu setitem\uuuuuu
\uuuu setitem\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
现在,当我们在numpy
中建立索引时,我们有三种基本方法可以做到这一点
- 切片(返回视图)
- “高级索引”(返回副本)
- “简单索引”(还返回副本)
“高级”索引和“简单”索引之间的一个主要区别是numpy
数组的\uuuu setitem\uuuu
函数可以解释高级索引。而视图
意味着数据地址是相同的,因此我们不需要\uuuu setitem\uuuu
来访问它们
因此:
但是,由于np.where(test[…,0]!=0)
是一个高级索引
,(test[np.where(test[…,0]!=0)])
返回一个副本,该副本将丢失,因为它从未分配过。它确实获取了我们想要的元素并将它们设置为[10,11]
,但是结果会丢失在缓冲区的某个地方
如果我们这样做:
test[..., 1:3][np.where(test[..., 0] != 0)] = np.array([[10, 11]]) #is intepreted as
(test[..., 1:3]).__setitem__( np.where(test[...,0] != 0), np.array([[10,11]]) )
test[…,1:3]
是一个视图,因此它仍然指向相同的内存。现在setitem
在test[…,1:3]
中查找对应于np.where(test[…,0]!=0)
的位置,并将它们设置为np.array([[10,11]])
。一切正常
您也可以这样做:
test[np.where(test[...,0] != 0), 1:3] = np.array([10, 11])
现在,因为所有的索引都在一组括号中,所以它对这些索引调用test.\uuuuuu setitem\uuuuuuu
,这也正确地设置了数据
更简单的(也是最具Python风格的)是:
test[test[...,0] != 0, 1:3] = np.array([10,11])
测试[where…]
步骤复制一份。下面的[…]=…
修改该副本,而不是原始副本。视图
传递更改,但不传递副本。
test[..., 1:3][np.where(test[..., 0] != 0)] = np.array([[10, 11]]) #is intepreted as
(test[..., 1:3]).__setitem__( np.where(test[...,0] != 0), np.array([[10,11]]) )
test[np.where(test[...,0] != 0), 1:3] = np.array([10, 11])
test[test[...,0] != 0, 1:3] = np.array([10,11])