2016-10-22 58 views
1

這裏發生了什麼?看起來陣列的id位置可能不穩定?運算符即使認爲id相同也會返回False。然後在打印數組後,元素的ID正在改變。任何解釋?numpy數組更改ID

import numpy as np 
a = np.arange(27) 
b = a[1:5] 
a[0] is b[1] #False 
id(a[0]) #40038736L 
id(b[1]) #40038736L 
a #prints the array 
id(b[1]) #40038712L 
id(a[0]) #40038712L 
b[0] #1 
a[1] #1 
id(b[0]) #40038712L 
id(a[1]) #40038784L 
+2

這可能適用於包含指向對象的指針的列表。但是一個數組將數值存儲在數據緩衝區中。 'a [2]'是一個引用該緩衝區的新對象,但它的'id'與'a'或databuffer無關。所以'id'在處理數組時無用。 – hpaulj

+0

http://stackoverflow.com/questions/3877230/why-does-id-id-and-id-id-in-cpython的半重複。我希望我們有一個「分割重複」功能。 – user2357112

回答

1

與列表第一次測試:

In [1109]: a=[0,1,2,3,4] 
In [1112]: b=a[1:3] 

In [1113]: id(a[1]) 
Out[1113]: 139407616 
In [1114]: id(b[0]) 
Out[1114]: 139407616 

In [1115]: a[1] is b[0] 
Out[1115]: True 

後來我試着

In [1129]: id(1) 
Out[1129]: 139407616 

所以在a[1]對象是一致的整數1(整數id是有點棘手,並依賴於實現)。

但是以與陣列:

In [1118]: aa=np.arange(5) 
In [1119]: ba=aa[1:] 

In [1121]: aa[1] 
Out[1121]: 1 
In [1122]: ba[0] 
Out[1122]: 1 
In [1123]: id(aa[1]) 
Out[1123]: 2925837264 
In [1124]: id(ba[0]) 
Out[1124]: 2925836912 

id是完全不同的;事實上,他們與每個接入改變:

In [1125]: id(aa[1]) 
Out[1125]: 2925837136 
In [1126]: id(ba[0]) 
Out[1126]: 2925835104 

這是因爲aa[1]不僅僅是整數1。這是一個np.int32對象。

In [1127]: type(aa[1]) 
Out[1127]: numpy.int32 

相反到列表,數組的值存儲爲在databuffer字節。 b[1:]view並訪問相同的數據緩衝區。但a[1]是一個新的對象,它包含對該數據緩衝區的引用。與列表案例相反,a[1]不是a中的第二個對象。

一般而言,id在處理數組時無用,is測試也沒有用。使用==isclose(用於浮標)。

================

看的一種方法,其中被存儲的aa的值是與:

In [1137]: aa.__array_interface__ 
Out[1137]: 
{'data': (179274256, False),  # 'id' so to speak of the databuffer 
'descr': [('', '<i4')], 
'shape': (5,), 
'strides': None, 
'typestr': '<i4', 
'version': 3} 
In [1138]: ba.__array_interface__ 
Out[1138]: 
{'data': (179274260, False), # this is 4 bytes larger 
'descr': [('', '<i4')], 
'shape': (4,), 
'strides': None, 
'typestr': '<i4', 
'version': 3} 

data指針的2陣列是相關的,因爲baview

aa[1]是數組狀態,也有數據緩衝區,但它不是視圖。

In [1139]: aa[1].__array_interface__ 
Out[1139]: 
{'__ref': array(1), 
'data': (182178952, False), 
...} 
+0

你想介紹一下爲什麼id每次訪問aa會改變一下[1]。它是否被垃圾收集並重新創建,每次調用id時都會被調用? –

+0

這不是垃圾收集的問題。 'aa [1]'由方法調用產生,'aa .__ getitem __((1))'。它每次創建一個新的'np.int32'對象。 – hpaulj