Il y a deux solutions possibles:
- Utilisez un masque booléen, puis utilisez
df.loc[mask]
- Définissez la colonne de date comme DatetimeIndex, puis utilisez
df[start_date : end_date]
Utilisation d'un masque booléen :
S'assurer df['date']
est une série avec dtype datetime64[ns]
:
df['date'] = pd.to_datetime(df['date'])
Faites un masque booléen. start_date
et end_date
peut être datetime.datetime
s,
np.datetime64
s, pd.Timestamp
s ou même des chaînes datetime:
#greater than the start date and smaller than the end date
mask = (df['date'] > start_date) & (df['date'] <= end_date)
Sélectionnez le sous-DataFrame:
df.loc[mask]
ou réattribuer à df
df = df.loc[mask]
Par exemple,
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.random((200,3)))
df['date'] = pd.date_range('2000-1-1', periods=200, freq='D')
mask = (df['date'] > '2000-6-1') & (df['date'] <= '2000-6-10')
print(df.loc[mask])
rendements
0 1 2 date
153 0.208875 0.727656 0.037787 2000-06-02
154 0.750800 0.776498 0.237716 2000-06-03
155 0.812008 0.127338 0.397240 2000-06-04
156 0.639937 0.207359 0.533527 2000-06-05
157 0.416998 0.845658 0.872826 2000-06-06
158 0.440069 0.338690 0.847545 2000-06-07
159 0.202354 0.624833 0.740254 2000-06-08
160 0.465746 0.080888 0.155452 2000-06-09
161 0.858232 0.190321 0.432574 2000-06-10
Utilisation d'un DatetimeIndex :
Si vous comptez effectuer de nombreuses sélections par date, il peut être plus rapide de définir d'abord la
date
colonne comme index. Ensuite, vous pouvez sélectionner des lignes par date en utilisant
df.loc[start_date:end_date]
.
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.random((200,3)))
df['date'] = pd.date_range('2000-1-1', periods=200, freq='D')
df = df.set_index(['date'])
print(df.loc['2000-6-1':'2000-6-10'])
rendements
0 1 2
date
2000-06-01 0.040457 0.326594 0.492136 # <- includes start_date
2000-06-02 0.279323 0.877446 0.464523
2000-06-03 0.328068 0.837669 0.608559
2000-06-04 0.107959 0.678297 0.517435
2000-06-05 0.131555 0.418380 0.025725
2000-06-06 0.999961 0.619517 0.206108
2000-06-07 0.129270 0.024533 0.154769
2000-06-08 0.441010 0.741781 0.470402
2000-06-09 0.682101 0.375660 0.009916
2000-06-10 0.754488 0.352293 0.339337
Alors que l'indexation de liste Python, par exemple seq[start:end]
inclut start
mais pas end
, en revanche, Pandas df.loc[start_date : end_date]
inclut les deux points d'extrémité dans le résultat s'ils sont dans l'index. Cependant, ni l'un start_date
ni l' autre ne end_date
doivent figurer dans l'index.
Notez également que pd.read_csv
possède un parse_dates
paramètre que vous pouvez utiliser pour analyser la date
colonne en tant que datetime64
s. Ainsi, si vous utilisez parse_dates
, vous n'aurez pas besoin d'utiliser df['date'] = pd.to_datetime(df['date'])
.
df = df.set_index(['date'])
étape, j'ai trouvé que l'index doit également être trié (viadf.sort_index(inplace=True, ascending=True)
), sinon vous pouvez obtenir des résultats DataFrame moins que pleins ou même videsdf.loc['2000-6-1':'2000-6-10']
. Et si vous utilisezascending=False
, cela ne fonctionnera pas du tout, même si vous l'inversez avecdf.loc['2000-6-10':'2000-6-1']
Je pense que la meilleure option sera d'utiliser les vérifications directes plutôt que d'utiliser la fonction loc:
Ça marche pour moi.
Le problème majeur avec la fonction loc avec une tranche est que les limites doivent être présentes dans les valeurs réelles, sinon cela entraînera KeyError.
la source
loc
sont excellentes. Et il me semble que, comme le dit unutbu, ni start_date ni end_date ne doivent cependant figurer dans l'index .Vous pouvez également utiliser
between
:la source
between_time
: pandas.pydata.org/pandas-docs/version/0.20.3/generatedVous pouvez utiliser la
isin
méthode sur ladate
colonne comme cecidf[df["date"].isin(pd.date_range(start_date, end_date))]
Remarque: cela ne fonctionne qu'avec les dates (comme le demande la question) et non avec les horodatages.
Exemple:
qui donne
la source
En gardant la solution simple et pythonique, je vous suggère d'essayer ceci.
Dans le cas où vous allez faire cela fréquemment, la meilleure solution serait de définir d'abord la colonne de date comme index qui convertira la colonne en DateTimeIndex et utilisera la condition suivante pour découper n'importe quelle plage de dates.
la source
Avec mes tests de
pandas
version,0.22.0
vous pouvez maintenant répondre à cette question plus facilement avec un code plus lisible en utilisant simplementbetween
.Supposons que vous souhaitiez saisir les dates entre le 27 novembre 2018 et le 15 janvier 2019:
Notez l'argument inclusif. très utile lorsque vous souhaitez être explicite sur votre gamme. notez que lorsque défini sur True, nous retournons également le 27 novembre 2018:
Cette méthode est également plus rapide que la
isin
méthode mentionnée précédemment :Cependant, ce n'est pas plus rapide que la réponse actuellement acceptée, fournie par unutbu, uniquement si le masque est déjà créé . mais si le masque est dynamique et doit être réaffecté à plusieurs reprises, ma méthode peut être plus efficace:
la source
Une autre option, comment y parvenir, consiste à utiliser la
pandas.DataFrame.query()
méthode. Permettez-moi de vous montrer un exemple sur le bloc de données suivant appelédf
.En tant qu'argument, utilisez la condition de filtrage comme ceci:
Si vous ne souhaitez pas inclure de limites, modifiez simplement la condition comme suit:
la source
Je préfère ne pas modifier le fichier
df
.Une option est de récupérer les
index
desstart
et lesend
dates:ce qui se traduit par:
la source