4 Stimmen

Automatische Stringlänge im Recarray

Wenn ich auf diese Weise ein Recarray erstelle:

In [29]: np.rec.fromrecords([(1,'hello'),(2,'world')],names=['a','b'])

Das Ergebnis sieht gut aus:

Out[29]: 
rec.array([(1, 'hello'), (2, 'world')], 
      dtype=[('a', '<i8'), ('b', '|S5')])

Aber wenn ich die Datentypen angeben möchte:

In [32]: np.rec.fromrecords([(1,'hello'),(2,'world')],dtype=[('a',np.int8),('b',np.str)])

Die Zeichenfolge wird auf eine Länge von Null gesetzt:

Out[32]: 
rec.array([(1, ''), (2, '')], 
      dtype=[('a', '|i1'), ('b', '|S0')])

Ich muss Datentypen für alle numerischen Typen angeben, da ich mich um int8/16/32 usw. kümmere, aber ich möchte von der automatischen Erkennung der Zeichenfolgenlänge profitieren, die funktioniert, wenn ich keine Datentypen angebe. Ich habe versucht, np.str durch None zu ersetzen, aber ohne Erfolg. Ich weiß, dass ich zum Beispiel '|S5' angeben kann, aber ich weiß nicht im Voraus, was die Stringlänge eingestellt werden sollte.

2voto

Wenn Sie die Zeichenketten nicht als Bytes manipulieren müssen, können Sie sie mit dem Datentyp Objekt darstellen. Dabei wird im Wesentlichen ein Zeiger anstelle der eigentlichen Bytes gespeichert:

In [38]: np.array(data, dtype=[('a', np.uint8), ('b', np.object)])
Out[38]: 
array([(1, 'hello'), (2, 'world')], 
      dtype=[('a', '|u1'), ('b', '|O8')])

Alternativ wäre auch die Idee von Alex gut geeignet:

new_dt = []

# For each field of a given type and alignment, determine
# whether the field is an integer.  If so, represent it as a byte.

for f, (T, align) in dt.fields.iteritems():
    if np.issubdtype(T, int):
        new_dt.append((f, np.uint8))
    else:
        new_dt.append((f, T))

new_dt = np.dtype(new_dt)
np.array(data, dtype=new_dt)

was Folgendes ergeben sollte

array([(1, 'hello'), (2, 'world')], 
      dtype=[('f0', '|u1'), ('f1', '|S5')])

0voto

Alex Martelli Punkte 805329

Ich weiß nicht, wie man Numpy bitten kann, einige Aspekte eines dtype zu bestimmen, andere aber nicht, aber könnte man nicht z.B.:

data = [(1,'hello'),(2,'world')]
dlen = max(len(s) for i, s in data)
st = '|S%d' % dlen
np.rec.fromrecords(data, dtype=[('a',np.int8), ('b',st)])

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X