2012-04-23 26 views
6

Ich schreibe eine Methode, um ein Array aus Datendatei zu erstellen. Das Verfahren sieht so aus:Entfernen dtype am Ende der numpy Array

import numpy 
def readDataFile(fileName): 
    try: 
     with open(fileName, 'r') as inputs: 
      data = None 
      for line in inputs: 
       line = line.strip() 
       items = line.split('\t') 
       if data == None: 
        data = numpy.array(items[0:len(items)]) 
       else: 
        data = numpy.vstack((data, items[0:len(items)])) 
       return numpy.array(data) 
    except IOError as ioerr: 
     print 'IOError: ', ioerr 
     return None 

Meine Datendatei die Zeilen von Zahlen enthält, von denen jede die voneinander durch einen Tabulator getrennt, zB:

1 2 3 
4 5 6 
7 8 9 

Und ich erwarte ein Array erhalten wie folgt :

array([[1, 2, 3], 
     [4, 5, 6], 
     [7, 8, 9]]) 

enthält jedoch das Ergebnis dtype davon am Ende:

array([[1, 2, 3], 
     [4, 5, 6], 
     [7, 8, 9]], dtype='|S9') 

Aus diesem Grund kann ich einige Operationen am Ergebnis nicht durchführen, z. wenn ich versuche, den Maximalwert für jede Zeile zu finden result.max(0) verwenden, werde ich eine Fehlermeldung erhalten:

TypeError: cannot perform reduce with flexible type.

Also, kann mir jemand sagen, was mit meinem Code falsch ist und wie man es beheben? Danke vielmals.

Antwort

8

Die einfachste Lösung ist numpy des loadtxt zu verwenden:

data = numpy.loadtxt(fileName, dtype='float') 

Gerade FYI, mit numpy.vstack innerhalb einer Schleife a schlechte Idee. Wenn Sie sich entschließen, loadtxt nicht zu verwenden, können Sie Ihre Schleife durch die folgenden ersetzen, um das dtype-Problem zu beheben und das numpy.vstack zu entfernen.

data = [row.split('\t') for row in inputs] 
data = np.array(data, dtype='float') 

aktualisieren

Jedes Mal vstack aufgerufen wird es ein neues Array macht, und kopiert den Inhalt der alten Arrays in das neue. Diese Kopie ist ungefähr O (n), wobei n die Größe des Arrays ist und wenn Ihre Schleife n mal läuft, wird das Ganze zu O (n ** 2), mit anderen Worten langsam. Wenn Sie die endgültige Größe des Arrays im Voraus kennen, ist es besser, das Array außerhalb der Schleife zu erstellen und das vorhandene Array zu füllen. Wenn Sie die endgültige Größe des Arrays nicht kennen, können Sie eine Liste innerhalb der Schleife verwenden und vstack am Ende aufrufen. Zum Beispiel:

import numpy as np 
myArray = np.zeros((10,3)) 
for i in xrange(len(myArray)): 
    myArray[i] = [i, i+1, i+2] 

# or: 
myArray = [] 
for i in xrange(10): 
    myArray.append(np.array([i, i+1, i+2])) 
myArray = np.vstack(myArray) 
+1

Danke, funktioniert Ihr Code wirklich gut. Aber können Sie erklären, warum es eine schlechte Idee ist, numpy.vstack in eine Schleife zu setzen? Prost. –

3

... Haben Sie versucht, sie zuerst in Zahlen zu verwandeln?

items = [int(x) for x in line.split('\t')] 
6

Hier ist, wie Sie Datentypen in numpy ändern:

>>> x 
array([[1, 2, 3], 
     [4, 5, 6], 
     [7, 8, 9]]) 
>>> x.astype('|S9') 
array([['1', '2', '3'], 
     ['4', '5', '6'], 
     ['7', '8', '9']], 
     dtype='|S9') 
>>> x.astype('Float64') 
array([[ 1., 2., 3.], 
     [ 4., 5., 6.], 
     [ 7., 8., 9.]]) 
>>> x.astype('int') 
array([[1, 2, 3], 
     [4, 5, 6], 
     [7, 8, 9]]) 
Verwandte Themen