2009-11-24 18 views
6

Supponiamo che faccio due recarrays con lo stesso DTYPE e impilarli:impilabile recarrays NumPy senza perdere la loro 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)) 

Anche se a e b sono recarrays, c non è:

>>> 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]) 

posso ovviamente trasformarlo nuovamente in un nuovo, come mostrato con d sopra, ma ciò è inopportuno. C'è una ragione per cui impilare due recray non produce un altro riepilogo?

risposta

6

Non so. Molto probabilmente è un bug/funzionalità che non è mai stata implementata. numpy.hstack è fondamentalmente un wrapper attorno a una funzione in numpy.core.fromnumeric. Numeric è uno dei due predecessori di Numpy. La maggior parte delle funzioni in numpy hanno una convenzione per produrre lo stesso tipo dell'input chiamando il metodo __array_wrap__ dell'ingresso sull'output e l'output risultante dovrebbe avere gli stessi dati, ma "inserito" nella nuova classe. Forse il concetto di "involucro" non era in forma numerica e non si è mai aggiunto a questa funzione.

È possibile utilizzare questa tecnica per fare una funzione intelligente di impilamento

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

Questo funziona sia per i recarrays e array regolari

>>> 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'> 

Non sono sicuro di quello che stai progettando, ma si potrebbe voler chiedere su numpy mailing list c'è un modo migliore rispetto all'utilizzo del metodo documentato, ma con doppio sottolineamento, e qual è il loro ragionamento per non eseguire il wrapping stesso.

-1

Per inciso, è anche possibile utilizzare:

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

o

c = np.r_[a, b] 

(Fonte: this mailing list message)

+1

Non mantengono neanche la recarray. –

5

In alternativa, ci sono alcune utility di supporto in numpy.lib.recfunctions che mi sono imbattuto in here. Questo modulo dispone di funzioni sia per la fusione e accatastamento 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]) 

Se si vuole aggiungere colonne in più per un recarray, questo può essere fatto utilizzando 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 

(Anche se non è una risposta alla domanda, sto postando l'ultimo esempio come riferimento)

Problemi correlati