2011-10-05 95 views
7

我最近遇到了使用例如創建Numpy對象數組時遇到的問題。Numpy對象數組

a = np.array([c], dtype=np.object) 

其中c是一些複雜的類的實例,在某些情況下與NumPy試圖訪問類的一些方法。但是,這樣做:

a = np.empty((1,), dtype=np.object) 
a[0] = c 

解決了這個問題。我很好奇內部這兩者之間有什麼不同。爲什麼在第一種情況下,Numpy可能會嘗試訪問c的某些屬性或方法?

編輯:爲了記錄在案,這裏是示例代碼演示問題:

import numpy as np 

class Thing(object): 

    def __getitem__(self, item): 
     print "in getitem" 

    def __len__(self): 
     return 1 

a = np.array([Thing()], dtype='object') 

此打印出getitem兩次。基本上,如果__len__出現在課堂上,那麼這是人們可能遇到意想不到的行爲。

+0

沒有關係的,但是爲什麼'np.object'並不僅僅是'object'? – JBernardo

+0

這兩者是等價的(''object == np.object''返回''True''),所以這與我所看到的問題無關。 – astrofrog

+1

@astrofog這就是爲什麼我問,並說它不相關。 – JBernardo

回答

9

在第一種情況下a = np.array([c], dtype=np.object),numpy對預期數組的形狀一無所知。

例如,當你定義

d = range(10) 
a = np.array([d]) 

然後,你希望numpy的確定基於對d長度的形狀。

因此,在你的情況下,numpy會嘗試查看是否定義了len(c),如果是,則通過c[i]訪問c的元素。

您可以通過定義一個類看到效果如

class X(object): 
    def __len__(self): return 10 
    def __getitem__(self, i): return "x" * i 

然後

print numpy.array([X()], dtype=object) 

產生

[[ x xx xxx xxxx xxxxx xxxxxx xxxxxxx xxxxxxxx xxxxxxxxx]] 

相反,在你的第二個案例

a = np.empty((1,), dtype=np.object) 
a[0] = c 

然後a的形狀已經確定。因此numpy可以直接分配對象。

但是在某種程度上這是真的,因爲a是一個向量。如果它已被定義爲不同的形狀,那麼方法訪問仍然會發生。下面例如仍將調用___getitem__一類

a = numpy.empty((1, 10), dtype=object) 
a[0] = X() 
print a 

回報

[[ x xx xxx xxxx xxxxx xxxxxx xxxxxxx xxxxxxxx xxxxxxxxx]] 
+0

這正是我所需要的 - 基本上如果定義了'__len__'',那就是當我遇到問題! – astrofrog