2009-11-24 55 views
6

想我做兩個recarrays用相同的D型和堆疊起來:堆疊numpy的recarrays不失其recarrayness

>>> import numpy as np 
>>> dt = [('foo', int), ('bar', float)] 
>>> a = np.empty(2, dtype=dt).view(np.recarray) 
>>> b = np.empty(3, dtype=dt).view(np.recarray) 
>>> c = np.hstack((a,b)) 

雖然ab是recarrays,c是不是:

>>> c.foo 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'numpy.ndarray' object has no attribute 'foo' 
>>> d = c.view(np.recarray) 
>>> d.foo 
array([     0,  111050731618561,     0, 
        7718048, 8246760947200437872]) 

我可以顯然將它重新變成一個recarray,如上面的d所示,但這很不方便。爲什麼堆疊兩個recarrays不會產生另一個recarray是有原因的嗎?

回答

6

我不知道。這很可能是一個從未實現過的bug /功能。 numpy.hstack基本上是圍繞numpy.core.fromnumeric中的函數的封裝。數字是numpy的兩個前輩之一。 numpy中的大多數函數都有一個約定,通過調用輸出上的輸入方法__array_wrap__來輸出與輸入相同的類型,並且生成的輸出應該具有相同的數據,但是會在新類中「包裝」。也許「包裝」的概念不是數字,並且一旦被添加到這個函數中。

您可以使用此技術來做出更明智的堆疊功能

def hstack2(arrays) : 
    return arrays[0].__array_wrap__(numpy.hstack(arrays)) 

這同時適用於recarrays和規則排列

>>> f = hstack2((a,b)) 
>>> type(f) 
<class 'numpy.core.records.recarray'> 
>>> f.foo 
array([ 140633760262784,  111050731618561,  140633760262800, 
        7536928, 8391166428122670177]) 
>>> x = numpy.random.rand(3) 
>>> y = numpy.random.rand(2) 
>>> z = hstack2((x,y)) 
>>> type(z) 
<type 'numpy.ndarray'> 

我不知道您的計劃,但你可能想詢問numpy mailing list是否有比使用記錄的但雙重下劃線的方法更好的方法,以及他們的理由是什麼,因爲他們自己沒有進行包裝。

-1

順便說一下,你也可以使用:

c = np.concatenate((a,b)) 

c = np.r_[a, b] 

(來源:this mailing list message

+1

他們不保留recarrayness要麼。 – 2011-05-27 18:01:45

5

另外,還有一些在numpy.lib.recfunctions一些幫助工具,這是我穿過here絆倒了。該模塊具有功能都融合和堆疊recarrays

from numpy.lib.recfunctions import stack_arrays 
c = stack_arrays((a, b), asrecarray=True, usemask=False) 
c.foo 
>>> array([  140239282560000,   4376479720, -4611686018427387904, 
        4358733828,   4365061216]) 

如果想要額外的列添加到recarray,這是可以做到使用merge_arrays

import numpy as np 
from numpy.lib.recfunctions import merge_arrays 
dt1 = [('foo', int), ('bar', float)] 
dt2 = [('foobar', int), ('barfoo', float)] 
aa = np.empty(6, dtype=dt1).view(np.recarray) 
bb = np.empty(6, dtype=dt2).view(np.recarray) 

cc = merge_arrays((aa, bb), asrecarray=True, flatten=True) 
type(cc) 
>>> numpy.core.records.recarray 

(雖然不是答案問題,我發佈後一個例子作爲參考)