Seite 1 von 1

Numpy Arrays

Verfasst: Freitag 3. Juni 2016, 12:34
von thedome
Hallo leute,

ich versuche gerade .txt files spaltenweise einzulesen mit der Funktion np.genfromtxt(). Eine der Spalten beinhaltet Zeitdaten im Format 'hh:mm:ss' als String. Mithilfe der Funktion np.core.defchararray.split(a,sep=':') habe ich die Zeit in 3 Teile aufgeteilt. Ouput sieht dann folgendermaßen aus:

Code: Alles auswählen

	a=
	array([['21', '46', '37'], ['21', '46', '42'], ['21', '46', '42'], ...,

	       ['09', '15', '37'], ['09', '15', '37'], ['09', '15', '37']], dtype=object)

	np.shape(a)=(1906,)
Da ich mathematische Operationen mit den Daten durchführen will, denke ich, dass ich das Array in Int formatieren muss.
Ich habe zwei Fragen:

1. Wieso ist das shape (1906,) und nicht (1906,3)?Wie kann ich das ändern?
2. Wie kann ich das Array in int Format formatieren?


Bin für jede Hilfe dankbar.

Re: Numpy Arrays

Verfasst: Freitag 3. Juni 2016, 13:20
von Sirius3
np.core.defchararray.split liefert Dir ein Array von Python Objekten erkenntlich am dtype=object. Die Frage ist ja, was Du mit den Daten anfangen willst. Normalerweise konvertiert man per converters-Parameter die Uhrzeit gleich in Sekunden o.ä.

Re: Numpy Arrays

Verfasst: Freitag 3. Juni 2016, 13:47
von thedome
Mir würde es reichen, wenn ich die Zahlen als int und nicht als String konvertiert bekomme. Ziel ist Zeitdifferenzen zu berechnen, sodass ich zwei Zeitdaten voneinander abziehen kann.

Re: Numpy Arrays

Verfasst: Freitag 3. Juni 2016, 17:10
von Sirius3
@thedome: daher habe ich auch von einem Konverter geschrieben, z.B:

Code: Alles auswählen

def parse_time(time):
    hours, minutes, seconds = map(int, time.split(':'))
    return (hours * 24 + minutes) * 60 +seconds

Re: Numpy Arrays

Verfasst: Sonntag 5. Juni 2016, 22:29
von thedome
Das funktionert leider nicht...Nachdem ich die Zeitdaten eingelesen habe befinden Sie sich schon im Array. Sieht dann so aus:

Code: Alles auswählen

time=array(['21:46:37', '21:46:42', '21:46:42', ..., '09:15:37', '09:15:37',
       '09:15:37'], 
      dtype='<U8')
Wenn ich den map Befehl nutze, bekomme ich eine Fehlermeldung (Split habe ich durch die numpy split Funktion ersetzt):

Code: Alles auswählen

hours, minutes, seconds = map(int, np.core.defchararray.split(time,sep=':'))

*** TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'
Theoretisch könnte ich jetzt mit einer For Schleife jedes Element konvertieren...Fällt dir noch was eleganteres ein?

Re: Numpy Arrays

Verfasst: Sonntag 5. Juni 2016, 22:35
von Sirius3
@thedome: wie schon geschrieben mußt Du beim einlesen einen Konverter angeben:

Beispiel:

Code: Alles auswählen

data = numpy.genfromtxt(filename, converters={0: parse_time})

Re: Numpy Arrays

Verfasst: Montag 6. Juni 2016, 06:38
von noisefloor
Hallo,

@Sirius3: den TypeError bekommt man (bzw. ich habe ihn auch bekommen...), wenn man das mit `converters=...` macht. Der TypeError war zumindest weg, wenn man `time` von str nach Bytes wandelt. Getestet mit Python 3.4.

Allerdings benutze ich Numpy zu wenig, um zu sagen, ob das eine gangbare Lösung oder ein Würg-Around ist.

Gruß, noisefloor

Re: Numpy Arrays

Verfasst: Montag 6. Juni 2016, 07:17
von Sirius3
@noisefloor: Den TypeError, den thedome bekommt, stammt ja daher, dass er versucht ein numpy-Array mit Listen per map in ein int zu verwandeln, hat also gar nichts mit Bytes oder Strings zu tun. Und über die Python-Version wissen wir nichts.

Zu Deinem Problem: je nach dem, mit was Du genfromtxt fütterst, brauchst Du entweder ein time.split(b':') oder time.split(':').

Re: Numpy Arrays

Verfasst: Montag 6. Juni 2016, 18:56
von noisefloor
Hallo,
Zu Deinem Problem: je nach dem, mit was Du genfromtxt fütterst, brauchst Du entweder ein time.split(b':') oder time.split(':').
Stimmt, Danke für den Hinweis. Mit `time.split(b':')` funktioniert es wie gewünscht.

Gruß, noisefloor

Re: Numpy Arrays

Verfasst: Dienstag 7. Juni 2016, 08:33
von thedome
also irgendwie bekomme ichs nicht hin..ich habe jetzt folgendes gemacht:

Code: Alles auswählen

def parse_time(time):
    hours, minutes, seconds = map(int, time.split(b':'))
    return (hours * 24 + minutes) * 60 +seconds
    

time=np.genfromtxt(file,converters={0:parse_time},delimiter='\t',usecols=(1))


time=
array([ nan,  nan,  nan, ...,  nan,  nan,  nan])
und genau, die file lese ich als Bytestream ein. Ich verstehe allerdings die Funktion parse_time nicht. Warum verrechest du stunden, minuten und sekunden im return befehl?

Re: Numpy Arrays

Verfasst: Dienstag 7. Juni 2016, 08:52
von Sirius3
@thedome: Du benutzt nur Spalte 1 setzt aber den Konverter für Spalte 0. Das macht keinen Sinn. Wahrscheinlich ist in Spalte 1 auch Deine Uhrzeit und nicht in Spalte 0, also:

Code: Alles auswählen

time = np.genfromtxt(file, converters={1:parse_time}, delimiter='\t', usecols=(1,))
Und wo soll ich Deiner Meinung nach sonst die Anzahl der Sekunden berechnen? Eine eigene Variable halte ich da für überflüssig.

PS: Und ich hoffe mal, Du ließt die Datei nicht mehrmals für verschiedene Spalten ein, wie in Deinem ersten Beitrag angedeutet, sondern alles Spalten auf einmal.

Re: Numpy Arrays

Verfasst: Dienstag 7. Juni 2016, 09:13
von snafu
@thedome:
Du wolltest doch die Uhrzeiten als Zahlwerte repräsentiert im Numpy-Array haben. Das leistet der hier vorgeschlagene Parser. Wäre es dir lieber, stattdessen Tupel in der Form (Stunden, Minuten, Sekunden) in das Array zu stecken? Dann würde ich aber eher die Einführung einer zweiten Dimension für das Array empfehlen, um den Speicherverbrauch zu reduzieren und um Numpy-interne Zugriffe zu vereinfachen. Mag sein, dass Numpy dies ohnehin von selbst entsprechend optimiert – so gut kenne ich Numpy nicht.

Re: Numpy Arrays

Verfasst: Dienstag 7. Juni 2016, 10:34
von thedome
@Sirius3: Danke, macht sinn. Es hat jetzt funktioniert, allerdings nur mit einem Array. Wenn ich die Spalten in mehrere Arrays einlesen möchte, bekomme ich eine Fehlermeldung. Damit beantworte ich auch schon deine Frage, ich möchte natürlich alle Spalten nur mit einem Befehl einlesen:

Code: Alles auswählen

time,col2,col3,col4,col5=np.genfromtxt(txt,converters={1:parse_time},delimiter='\t',dtype=None,usecols=(1,2,3,4,5),unpack=True)

->ValueError: too many values to unpack (expected 5)
Die Fehlermeldung erscheint komischerweise nur mit dem Converter, ohne funktioniert alles. Zur Info, ich benutze Python 3.4.4.

@snafu: Ursprünglich wollte ich stunden, minuten, sekunden in einer zweiten Dimension haben. Mir ist eben erst bewusst geworden, dass es viel besser ist, den Zeitstempel in Sekunden umzurechen :)

Re: Numpy Arrays

Verfasst: Dienstag 7. Juni 2016, 10:40
von Sirius3
Was liefert denn genformtxt ohne unpack?

Re: Numpy Arrays

Verfasst: Dienstag 7. Juni 2016, 11:09
von thedome
genau das selbe -.-

Re: Numpy Arrays

Verfasst: Dienstag 7. Juni 2016, 12:23
von noisefloor
Hallo,

zeigt doch mal 1-2 Zeilen des Ausgangsdatensatzes.

Gruß, noisefloor