2015-01-14 54 views
3

我有一些無法理解爲什麼下面不工作:numpy的D型錯誤 - (結構數組創建)

np.dtype(dict(names="10", formats=np.float64)) 

我一直在苦苦掙扎,是因爲我想獲得的recfunctions功能numpy到工作,但由於與numpy.dtype問題,我沒有成功。這是我目前收到的錯誤:

dtype = np.dtype(dict(names=names, formats=formats)) 
ValueError: all items in the dictionary must have the same length. 

我想要得到的數據結構將包含每個分配領域中的一個類型記錄陣列與多列數據的 - 類似於字典,其中每個值是一個二維數組或幾列數據。通常情況下,數據可能最終爲〜6列,每個密鑰或記錄約〜2000行,約200條記錄。

這是我曾嘗試在一個完整的腳本:(雖然仍給予同樣的錯誤)

import numpy as np 
from numpy.lib import recfunctions 


# Just function to make random data 
def make_data(i, j): 
    # some arbitrary function to show that the number of columns may change, but rows stay the same length 
    if i%3==0: 
     data = np.array([[i for i in range(0,1150)]*t for t in range(0,3)]) 
    else: 
     data = np.array([[i for i in range(0,1150)]*t for t in range(0,6)]) 
    return data 

def data_struct(low_ij, high_ij): 

    """ 
    Data Structure to contain several columns of data for different combined values between "low ij" and "high ij" 

    Key: "(i, j)" 
    Value: numpy ndarray (multidimensional) 
    """ 

    for i in range(0,low_ij+1): 
     for j in range(0,high_ij+1): 
      # Get rid of some of the combinations 
      # (unimportant) 
      if(i<low_ij and j<low_ij): 
       break 
      elif(i<j): 
       break 

      # Combinations of interest to create structure 
      else: 
       names = str(i)+str(j) 
       formats = np.float64 
       data = np.array(make_data(i, j)) 
       try: 
        data_struct = recfunctions.append_fields(base=data_struct, names=names, data=data, dtypes=formats) 
       # First loop will assign data_struct using this exception, 
       # then proceed to use the try statement to add on the rest of the data 
       except UnboundLocalError: 
        dtype = np.dtype(dict(names=names, formats=formats)) 
        data_struct = np.array(data, dtype=dtype) 

    return data_struct 

回答

1

貌似你試圖構建一個結構數組是這樣的:

In [152]: names=['1','2','3','4'] 
In [153]: formats=[(float,2),(float,3),(float,2),(float,3)] 
In [154]: dt=np.dtype({'names':names, 'formats':formats}) 
In [156]: ds=np.zeros(5, dtype=dt) 

In [157]: ds 
Out[157]: 
array([([0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0], [0.0, 0.0, 0.0]), 
     ([0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0], [0.0, 0.0, 0.0]), 
     ([0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0], [0.0, 0.0, 0.0]), 
     ([0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0], [0.0, 0.0, 0.0]), 
     ([0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0], [0.0, 0.0, 0.0])], 
     dtype=[('1', '<f8', (2,)), ('2', '<f8', (3,)), ('3', '<f8', (2,)), 
      ('4', '<f8', (3,))]) 
In [159]: ds['1']=np.arange(10).reshape(5,2) 
In [160]: ds['2']=np.arange(15).reshape(5,3) 

在其他字,多個字段,每個字段具有不同數量的「列」(形狀)。

這裏我創建初始化整個數組,然後單獨填寫字段。這似乎是創建複雜結構化數組的最直接的方法。

您正在嘗試逐步建立這樣的陣列,從一個領域,並與recfunctions.append_fields

In [162]: i=1; 
    ds2 = np.array(np.arange(5),dtype=np.dtype({'names':[str(i)],'formats':[float]})) 
In [164]: i+=1; 
    ds2=recfunctions.append_fields(base=ds2,names=str(i),dtypes=float, 
     data=np.arange(5), usemask=False,asrecarray=False) 
In [165]: i+=1; 
    ds2=recfunctions.append_fields(base=ds2,names=str(i),dtypes=float, 
     data=np.arange(5), usemask=False,asrecarray=False) 

In [166]: ds2 
Out[166]: 
array(data = [(0.0, 0.0, 0.0) (1.0, 1.0, 1.0) (2.0, 2.0, 2.0) 
    (3.0, 3.0, 3.0) (4.0, 4.0, 4.0)], 
    dtype = [('1', '<f8'), ('2', '<f8'), ('3', '<f8')]) 

這工作時,附加的領域均具有1「列」添加新的。通過掩蔽,他們甚至可以有不同數量的「行」。但是,當我嘗試改變內部形狀時,它在附加該領域時存在問題。 marge_arrays不是更成功。

即使我們可以得到增量recfunctions方法的工作,它可能會比初始化和填充方法更慢。即使你在開始時並不知道每個字段的形狀,你也可以將它們全部收集在字典中,然後從中組合數組。這種結構化數組比字典更緊湊或更高效。它只是使某些類型的數據訪問(跨域)更方便。

1

你必須通過值列表和格式的列表,而不是一個單一值和一個格式。如果你調試的問題,你會發現,

type(names) # result is <type 'str'> 
type(formats) # result is <type 'type'> 

然後,它發生的字典初始化爲

{'formats': numpy.float64, 'names': '30'} 

而每個formatsnames應該是一個列表。

編輯:此外,注意formats應該是一個字符串列表,像['float64','u8']等。