Filtro Pandas DataFrames per data


157

Ho un Pandas DataFrame con una colonna 'data'. Ora devo filtrare tutte le righe nel DataFrame che hanno date al di fuori dei prossimi due mesi. In sostanza, ho solo bisogno di conservare le righe che si trovano entro i prossimi due mesi.

Qual è il modo migliore per raggiungere questo obiettivo?

Risposte:


238

Se la colonna della data è l'indice , utilizzare .loc per l'indicizzazione basata su etichetta o .iloc per l'indicizzazione posizionale.

Per esempio:

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

Vedi i dettagli qui http://pandas.pydata.org/pandas-docs/stable/dsintro.html#indexing-selection

Se la colonna non è l'indice, hai due possibilità:

  1. Rendilo l'indice (temporaneamente o permanentemente se si tratta di dati di serie temporali)
  2. df[(df['date'] > '2013-01-01') & (df['date'] < '2013-02-01')]

Vedi qui per la spiegazione generale

Nota: .ix è obsoleto.


4
Grazie, leggerò. La data è una colonna separata e non l'indice nel mio caso. Avrei probabilmente dovuto dare queste informazioni in primo luogo. La mia domanda non era molto istruttiva.
AMM,

42
Puoi usare anche queryqui. df.query('20130101 < date < 20130201').
Phillip Cloud,

10
Dovresti dire che i filtri per indice (via .loce .ix) e colonne nei tuoi esempi non sono equivalenti. df.ix['2014-01-01':'2014-02-01']include 2014-02-01mentre df[(df['date'] > '2013-01-01') & (df['date'] < '2013-02-01')]non include 2013-02-01, corrisponderà solo alle righe fino a 2013-01-31.
Rafael Barbosa,

4
Questa chiamata è obsoleta ora!
Mohamed Taher Alrefaie,

6
Cosa succede se non si desidera filtrare su un intervallo di date, ma su più periodi di dati?
Salem Ben Mabrouk,

53

La risposta precedente non è corretta nella mia esperienza, non puoi passarle una semplice stringa, deve essere un oggetto datetime. Così:

import datetime 
df.loc[datetime.date(year=2014,month=1,day=1):datetime.date(year=2014,month=2,day=1)]

16
Posso assolutamente passare una stringa senza problemi.
Ninjakannon,

9
indicizzatore ix è deprecato, usa loc - pandas.pydata.org/pandas-docs/stable/…
Nick,

3
panda convertirà qualsiasi stringa "datetime" in un oggetto datetime .. quindi è corretto
janscas

8
Ricevo il seguente errore usando questo: TypeError: '<' non supportato tra istanze di 'int' e 'datetime.date'
Haris Khaliq,

41

E se le tue date sono standardizzate importando il pacchetto datetime, puoi semplicemente usare:

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

Per standardizzare la stringa di date utilizzando il pacchetto datetime, è possibile utilizzare questa funzione:

import datetime
datetime.datetime.strptime

5
Si consiglia di utilizzare df[(df['date']>pd.Timestamp(2016,1,1)) & (df['date']<pd.Timestamp(2016,3,1))].
Quindi,

20

Se la colonna datetime ha il tipo di datetime Pandas (ad es. datetime64[ns]), Per un filtro adeguato è necessario l' oggetto pd.Timestamp , ad esempio:

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]

14

Se le date sono nell'indice, semplicemente:

df['20160101':'20160301']

7

È possibile utilizzare pd.Timestamp per eseguire una query e un riferimento 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")')

con l'uscita

                 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

Dai un'occhiata alla documentazione di Panda per DataFrame.query , in particolare la menzione della variabile locale a cui fa riferimento il @prefisso udsing . In questo caso facciamo riferimento pd.Timestampusando l'alias locale tsper poter fornire una stringa timestamp


Potresti passare un link per la documentazione delle funzioni di @ts?
Glen Moutrie,

6

Quindi, quando si carica il file di dati CSV, sarà necessario impostare la colonna della data come indice ora come di seguito, al fine di filtrare i dati in base a un intervallo di date. Questo non era necessario per il metodo ormai deprecato: pd.DataFrame.from_csv ().

Se vuoi solo mostrare i dati per due mesi da gennaio a febbraio, ad es. Dal 2020-01-01 al 2020-02-29, puoi farlo:

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'] 

Questo è stato testato funzionando con Python 3.7. Spero che lo troverai utile.


1
index_coldeve essere un stringnon elenco. mydata = pd.read_csv('mydata.csv',index_col='date')
Sharl Sherif,

5

Che ne dici di usare pyjanitor

Ha caratteristiche interessanti.

Dopo pip install pyjanitor

import janitor

df_filtered = df.filter_date(your_date_column_name, start_date, end_date)

2

Il modo più breve per filtrare il tuo dataframe per data: supponiamo che la colonna della tua data sia il tipo di 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']

1

Non sono ancora autorizzato a scrivere commenti, quindi scriverò una risposta, se qualcuno li leggerà tutti e raggiungerà questo.

Se l'indice del set di dati è un datetime e si desidera filtrarlo solo per (ad esempio) mesi, è possibile effettuare le seguenti operazioni:

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

Questo filtrerà il set di dati per te entro marzo.


1

Se hai già convertito la stringa in un formato data usando pd.to_datetime puoi semplicemente usare:

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


0

Puoi semplicemente selezionare l'intervallo di tempo facendo: df.loc ['start_date': 'end_date']

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.