Filtrage des données PandasFrames sur les dates

157

J'ai un Pandas DataFrame avec une colonne «date». Maintenant, je dois filtrer toutes les lignes du DataFrame qui ont des dates en dehors des deux prochains mois. Essentiellement, je n'ai besoin de conserver que les lignes qui se trouvent dans les deux prochains mois.

Quelle est la meilleure façon d'y parvenir?

AMM
la source

Réponses:

238

Si la colonne de date est l'index , utilisez .loc pour l'indexation basée sur l'étiquette ou .iloc pour l'indexation positionnelle.

Par exemple:

df.loc['2014-01-01':'2014-02-01']

Voir les détails ici http://pandas.pydata.org/pandas-docs/stable/dsintro.html#indexing-selection

Si la colonne n'est pas l'index, vous avez deux choix:

  1. Faites-en l'index (temporairement ou définitivement s'il s'agit de données chronologiques)
  2. df[(df['date'] > '2013-01-01') & (df['date'] < '2013-02-01')]

Voir ici pour l'explication générale

Remarque: .ix est obsolète.

Retozi
la source
4
Merci, lira. La date est une colonne séparée et non l'index dans mon cas. J'aurais probablement dû donner cette information en premier lieu. Ma question n'était pas très informative.
AMM
42
Vous pouvez également l'utiliser queryici. df.query('20130101 < date < 20130201').
Phillip Cloud
10
Vous devez mentionner que les filtres d'index (via .locet .ix) et de colonnes dans vos exemples ne sont pas équivalents. df.ix['2014-01-01':'2014-02-01']inclut 2014-02-01tandis que df[(df['date'] > '2013-01-01') & (df['date'] < '2013-02-01')]n'inclut pas 2013-02-01, il ne correspondra qu'aux lignes jusqu'à 2013-01-31.
Rafael Barbosa
4
Cet appel est désormais obsolète!
Mohamed Taher Alrefaie
6
Que faire si l'on ne veut pas filtrer sur une plage de dates, mais sur plusieurs datetimes?
Salem Ben Mabrouk
53

La réponse précédente n'est pas correcte dans mon expérience, vous ne pouvez pas lui passer une simple chaîne, doit être un objet datetime. Alors:

import datetime 
df.loc[datetime.date(year=2014,month=1,day=1):datetime.date(year=2014,month=2,day=1)]
orange1
la source
16
Je peux absolument passer une chaîne sans problème.
Ninjakannon
9
ix indexer est obsolète, utilisez loc - pandas.pydata.org/pandas-docs/stable/…
Nick
3
pandas convertira toute chaîne "datetime" en un objet datetime .. donc c'est correct
janscas
8
Je reçois l'erreur suivante en utilisant ceci: TypeError: '<' non pris en charge entre les instances de 'int' et 'datetime.date'
Haris Khaliq
41

Et si vos dates sont standardisées en important le package datetime, vous pouvez simplement utiliser:

df[(df['date']>datetime.date(2016,1,1)) & (df['date']<datetime.date(2016,3,1))]  

Pour standardiser votre chaîne de date à l'aide du package datetime, vous pouvez utiliser cette fonction:

import datetime
datetime.datetime.strptime
shm2008
la source
5
Il est recommandé d'utiliser df[(df['date']>pd.Timestamp(2016,1,1)) & (df['date']<pd.Timestamp(2016,3,1))].
So S
20

Si votre colonne datetime a le type de datetime Pandas (par exemple datetime64[ns]), pour un filtrage approprié, vous avez besoin de l' objet pd.Timestamp , par exemple:

from datetime import date

import pandas as pd

value_to_check = pd.Timestamp(date.today().year, 1, 1)
filter_mask = df['date_column'] < value_to_check
filtered_df = df[filter_mask]
VMAtm
la source
14

Si les dates sont dans l'index, alors simplement:

df['20160101':'20160301']
fantastique
la source
7

Vous pouvez utiliser pd.Timestamp pour effectuer une requête et une référence locale

import pandas as pd
import numpy as np

df = pd.DataFrame()
ts = pd.Timestamp

df['date'] = np.array(np.arange(10) + datetime.now().timestamp(), dtype='M8[s]')

print(df)
print(df.query('date > @ts("20190515T071320")')

avec la sortie

                 date
0 2019-05-15 07:13:16
1 2019-05-15 07:13:17
2 2019-05-15 07:13:18
3 2019-05-15 07:13:19
4 2019-05-15 07:13:20
5 2019-05-15 07:13:21
6 2019-05-15 07:13:22
7 2019-05-15 07:13:23
8 2019-05-15 07:13:24
9 2019-05-15 07:13:25


                 date
5 2019-05-15 07:13:21
6 2019-05-15 07:13:22
7 2019-05-15 07:13:23
8 2019-05-15 07:13:24
9 2019-05-15 07:13:25

Jetez un œil à la documentation pandas pour DataFrame.query , en particulier la mention sur le @préfixe udsing référencé variabile local . Dans ce cas, nous référons pd.Timestampà l'utilisation de l'alias local tspour pouvoir fournir une chaîne d'horodatage

Danielhrisca
la source
Pourriez-vous passer un lien vers la documentation des fonctions @ts?
Glen Moutrie
6

Ainsi, lors du chargement du fichier de données csv, nous devrons définir la colonne de date comme index maintenant comme ci-dessous, afin de filtrer les données en fonction d'une plage de dates. Cela n'était pas nécessaire pour la méthode désormais obsolète: pd.DataFrame.from_csv ().

Si vous souhaitez simplement afficher les données pour deux mois de janvier à février, par exemple du 01/01/2020 au 29/02/2020, vous pouvez le faire:

import pandas as pd
mydata = pd.read_csv('mydata.csv',index_col='date') # or its index number, e.g. index_col=[0]
mydata['2020-01-01':'2020-02-29'] # will pull all the columns
#if just need one column, e.g. Cost, can be done:
mydata['2020-01-01':'2020-02-29','Cost'] 

Cela a été testé pour Python 3.7. J'espère que vous trouverez cela utile.

Harry
la source
1
index_colne doit pas être stringune liste. mydata = pd.read_csv('mydata.csv',index_col='date')
Sharl Sherif le
5

Que diriez-vous d'utiliser pyjanitor

Il a des fonctionnalités intéressantes.

Après pip install pyjanitor

import janitor

df_filtered = df.filter_date(your_date_column_name, start_date, end_date)
pakira79
la source
2

Le moyen le plus court de filtrer votre dataframe par date: Supposons que votre colonne de date soit de type datetime64 [ns]

# filter by single day
df = df[df['date'].dt.strftime('%Y-%m-%d') == '2014-01-01']

# filter by single month
df = df[df['date'].dt.strftime('%Y-%m') == '2014-01']

# filter by single year
df = df[df['date'].dt.strftime('%Y') == '2014']
Ekrem Gurdal
la source
1

Je ne suis pas encore autorisé à écrire de commentaires, alors j'écrirai une réponse, si quelqu'un veut les lire tous et atteindre celui-ci.

Si l'index de l'ensemble de données est une date / heure et que vous souhaitez le filtrer uniquement par mois (par exemple), vous pouvez procéder comme suit:

df.loc[df.index.month = 3]

Cela filtrera l'ensemble de données pour vous d'ici mars.

uhetz
la source
1

Si vous avez déjà converti la chaîne en un format de date en utilisant pd.to_datetime, vous pouvez simplement utiliser:

df = df[(df['Date']> "2018-01-01") & (df['Date']< "2019-07-01")]

Jerin Mathew
la source
0

Vous pouvez simplement sélectionner la plage horaire en faisant: df.loc ['start_date': 'end_date']

Ernesto Lopez Fune
la source