2012-09-01 86 views
2

python相對較新,所以如果這有一個明顯的答案,我還沒有找到,請原諒。Numpy recarray種類的列和堆棧

我正在讀取一些臨時連續的二進制文件到numpy記錄數組中,最終目標是將它們存儲在一個pytable中。我預期的問題是文件可能並不都具有相同的字段或相同的字段順序。我一直在尋找一個numpy函數,它將使用字段標籤或索引對recarray的列(而不是行)進行排序。更好的辦法是爲你做這個功能,並且當你將一個recarray追加到另一個時,這個功能可以解釋缺失的列。下面是什麼我想到一個例子:

#-------script------------ 
Myarray1 = np.array([(1,2,3),(1,2,3),(1,2,3)], {'names': ('a','b','c'), 'formats': ('f4', 'f4', 'f4')}) 
Myarray2 = np.array([(2,1,4,3),(2,1,4,3),(2,1,4,3)], {'names': ('b','a','d','c'), 'formats': ('f4', 'f4', 'f4', 'f4')}) 
Myarray3 = SomeColumnSortFunction(Myarray2, sortorder=[2,1,4,3]) 
Myarray4 = SomeBetterVerticalStackFunction(Myarray1,Myarray2) 
# 
print(Myarray1) 
print() 
print(Myarray2) 
print() 
print(Myarray3) 
print() 
print(Myarray4) 

#---------- Wished for Output ------------- 
[(1.0, 2.0, 3.0) (1.0, 2.0, 3.0) (1.0, 2.0, 3.0)], 
dtype=[('a', 'i4'), ('b', 'i4'), ('c', 'i4')] 

[(2.0, 1.0, 4.0, 3.0) (2.0, 1.0, 4.0, 3.0) (2.0, 1.0, 4.0, 3.0)], 
dtype=[('b', 'i4'), ('a', 'i4'), ('d', 'i4'), ('c', 'i4')] 


[(1.0, 2.0, 3.0, 4.0) (1.0, 2.0, 3.0, 4.0) (1.0, 2.0, 3.0, 4.0)] 
dtype=[('a', 'i4'), ('b', 'i4'), ('c', 'i4'), ('d', 'i4')] 

[(1.0, 2.0, 3.0, NaN) (1.0, 2.0, 3.0, NaN) (1.0, 2.0, 3.0, NaN), 
(1.0, 2.0, 3.0, 4.0) (1.0, 2.0, 3.0, 4.0) (1.0, 2.0, 3.0, 4.0)] 
dtype=[('a', 'i4'), ('b', 'i4'), ('c', 'i4'), ('d', 'i4')] 

回答

4
  • 如果你想重新排列結構數組的領域,只是用花哨的索引:

    MyArray3 = MyArray2[['a','b','c','d']] 
    

    如果你想使用整數您的字段進行排序,你可以使用類似:

    order = [1,0,3,2] 
    names = MyArray2.dtype.names 
    MyArray3 = MyArray2[[names[i] for i in order]] 
    

    (在你的sortorder=[2,1,4,3],你可能放棄t表示可迭代的第一個索引爲0 ...)

  • 對於堆疊結構化陣列,請參閱numpy.lib.recfunctions子模塊,特別是stack_arrays函數。請注意,您必須使用import numpy.lib.recfunctions明確

這裏的文檔字符串

stack_arrays(arrays, defaults=None, usemask=True, asrecarray=False, autoconvert=False) 

Superposes arrays fields by fields 

Parameters 
---------- 
seqarrays : array or sequence 
    Sequence of input arrays. 
defaults : dictionary, optional 
    Dictionary mapping field names to the corresponding default values. 
usemask : {True, False}, optional 
    Whether to return a MaskedArray (or MaskedRecords is `asrecarray==True`) 
    or a ndarray. 
asrecarray : {False, True}, optional 
    Whether to return a recarray (or MaskedRecords if `usemask==True`) or 
    just a flexible-type ndarray. 
autoconvert : {False, True}, optional 
    Whether automatically cast the type of the field to the maximum. 

Examples 
-------- 
>>> from numpy.lib import recfunctions as rfn 
>>> x = np.array([1, 2,]) 
>>> rfn.stack_arrays(x) is x 
True 
>>> z = np.array([('A', 1), ('B', 2)], dtype=[('A', '|S3'), ('B', float)]) 
>>> zz = np.array([('a', 10., 100.), ('b', 20., 200.), ('c', 30., 300.)], 
... dtype=[('A', '|S3'), ('B', float), ('C', float)]) 
>>> test = rfn.stack_arrays((z,zz)) 
>>> test 
masked_array(data = [('A', 1.0, --) ('B', 2.0, --) ('a', 10.0, 100.0) ('b', 20.0, 200.0) 
('c', 30.0, 300.0)], 
      mask = [(False, False, True) (False, False, True) (False, False, False) 
(False, False, False) (False, False, False)], 
     fill_value = ('N/A', 1e+20, 1e+20), 
      dtype = [('A', '|S3'), ('B', '<f8'), ('C', '<f8')]) 
+0

Pierre,Fabulous – RJCL

0

只是要注意,通過@PierreGM答案似乎並不在舊版本的numpy工作,比如這個片段:

python -c 'import numpy as np 
from pprint import pformat 
print np.__version__ 
a = np.array([ (1, 4.0, "Hello"), 
       (-1, -1.0, "World")], 
     dtype=[("f0", ">i4"), ("f1", ">f4"), ("S2", "|S10")]) 
print("a : "+ pformat(a)) 
print("a1: "+ pformat(a[["f0", "S2"]])) 
print("a2: "+ pformat(a[["S2", "f0"]])) 
' 

...產生這對我來說(蟒蛇2.7):

1.5.1 
a : array([(1, 4.0, 'Hello'), (-1, -1.0, 'World')], 
     dtype=[('f0', '>i4'), ('f1', '>f4'), ('S2', '|S10')]) 
a1: array([(1, 'Hello'), (-1, 'World')], 
     dtype=[('f0', '>i4'), ('S2', '|S10')]) 
a2: array([(1, 'Hello'), (-1, 'World')], 
     dtype=[('f0', '>i4'), ('S2', '|S10')]) 

......也就是說,列根本不重新排列。


編輯:發現一種替代,使用numpy.lib.recfunctions;還有Indexing — NumPy v1.5 Manual (NumPy Reference)Structured arrays (aka 「Record arrays」) — NumPy v1.5 Manual (NumPy User Guide)。基本上是:

  • 創建一個新的列表,包含的順序重新排列列dtypes要
  • 通過.view創建的np.array個新的列表(這樣既名和D型是保存每個)表示每列,根據重新排列列D型列表
  • 使用np.array S作爲參數列表中numpy.lib.recfunctions.merge_arrays

所以這可以被添加到上面的代碼片段中THI重新排序s post:

from numpy.lib import recfunctions as rfn 

rdtype=[("S2", "|S10"), ("f1", ">f4"), ("f0", ">i4")] 
#ra = np.array([ np.array(a[rdt[0]], rdt) for rdt in rdtype]) 
#print [np.array(a[rdt[0]], dtype=rdt) for rdt in rdtype] # no 
#print [np.array(a[rdt[0]]) for rdt in rdtype] #passes, no field names 
print [np.array(a[rdt[0]]).view([rdt]) for rdt in rdtype] #ok 
ra = rfn.merge_arrays(([np.array(a[rdt[0]]).view([rdt]) for rdt in rdtype])) 
print("a4: "+ pformat(ra)) 

...其中另外輸出:

[array([('Hello',), ('World',)], 
     dtype=[('S2', '|S10')]), array([(4.0,), (-1.0,)], 
     dtype=[('f1', '>f4')]), array([(1,), (-1,)], 
     dtype=[('f0', '>i4')])] 

a4: array([('Hello', 4.0, 1), ('World', -1.0, -1)], 
     dtype=[('S2', '|S10'), ('f1', '>f4'), ('f0', '>i4')]) 

......它最終顯示列按要求重新排列。

嗯,希望這可以幫助別人 - 希望這裏沒有別的東西出錯了,
乾杯!