2015-07-10 186 views
1

我想在Python中構建一個structured array,它可以通過列和行的名稱進行訪問。這可能與structured array方法的numpy?二維結構化數組

例子: 我的陣列大致有這樣的形式:

My_array =  A B C 
       E 1 2 3 
       F 4 5 6 
       G 7 8 9 

,我想必須做以下可能性:

My_array["A"]["E"] = 1 
My_array["C"]["F"] = 6 

是否有可能使用爲此在pyhton structured arrays還是有另一種更適合這樣的任務的結構?

+1

您可以使用[pandas](http://pandas.pydata。org) – yangjie

+0

@揚傑坦克,'熊貓'看起來很有希望。但是,我必須通過MPI接口傳遞這些數據'numpy'將是一個很好的解決方案,因爲它們更快更容易通過接口。 – swot

回答

1

使用重新數組,可以使用點符號或具體引用列名稱來訪問列。對於行,它們由行號訪問。我還沒有看到他們通過行名稱訪問,例如:

>>> import numpy as np 
>>> a = np.arange(1,10,1).reshape(3,3) 
>>> dt = np.dtype([('A','int'),('B','int'),('C','int')]) 
>>> a.dtype = dt 
>>> r = a.view(type=np.recarray) 
>>> r 
rec.array([[(1, 2, 3)], 
     [(4, 5, 6)], 
     [(7, 8, 9)]], 
     dtype=[('A', '<i4'), ('B', '<i4'), ('C', '<i4')]) 
>>> r.A 
array([[1], 
     [4], 
     [7]]) 
>>> r['A'] 
array([[1], 
     [4], 
     [7]]) 
>>> r.A[0] 
array([1]) 
>>> a['A'][0] 
array([1]) 
>>> # now for the row 
>>> >>> r[0] 
rec.array([(1, 2, 3)], 
     dtype=[('A', '<i4'), ('B', '<i4'), ('C', '<i4')]) 
>>> 

您可以指定D型,並在同一時間類型

>>> a = np.ones((3,3)) 
>>> b = a.view(dtype= [('A','<f8'), ('B','<f8'),('C', '<f8')], type = np.recarray) 
>>> b 
rec.array([[(1.0, 1.0, 1.0)], 
     [(1.0, 1.0, 1.0)], 
     [(1.0, 1.0, 1.0)]], 
     dtype=[('A', '<f8'), ('B', '<f8'), ('C', '<f8')]) 
>>> b.A 
array([[ 1.], 
     [ 1.], 
     [ 1.]]) 
>>> b.A[0] 
array([ 1.]) 
+0

感謝您的建議。我想我可以解決列的索引問題。但是,如果我使用'np.zeros((3,3))'而不是arange和reshape,我得到一個數組,其中有兩個三元組:'[(0.0,0.0,0.0),(0.0,0.0, 0.0)]'。但我只想要一個三倍。 – swot

+0

'dtype = [('A',np.float),('B',np.float),('C',np.float)]'解決了這個問題。誰能告訴我爲什麼? – swot

+1

swot我正在添加行的東西到我原來的帖子 – 2015-07-10 15:09:34

1

基本結構數組給你的東西,可以用一個名字索引:

In [276]: dt=np.dtype([('A',int),('B',int),('C',int)]) 
In [277]: x=np.arange(9).reshape(3,3).view(dtype=dt) 
In [278]: x 
Out[278]: 
array([[(0, 1, 2)], 
     [(3, 4, 5)], 
     [(6, 7, 8)]], 
     dtype=[('A', '<i4'), ('B', '<i4'), ('C', '<i4')]) 

In [279]: x['B'] # index by field name 
Out[279]: 
array([[1], 
     [4], 
     [7]]) 

In [280]: x[1] # index by row (array element) 
Out[280]: 
array([(3, 4, 5)], 
     dtype=[('A', '<i4'), ('B', '<i4'), ('C', '<i4')]) 

In [281]: x['B'][1] 
Out[281]: array([4]) 

In [282]: x.shape # could be reshaped to (3,) 
Out[282]: (3, 1) 

視圖方法產生了一個2d數組,但只有一列。通常的列被dtype字段替換。這是2D,但有一個轉折點。通過使用view,數據緩衝區不變; dtype只是提供了訪問這些'列'的不同方式。在技​​術上,dtype字段不是維度。它們不在陣列的.shape.ndim中註冊。你也不能使用x[0,'A']

recarray做了同樣的事情,但增加了訪問字段作爲屬性的選項,例如, x.Bx['B']相同。

rows仍然必須通過索引號訪問。

另一種構造結構化數組的方法是將定義的值作爲元組列表。

In [283]: x1 = np.arange(9).reshape(3,3) 
In [284]: x2=np.array([tuple(i) for i in x1],dtype=dt) 
In [285]: x2 
Out[285]: 
array([(0, 1, 2), (3, 4, 5), (6, 7, 8)], 
     dtype=[('A', '<i4'), ('B', '<i4'), ('C', '<i4')]) 
In [286]: x2.shape 
Out[286]: (3,) 

oneszerosempty還構造基本結構化陣列

In [287]: np.ones((3,),dtype=dt) 
Out[287]: 
array([(1, 1, 1), (1, 1, 1), (1, 1, 1)], 
     dtype=[('A', '<i4'), ('B', '<i4'), ('C', '<i4')]) 

我可以構建被索引與2字段名,由嵌套dtypes數組:

In [294]: dt1=np.dtype([('D',int),('E',int),('F',int)]) 

In [295]: dt2=np.dtype([('A',dt1),('B',dt1),('C',dt1)]) 

In [296]: y=np.ones((),dtype=dt2) 

In [297]: y 
Out[297]: 
array(((1, 1, 1), (1, 1, 1), (1, 1, 1)), 
     dtype=[('A', [('D', '<i4'), ('E', '<i4'), ('F', '<i4')]), ('B', [('D', '<i4'), ('E', '<i4'), ('F', '<i4')]), ('C', [('D', '<i4'), ('E', '<i4'), ('F', '<i4')])]) 

In [298]: y['A']['F'] 
Out[298]: array(1) 

但坦率地說這是相當複雜的。我甚至沒有想到如何將元素設置爲arange(9)(沒有迭代字段名稱)。

結構化陣列最常見的是通過csv文件與np.genfromtxt(或loadtxt)生成。結果是每個標記列的命名字段以及文件中每行的編號「行」。

+0

無法在評論中正確格式化,所以忍受着我。在[299]中:z = y.view(type = np.recarray),然後在[300]中:zA ['F']或In [3XX]:zAF產生數組(1) )recarrays只是增加了arry.field表示的arry ['field']的能力,所以zAF'看起來'比等效片段更好 – 2015-07-10 19:56:57

+0

是的,我的'dt2' dtype可以轉換爲'recarray'並且可以用'xAF '。 dtype越複雜,'recarray'看起來越好。 – hpaulj

+0

@hpaulj感謝您對不同可能性的討論。我不知道嵌套'dtypes'的可能性。也許,我會在稍後嘗試使用嵌套'dtypes'的最後一個建議。 – swot