数组在numpy中切片

she*_*per 6 python arrays numpy

今天我使用了numpy数组进行了一些计算,发现了一个奇怪的问题,例如,假设我已经在Ipython中导入了numpy.arange,并运行了一些脚本,如下所示:

In [5]: foo = arange(10)                                                      

In [8]: foo1 = foo[arange(3)]                                                 

In [11]: foo1[:] = 0                                                          

In [12]: foo
Out[12]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [16]: foo2 = foo[0:3]                                                      

In [19]: foo2[:]=0                                                            

In [21]: foo
Out[21]: array([0, 0, 0, 3, 4, 5, 6, 7, 8, 9])
Run Code Online (Sandbox Code Playgroud)

上面显示当我通过foo [arange(3)]对数组进行切片时,我得到了数组切片的副本,但是当我通过foo [0:3]对数组进行切片时,我得到了数组切片的引用,因此foo随foo2而变化.然后我认为foo和foo2应该有相同的id,但这似乎不是真的

In [59]: id(foo)
Out[59]: 27502608

In [60]: id(foo2)
Out[60]: 28866880

In [61]: id(foo[0])
Out[61]: 38796768

In [62]: id(foo2[0])
Out[62]: 38813248

...
Run Code Online (Sandbox Code Playgroud)

更奇怪的是,如果我继续检查foo和foo2的id,它们不是常数,有时它们确实相互匹配!

In [65]: id(foo2[0])
Out[65]: 38928592

In [66]: id(foo[0])                                                          
Out[66]: 37111504

In [67]: id(foo[0])
Out[67]: 38928592
Run Code Online (Sandbox Code Playgroud)

任何人都能解释一下吗?我对python的这个动态特性感到困惑

非常感谢

use*_*ica 5

foo[arange(3)]
Run Code Online (Sandbox Code Playgroud)

不是一片.元素arange(3)用于选择foo构造新数组的元素.由于这不能有效地返回视图(视图的每个元素都必须是一个独立的引用,并且视图上的操作需要遵循太多的指针),因此它返回一个新数组.

foo[0:3]
Run Code Online (Sandbox Code Playgroud)

是一片.这可以作为一种观点有效地完成; 它只需要调整一些界限.因此,它返回一个视图.

id(foo[0])
Run Code Online (Sandbox Code Playgroud)

foo[0]不引用特定的Python对象.为每个数组元素保留单独的Python对象太昂贵了,否定了numpy的大部分好处.相反,当在numpy ndarray上执行索引操作时,numpy构造一个要返回的新对象.每次都会得到一个具有不同ID的不同对象.

  • 您可以通过比较它们的`.base`属性来检查两个数组是否共享相同的基本内存,即在您的情况下`foo.base是foo2.base`应该评估为'True`. (2认同)