数组在numpy中切片

时间:2013-10-25 23:46:27

标签: 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])

上面显示当我通过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

...

更奇怪的是,如果我继续检查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

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

非常感谢

1 个答案:

答案 0 :(得分:5)

foo[arange(3)]

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

foo[0:3]

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

id(foo[0])

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