2017-01-05 4 views
1

Ich habe eine CSV-Datei mit einer Menge von Daten, die ich als maskiertes Array lesen möchte. Ich habe so mit dem folgenden verwendet:numpy - Ändern/Angeben dtypes von maskierten Array-Spalten

data=np.recfromcsv(filename,case_sensitive=True,usemask=True) 

was gut funktioniert. Mein Problem ist jedoch, dass die Daten entweder Strings, Integer oder Floats sind. Was ich jetzt tun möchte, ist, alle Integer in Floats umzuwandeln, d. H. Alle "1" s in "1.0" s umzuwandeln, während alles andere erhalten bleibt.

Zusätzlich suche ich nach einer generischen Lösung. Die manuelle Angabe der gewünschten Typen ist daher nicht möglich, da sich die CSV-Datei (einschließlich der Anzahl der Spalten) ändert.

Ich habe versucht astype aber da das Array auch String-Einträge hat, die nicht funktionieren, oder fehle ich etwas?

Danke.

Antwort

0

Ich habe recfromcsv nicht verwendet, aber mit Blick auf seinen Code sehe ich np.genfromtxt, gefolgt von einer maskierten Aufzeichnungen Konstruktion.

Ich würde vorschlagen, geben Sie eine kleine Probe csv Text (3 oder so Linien), und zeigen Sie die resultierende data. Wir müssen insbesondere die dtype sehen.

Es kann auch nützlich sein, mit genfromtxt zu beginnen, das maskierte Array Zeug für jetzt überspringend. Ich glaube nicht, dass das der Punkt ist, an dem dtypes in strukturierten Arrays konvertiert werden.

In jedem Fall brauchen wir etwas konkreter zu erkunden.

Sie können die dtype von strukturierten Feldern nicht direkt ändern. Sie müssen ein neues Array mit einem neuen dtype erstellen und Werte von alt nach neu kopieren.

hat einige Funktionen, die beim Ändern von strukturierten Arrays helfen können.

===========

Ich vermute, dass es einfacher sein wird, die dtypes wenn genfromtxt als Aufruf zu buchstabieren dtypes in einem vorhandenen Array zu ändern.

Sie könnten versuchen, eine Lesung mit der dtype=None und begrenzte Anzahl von Zeilen, um die Anzahl der Spalten und Basis dtype zu erhalten. Dann bearbeite das und setze nach Bedarf Floats für Ints ein. Lies nun das Ganze mit dem neuen dtype. Suchen Sie im Code recfunctions, wenn Sie Ideen zum Bearbeiten von Dtypes benötigen.

Zum Beispiel:

In [504]: txt=b"""a, 1, 2, 4\nb, 6, 9, 10\nc, 4, 4, 3""" 

In [506]: arr = np.genfromtxt(txt.splitlines(), dtype=None, delimiter=',') 
In [507]: arr 
Out[507]: 
array([(b'a', 1, 2, 4), (b'b', 6, 9, 10), (b'c', 4, 4, 3)], 
     dtype=[('f0', 'S1'), ('f1', '<i4'), ('f2', '<i4'), ('f3', '<i4')]) 
In [508]: arr.dtype.descr 
Out[508]: [('f0', '|S1'), ('f1', '<i4'), ('f2', '<i4'), ('f3', '<i4')] 

Ein rohes dtype Editor:

def foo(tup): 
    name, dtype=tup 
    dtype = dtype.replace('S','U') 
    dtype = dtype.replace('i','f') 
    return name, dtype 

und Anwendung dieses dtype auf Standard:

In [511]: dt = [foo(tup) for tup in arr.dtype.descr] 
In [512]: dt 
Out[512]: [('f0', '|U1'), ('f1', '<f4'), ('f2', '<f4'), ('f3', '<f4')] 

In [513]: arr = np.genfromtxt(txt.splitlines(), dtype=dt, delimiter=',') 
In [514]: arr 
Out[514]: 
array([('a', 1.0, 2.0, 4.0), ('b', 6.0, 9.0, 10.0), ('c', 4.0, 4.0, 3.0)], 
     dtype=[('f0', '<U1'), ('f1', '<f4'), ('f2', '<f4'), ('f3', '<f4')]) 

In [522]: arr = np.recfromcsv(txt.splitlines(), dtype=dt, delimiter=',',case_sensitive=True,usemask=True,names=None) 
In [523]: arr 
Out[523]: 
masked_records(
    f0 : ['a' 'b' 'c'] 
    f1 : [1.0 6.0 4.0] 
    f2 : [2.0 9.0 4.0] 
    f3 : [4.0 10.0 3.0] 
    fill_value : ('N', 1.0000000200408773e+20, 1.0000000200408773e+20, 1.0000000200408773e+20) 
      ) 

========== ==========

astype wor ks, wenn der Ziel-dtype übereinstimmt. Zum Beispiel, wenn ich die txt mit dtype = None lesen, und verwenden Sie dann den abgeleiteten dt, funktioniert es:

In [530]: arr = np.genfromtxt(txt.splitlines(), delimiter=',',dtype=None) 
In [531]: arr 
Out[531]: 
array([(b'a', 1, 2, 4), (b'b', 6, 9, 10), (b'c', 4, 4, 3)], 
     dtype=[('f0', 'S1'), ('f1', '<i4'), ('f2', '<i4'), ('f3', '<i4')]) 
In [532]: arr.astype(dt) 
Out[532]: 
array([('a', 1.0, 2.0, 4.0), ('b', 6.0, 9.0, 10.0), ('c', 4.0, 4.0, 3.0)], 
     dtype=[('f0', '<U1'), ('f1', '<f4'), ('f2', '<f4'), ('f3', '<f4')]) 

Das Gleiche gilt für arr.astype('U3,int,float,int') die auch 4-kompatible Felder.

+0

Danke, dieser nette kleine Editor hat es für mich getan. – RxHEAD

Verwandte Themen