2012-08-16 7 views
10

tengo unas grandes pandas DataFrameLa selección de un subconjunto de un pandas trama de datos indexados por DatetimeIndex con una lista de marcas de hora

<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) 

que seleccionar un subconjunto de ese DataFrame usando .ix[start_datetime:end_datetime] y paso a un peakdetect function que devuelve el índice y valor de los máximos y mínimos locales en dos listas separadas. Extraigo la posición de índice de los máximos y usando DataFrame.index obtengo una lista de pandas TimeStamps.

Intento extraer el subconjunto relevante del DataFrame grande pasando la lista de TimeStamps a .ix[] pero siempre parece devolver un DataFrame vacío. Puedo recorrer la lista de TimeStamps y obtener las filas relevantes del DataFrame pero este es un proceso largo y pensé que ix[] debería aceptar una lista de valores de acuerdo con the docs? (Aunque veo que el ejemplo para pandas 0.7 utiliza un numpy.ndarray de numpy.datetime64)

Actualización: se selecciona Un pequeño 8 segundo subconjunto de la trama de datos a continuación, # líneas muestran algunos de los valores:

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 

actualización 2: I created a gist, que realmente funciona porque cuando los datos se cargan en desde cSV las columnas de índice de marcas de tiempo se almacenan como numpy gama de objetos que parecen ser cadenas. A diferencia de mi propio código, donde el índice es del tipo <class 'pandas.tseries.index.DatetimeIndex'> y cada elemento es del tipo <class 'pandas.lib.Timestamp'>, pensé que pasar una lista de pandas.lib.Timestamp funcionaría igual que pasar marcas de tiempo individuales, ¿se consideraría un error?

Si creo el DataFrame original con el índice como una lista de cadenas, consultar con una lista de cadenas funciona bien. Sin embargo, sí aumenta significativamente el tamaño de bytes del DataFrame.

Actualización 3: El error sólo parece ocurrir con grandes tramas de datos, que volvió a ejecutar el código en diferentes tamaños de trama de datos (con cierto detalle en un comentario más abajo) y parece que se produzca en una trama de datos por encima de 2,7 millones de registros . Usar cadenas en lugar de TimeStamps resuelve el problema, pero aumenta el uso de la memoria.

Corregido En el último maestro de github (18/09/2012), vea el comentario de Wes en la parte inferior de la página.

Respuesta

15

df.ix [mi_lista_de_datos] debería funcionar bien.

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

Gracias por el ejemplo, esa era mi comprensión de cómo se supone que funciona, ahora he proporcionado un ejemplo de cómo está fallando en mi pregunta original. – seumas

+0

¿Qué versión de pandas estás usando? ¿Es posible compartir raw_disp? Para mí 'update' funciona bien, y.ix [timestamps] (y tiene DateTimeIndex) da el resultado esperado (no puedo hacer raw_disp.ix [timestamps] por supuesto, ya que raw_disp no está disponible.) –

+0

Pandas versión 0.8.1 , He intentado reproducir el error en DataFrames más pequeños pero no ocurre. Cuando lo pruebo en mi gran DataFrame de 3 millones de filas más obtengo un Empty DataFrame. He reproducido correctamente el error en un DataFrame de 2888264 filas, pero funciona bien en un DataFrame de 2665621 filas.Podría subir el DataFrame grande si otros desean reproducirlo. – seumas

Cuestiones relacionadas