2014-08-27 38 views
1

,我發現我的代碼一個奇怪的現象,但問題出在代碼波紋管numpy的recarray的花式索引丟失分配後參考

import numpy as np 

dt = dict(names = ['n1','n2'], formats = ['a8','int']) 
reca = np.recarray((10,), dtype = dt) 
reca['n1'] = ['a','b','c','d','e','f','g','e','f','g'] 
reca['n2'] = range(10) 

sreca = reca[::2] 
print sreca[0] in reca 

sreca[0]['n2'] = 12 
print sreca[0] in reca 

ireca = reca[[1,3,5,7]] 
print ireca[0] in reca 

ireca[0]['n2'] = 7 
print ireca[0] in reca 

輸出是:

True 
True 
True 
False 

據我瞭解,srecaireca應該保留reca的引用,除非我直接給它們分配新的值,但ireca在賦值後失去了引用。我不知道這是否是預期的。

任何人都可以告訴我如何避免這種情況?順便說一句,我發現代碼的小改動(例如reca['n1'] = ['a']*10)會給我所有的True這個樣本,這真的讓我感到困惑。

回答

2

recarray使用花哨的索引將數據複製到一個新的數組。相反,你可以這樣做:

ireca = [reca[i] for i in [1,3,5,7]] 

因爲只有一個項目的重新陣列保持參考。

  • print(reca[0].flags)顯示OWNDATA : False
  • print(reca[[0,1]].flags)顯示OWNDATA : True
+0

所以這意味着在這種情況下應該避免花哨的索引,並且關鍵字'in'不應該用於檢查副本是否被創建?那麼創建reca的索引視圖而不是簡單列表的方式是什麼?之後我仍然需要經常打電話給ireca ['n1']。 – guofeng 2014-08-27 17:36:55

+0

@guofeng在這種方法列表中的每個項目是你的recarray的一部分的視圖...這樣,沒有複製 – 2014-08-27 18:07:27

+0

@guofeng做了這個答案符合您的需求?如果是,我只是想提醒你可以接受答案... – 2014-08-28 10:29:18

0

您首先分配給ireca以下組件:

>>> ireca = reca[[1,3,5,7]] 
>>> ireca 
rec.array([('b', 1), ('d', 3), ('f', 5), ('e', 7)], 
     dtype=[('n1', 'S8'), ('n2', '<i8')]) 

然後分配給第一個組件在'n2'而不是17,然後你想看看它是否仍然父陣列中reca或不是,因爲第二個組件已經改變,那麼它不再在reca,所以你得到False結果。

>>> ireca[0]['n2']=7 
>>> ireca[0] 
('b', 7) 
>>> ireca 
rec.array([('b', 7), ('d', 3), ('f', 5), ('e', 7)], 
     dtype=[('n1', 'S8'), ('n2', '<i8')]) 

>>> print ireca[0] in reca 
False 
+0

,如果要更換我的4號線絲毫的recA有趣的是,['N1:當一個新的陣列已經使用flags參數創建您可以檢查'] = ['a'] * 10,你會變成真。 – guofeng 2014-08-27 16:43:04