2009-11-24 8 views
6

Angenommen zu verlieren ich zwei recarrays mit dem gleichen dtype machen und sie stapeln:Stapel numpy recarrays ohne ihre 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)) 

Obwohl a und b sind recarrays ist c nicht:

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

ich kann offensichtlich wieder in eine erneute Anordnung, wie oben mit d gezeigt, aber das ist unbequem. Gibt es einen Grund, warum das Stapeln von zwei Rekarrays keine weitere Rekombination erzeugt?

Antwort

6

Ich weiß es nicht. Wahrscheinlich ist es ein Bug/Feature, der nie implementiert wurde. numpy.hstack ist im Grunde ein Wrapper um eine Funktion in numpy.core.fromnumeric. Numeric ist einer der beiden Vorgänger von numpy. Die meisten Funktionen in numpy haben eine Konvention, um den gleichen Typ wie die Eingabe auszugeben, indem sie die Methode __array_wrap__ der Eingabe auf der Ausgabe aufrufen, und die resultierende Ausgabe sollte dieselben Daten haben, aber in der neuen Klasse "eingepackt" sein. Vielleicht war das Konzept des "Wrappings" nicht numerisch und wurde dieser Funktion nie hinzugefügt.

können Sie diese Technik verwenden eine intelligentere Stapelfunktion

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

Dies funktioniert sowohl für recarrays und regelmäßige Anordnungen

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

Ich bin mir nicht sicher, was Sie planen, aber Sie zu machen Vielleicht möchten Sie auf der numpy mailing list fragen, gibt es einen besseren Weg als die Verwendung der dokumentierten, aber doppelt unterstrichenen Methode, und was ihre Argumentation ist, nicht die Verpackung selbst zu tun.

5

Alternativ gibt es einige Helfer Dienstprogramme in numpy.lib.recfunctions, die ich über here stolperte. Dieses Modul verfügt über Funktionen für beide Zusammenführung und Stapel 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]) 

Will man zusätzliche Spalten zu einem recarray hinzufügen möchten, können dies mit merge_arrays erfolgen:

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 

(Obwohl keine Antwort auf die Frage, ich poste das letztere Beispiel als eine Referenz)