Python Pandas Dataframe corte por condiciones de fecha

Soy capaz de leer y dividir el dataframe de pandas utilizando objetos datetime de python, sin embargo, me veo obligado a usar solo las fechas existentes en el índice. Por ejemplo, esto funciona:

>>> data  DatetimeIndex: 252 entries, 2010-12-31 00:00:00 to 2010-04-01 00:00:00 Data columns: Adj Close 252 non-null values dtypes: float64(1) >>> st = datetime.datetime(2010, 12, 31, 0, 0) >>> en = datetime.datetime(2010, 12, 28, 0, 0) >>> data[st:en] Adj Close Date 2010-12-31 593.97 2010-12-30 598.86 2010-12-29 601.00 2010-12-28 598.92 

Sin embargo, si uso una fecha de inicio o finalización que no está presente en el DF, obtengo KeyError de python.

Mi pregunta: ¿Cómo puedo consultar el objeto de dataframe para un rango de fechas; incluso cuando las fechas de inicio y finalización no están presentes en el DataFrame. ¿Los pandas permiten el corte basado en rango?

Estoy usando pandas versión 0.10.1

Use searchsorted para encontrar los tiempos más cercanos primero, y luego searchsorted para cortar.

 In [15]: df = pd.DataFrame([1, 2, 3], index=[dt.datetime(2013, 1, 1), dt.datetime(2013, 1, 3), dt.datetime(2013, 1, 5)]) In [16]: df Out[16]: 0 2013-01-01 1 2013-01-03 2 2013-01-05 3 In [22]: start = df.index.searchsorted(dt.datetime(2013, 1, 2)) In [23]: end = df.index.searchsorted(dt.datetime(2013, 1, 4)) In [24]: df.ix[start:end] Out[24]: 0 2013-01-03 2 

Respuesta corta: Ordene sus datos ( data.sort() ) y luego creo que todo funcionará de la forma que espera.

Sí, puede dividir utilizando tiempos de datos que no están presentes en el DataFrame. Por ejemplo:

 In [12]: df Out[12]: 0 2013-04-20 1.120024 2013-04-21 -0.721101 2013-04-22 0.379392 2013-04-23 0.924535 2013-04-24 0.531902 2013-04-25 -0.957936 In [13]: df['20130419':'20130422'] Out[13]: 0 2013-04-20 1.120024 2013-04-21 -0.721101 2013-04-22 0.379392 

Como puede ver, ni siquiera tiene que crear objetos de fecha y hora; cuerdas de trabajo.

Debido a que los tiempos de las fechas en su índice no son secuenciales, el comportamiento es extraño. Si barajamos el índice de mi ejemplo aquí …

 In [17]: df Out[17]: 0 2013-04-22 1.120024 2013-04-20 -0.721101 2013-04-24 0.379392 2013-04-23 0.924535 2013-04-21 0.531902 2013-04-25 -0.957936 

… y tomamos la misma rebanada, obtenemos un resultado diferente. Devuelve el primer elemento dentro del rango y se detiene en el primer elemento fuera del rango.

 In [18]: df['20130419':'20130422'] Out[18]: 0 2013-04-22 1.120024 2013-04-20 -0.721101 2013-04-24 0.379392 

Probablemente este comportamiento no sea útil. Si desea seleccionar rangos de fechas, ¿tendría sentido ordenarlas por fecha primero?

 df.sort_index() 

Puedes usar una máscara simple para lograr esto:

 date_mask = (data.index > start) & (data.index < end) dates = data.index[date_mask] data.ix[dates] 

Por cierto, esto también funciona para la indexación jerárquica. En ese caso, data.index sería reemplazado por data.index.levels[0] o similar.

Tuve dificultades con otros enfoques pero encontré que el siguiente enfoque funcionó para mí:

 # Set the Index to be the Date df['Date'] = pd.to_datetime(df['Date_1'], format='%d/%m/%Y') df.set_index('Date', inplace=True) # Sort the Data df = df.sort_values('Date_1') # Slice the Data From = '2017-05-07' To = '2017-06-07' df_Z = df.loc[From:To,:]