Je suis capable de lire et de découper des images de données de pandas à l'aide d'objets Python datetime. Toutefois, je suis obligé d'utiliser uniquement dates existantes index. Par exemple, cela fonctionne:
>>> data
<class 'pandas.core.frame.DataFrame'>
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
Cependant, si j'utilise une date de début ou de fin qui n'est pas présente dans le DF, j'obtiens python KeyError.
Ma question: Comment interroger l'objet dataframe pour une plage de dates; même lorsque les dates de début et de fin ne sont pas présentes dans le DataFrame. Les pandas permettent-ils un découpage basé sur la plage?
J'utilise la version 0.10.1 de pandas
Utilisez searchsorted
pour trouver d'abord les temps les plus proches, puis utilisez-le pour découper.
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
Réponse courte: Triez vos données (data.sort()
), puis je pense que tout fonctionnera comme prévu.
Oui, vous pouvez découper en utilisant des dates/heures ne figurant pas dans le DataFrame. Par exemple:
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
Comme vous pouvez le constater, vous n’avez même pas besoin de créer d’objets datetime; les cordes fonctionnent.
Étant donné que les dates/heures dans votre index ne sont pas séquentielles, le comportement est étrange. Si nous mélangeons l'index de mon exemple ici ...
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
... et prenons la même tranche, nous obtenons un résultat différent. Il retourne le premier élément à l'intérieur de la plage et s'arrête au premier élément à l'extérieur de la plage.
In [18]: df['20130419':'20130422']
Out[18]:
0
2013-04-22 1.120024
2013-04-20 -0.721101
2013-04-24 0.379392
Ce n'est probablement pas un comportement utile. Si vous souhaitez sélectionner des plages de dates, serait-il judicieux de les trier d'abord par date?
df.sort_index()
Vous pouvez utiliser un simple masque pour accomplir ceci:
date_mask = (data.index > start) & (data.index < end)
dates = data.index[date_mask]
data.ix[dates]
À propos, cela fonctionne également pour l'indexation hiérarchique. Dans ce cas, data.index
serait remplacé par data.index.levels[0]
ou similaire.
J'ai eu de la difficulté avec d'autres approches mais j'ai trouvé que l'approche suivante fonctionnait pour moi:
# 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,:]