2012-08-16 17 views
10

Ich habe eine große Pandas DataFrameAuswählen einer Teilmenge eines Pandas Datenrahmen indiziert durch DatetimeIndex mit einer Liste von Zeitmarken

<class 'pandas.core.frame.DataFrame'> 
DatetimeIndex: 3425100 entries, 2011-12-01 00:00:00 to 2011-12-31 23:59:59 
Data columns: 
sig_qual 3425100 non-null values 
heave  3425100 non-null values 
north  3425099 non-null values 
west  3425097 non-null values 
dtypes: float64(4) 

ich eine Teilmenge dieser DataFrame wählen .ix[start_datetime:end_datetime] mit und ich gehe dies zu einer peakdetect function, die die zurück Index und Wert der lokalen Maxima und Minima in zwei separaten Listen. Ich extrahiere die Indexposition der Maxima und benutze DataFrame.index Ich bekomme eine Liste von Pandas TimeStamps.

Ich versuche dann, die relevante Teilmenge des großen DataFrame zu extrahieren, indem ich die Liste der TimeStamps an .ix[] übergebe, aber es scheint immer eine leere DataFrame zurückzugeben. Ich kann die Liste der TimeStamps durchlaufen und die relevanten Zeilen von der DataFrame bekommen, aber das ist ein langwieriger Prozess und ich dachte, dass ix[] eine Liste von Werten gemäß the docs akzeptieren sollte? (obwohl ich sehe, daß das Beispiel für Pandas 0,7 a numpy.ndarray von numpy.datetime64 verwendet)

Update: Eine kleinen 8 Sekunden Teilmenge des Datenrahmen unter ausgewählt ist, # Linien einige der Werte zeigen:

y = raw_disp['heave'].ix[datetime(2011,12,30,0,0,0):datetime(2011,12,30,0,0,8)] 
#csv representation of y time-series 
2011-12-30 00:00:00,-310.0 
2011-12-30 00:00:01,-238.0 
2011-12-30 00:00:01.500000,-114.0 
2011-12-30 00:00:02.500000,60.0 
2011-12-30 00:00:03,185.0 
2011-12-30 00:00:04,259.0 
2011-12-30 00:00:04.500000,231.0 
2011-12-30 00:00:05.500000,139.0 
2011-12-30 00:00:06.500000,55.0 
2011-12-30 00:00:07,-49.0 
2011-12-30 00:00:08,-144.0 

index = y.index 
<class 'pandas.tseries.index.DatetimeIndex'> 
[2011-12-30 00:00:00, ..., 2011-12-30 00:00:08] 
Length: 11, Freq: None, Timezone: None 

#_max returned from the peakdetect function, one local maxima for this 8 seconds period 
_max = [[5, 259.0]] 

indexes = [x[0] for x in _max] 
#[5] 

timestamps = [index[z] for z in indexes] 
#[<Timestamp: 2011-12-30 00:00:04>] 

print raw_disp.ix[timestamps] 
#Empty DataFrame 
#Columns: array([sig_qual, heave, north, west, extrema], dtype=object) 
#Index: <class 'pandas.tseries.index.DatetimeIndex'> 
#Length: 0, Freq: None, Timezone: None 

for timestamp in timestamps: 
    print raw_disp.ix[timestamp] 
#sig_qual  0 
#heave  259 
#north  27 
#west  132 
#extrema  0 
#Name: 2011-12-30 00:00:04 

Update 2: created a gist I, die tatsächlich funktioniert, weil, wenn die Daten in aus cSV die Indexspalten Zeitstempel gespeichert werden als Array von numPy geladen wird Objekte, die wie Strings erscheinen. Anders als in meinem eigenen Code, wo der Index vom Typ <class 'pandas.tseries.index.DatetimeIndex'> ist und jedes Element vom Typ <class 'pandas.lib.Timestamp'> ist, dachte ich, dass das Übergeben einer Liste von pandas.lib.Timestamp genauso funktionieren würde wie das Übergeben einzelner Zeitstempel, würde dies als ein Fehler angesehen werden?

Wenn ich das Original DataFrame mit dem Index als eine Liste von Zeichenfolgen erstellen, funktioniert die Abfrage mit einer Liste von Zeichenfolgen einwandfrei. Es erhöht jedoch die Byte-Größe des DataFrame erheblich.

Update 3: Der Fehler nur bei sehr großen Datenrahmen auftreten erscheint, reran ich den Code auf unterschiedliche Größen von Datenrahmen (einige Details in einem Kommentar unten) und es scheint, über 2,7 Millionen Datensätze auf einem Datenrahmen auftreten . Die Verwendung von Strings im Gegensatz zu TimeStamps behebt das Problem, erhöht jedoch die Speicherauslastung.

Fest In neuestem Github-Master (18.09.2012) finden Sie von Wes Kommentar am Ende der Seite.

Antwort

15

df.ix [meine_list_of_dates] sollte gut funktionieren.

In [193]: df 
Out[193]: 
      A B C D 
2012-08-16 2 1 1 7 
2012-08-17 6 4 8 6 
2012-08-18 8 3 1 1 
2012-08-19 7 2 8 9 
2012-08-20 6 7 5 8 
2012-08-21 1 3 3 3 
2012-08-22 8 2 3 8 
2012-08-23 7 1 7 4 
2012-08-24 2 6 0 6 
2012-08-25 4 6 8 1 

In [194]: row_pos = [2, 6, 9] 

In [195]: df.ix[row_pos] 
Out[195]: 
      A B C D 
2012-08-18 8 3 1 1 
2012-08-22 8 2 3 8 
2012-08-25 4 6 8 1 

In [196]: dates = [df.index[i] for i in row_pos] 

In [197]: df.ix[dates] 
Out[197]: 
      A B C D 
2012-08-18 8 3 1 1 
2012-08-22 8 2 3 8 
2012-08-25 4 6 8 1 
+0

Danke für das Beispiel, das war mein Verständnis davon, wie es funktionieren soll, habe ich jetzt ein Beispiel dafür geliefert, wie es in meiner ursprünglichen Frage versagt. – seumas

+0

Welche Version von Pandas verwendest du? Ist es möglich, raw_disp zu teilen? Für mich funktioniert 'update' gut, y.ix [Zeitstempel] (y hat DateTimeIndex) gibt die erwartete Ausgabe (ich kann natürlich raw_disp.ix [Zeitstempel] nicht machen, da raw_disp nicht verfügbar ist.) –

+0

Pandas Version 0.8.1 , Ich habe versucht, den Fehler auf kleineren Datenrahmen zu reproduzieren, aber es tritt nicht auf. Wenn ich es auf meinem großen DataFrame von 3 Millionen plus Zeilen versuche, erhalte ich einen leeren Datenrahmen. Ich habe erfolgreich den Fehler auf einem DataFrame von 2888264 Zeilen reproduziert, aber es funktioniert gut auf einem DataFrame von 2665621 Zeilen.Ich könnte den großen DataFrame hochladen, wenn andere ihn reproduzieren möchten. – seumas

Verwandte Themen