2015-12-15 5 views
6

ich in das folgende Problem lief 1.10.2 mit NumPy wenn einer CSV-Datei zu lesen. Ich kann nicht herausfinden, wie man explizite Datentypen genfromtxt gibt. HierNumPy: Mismatch in der Größe des alten und neuen Daten-Descriptor

ist die CSV, minimal.csv:

x,y 
1,hello 
2,hello 
3,jello 
4,jelly 
5,belly 

Hier versuche ich, es zu lesen, mit genfromtxt:

import numpy 
numpy.genfromtxt('minimal.csv', dtype=(int, str)) 

ich auch versucht:

import numpy 
numpy.genfromtxt('minimal.csv', names=True, dtype=(int, str)) 

Wie auch immer, ich bekommen Fehler:

Traceback (most recent call last): 
    File "visualize_numpy.py", line 39, in <module> 
    numpy.genfromtxt('minimal.csv', dtype=(int, str)) 
    File "/Users/xeli/workspace/myproj/env/lib/python3.5/site-packages/numpy/lib/npyio.py", line 1518, in genfromtxt 
    replace_space=replace_space) 
    File "/Users/xeli/workspace/myproj/env/lib/python3.5/site-packages/numpy/lib/_iotools.py", line 881, in easy_dtype 
    ndtype = np.dtype(ndtype) 
ValueError: mismatch in size of old and new data-descriptor 

Alternativ habe ich versucht:

import numpy 
numpy.genfromtxt('minimal.csv', dtype=[('x', int), ('y', str)]) 

Welche wirft:

Traceback (most recent call last): 
    File "visualize_numpy.py", line 39, in <module> 
    numpy.genfromtxt('minimal.csv', dtype=[('x', int), ('y', str)]) 
    File "/Users/xeli/workspace/myproj/env/lib/python3.5/site-packages/numpy/lib/npyio.py", line 1834, in genfromtxt 
    rows = np.array(data, dtype=[('', _) for _ in dtype_flat]) 
ValueError: size of tuple must match number of fields. 

I bekannt dtype=None macht NumPy zu versuchen richtigen Typen zu erraten, und in der Regel gut funktioniert. Die Dokumentation erwähnt jedoch, dass es viel langsamer als explizite Typen ist. In meinem Fall ist die Recheneffizienz erforderlich, so dass dtype=None keine Option ist.

Gibt es etwas schrecklich falsch mit meinem Ansatz oder NumPy?

+1

Ich hatte ein sehr ähnliches Problem, das ich löste, indem ich den dtype als eine Liste anstelle eines Tupels gab, und es scheint dasselbe für Ihren Fall zu sein. – pela

Antwort

3

Das funktioniert gut, und bewahrt Ihre Daten-Header:

df = numpy.genfromtxt('minimal.csv', 
         names=True, 
         dtype=None, 
         delimiter=',') 

Dies macht genfromtxt die dtype erraten, die in der Regel ist das, was Sie wollen. Trennzeichen ist ein Komma, also sollten wir dieses Argument ebenfalls übergeben und schließlich behält names=True die Header-Information bei.

Zugriff einfach Ihre Daten wie bei jeder anderen Rahmen würde:

>>>>print(df['x']) 
[1 2 3 4 5] 

Edit: wie pro Ihren Kommentar unten, könnten Sie die dtype ausdrücklich vor, etwa so:

df = numpy.genfromtxt('file1.csv', 
         names=True, 
         dtype=[('x', int), ('y', 'S5')], # assuming each string is of len =< 5 
         delimiter=',') 
+0

Danke! Und leider, leider ist 'dtype = None' in meinem Fall wegen seiner Langsamkeit nicht geeignet. Ich habe das zur Frage hinzugefügt. Ich kann einfach nicht herausfinden, wie man die Typen explizit zu genfromtxt gibt. –

+0

@ AkseliPalén, siehe meine aktualisierte Antwort! Ich hoffe das hilft :) –

0

Von einem kurzen Blick auf die documentation, die Standardeinstellung delimiter=None.

Versuchen numpy.genfromtxt('minimal.csv', dtype=(int, str), names=True, delimiter=',')

+0

können Sie 'names = True' verwenden, um die Spaltennamen aus der ersten Zeile zu lesen – MaxNoe

+0

@MaxNoe oh mein Fehler. Also ist das Begrenzerfeld nicht wichtig. – pushkin

+0

'name = True' ersetzt' skip_header'. Sie brauchen noch 'delimiter = ','' und 'dtype = None'. – hpaulj

0

I bin in der gleichen Position, in der ich nicht sicher bin, warum meine bereitgestellten Typen einen Fehler werfen. Das könnte eine praktikable Lösung für Sie sein. Hier ist ein Beispiel, das meinen Datensatz verwendet, der Ihrem ähnlich ist.

Zunächst einige der Daten laden und überprüfen Sie die tatsächlichen dtypes NumPy verwendet:

>>> movies = np.genfromtxt('movies.csv', delimiter='|', dtype=None) 
>>> movies 
array([(1, 'Toy Story (1995)'), (2, 'GoldenEye (1995)'), 
     (3, 'Four Rooms (1995)'), ..., (1680, 'Sliding Doors (1998)'), 
     (1681, 'You So Crazy (1994)'), 
     (1682, 'Scream of Stone (Schrei aus Stein) (1991)')], 
     dtype=[('f0', '<i8'), ('f1', 'S81')]) 

Dann laden Sie alle Ihre Daten die erfassten Arten mit:

>>> movies = np.genfromtxt('movies.csv', delimiter='|', 
          dtype=[('f0', '<i8'), ('f1', 'S81')]) 

Dies ist zwar nicht so zufriedenstellend wie zu wissen, warum NumPy den Fehler verursacht, aber es funktioniert für Ihren speziellen Anwendungsfall.

Verwandte Themen