Lọc dữ liệu Pandas vào ngày


157

Tôi có một DataFrame Pandas với cột 'ngày'. Bây giờ tôi cần lọc ra tất cả các hàng trong DataFrame có ngày ngoài hai tháng tới. Về cơ bản, tôi chỉ cần giữ lại các hàng trong vòng hai tháng tới.

cách tốt nhất để đạt được điều này là gì?

Câu trả lời:


238

Nếu cột ngày là chỉ mục , thì hãy sử dụng .loc để lập chỉ mục dựa trên nhãn hoặc .iloc để lập chỉ mục theo vị trí.

Ví dụ:

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

Xem chi tiết tại đây http://pandas.pydata.org/pandas-docs/urdy/dsintro.html#indexing-selection

Nếu cột là không chỉ số bạn có hai lựa chọn:

  1. Biến nó thành chỉ mục (tạm thời hoặc vĩnh viễn nếu đó là dữ liệu chuỗi thời gian)
  2. df[(df['date'] > '2013-01-01') & (df['date'] < '2013-02-01')]

Xem ở đây để giải thích chung

Lưu ý: .ix không dùng nữa.


4
Cảm ơn bạn, sẽ đọc. Ngày là một cột riêng biệt và không phải là chỉ mục trong trường hợp của tôi. Tôi có lẽ nên đưa thông tin đó ở nơi đầu tiên. Câu hỏi của tôi không nhiều thông tin.
AMM

42
Bạn có thể sử dụng queryở đây là tốt. df.query('20130101 < date < 20130201').
Đám mây Phillip

10
Bạn nên đề cập rằng các bộ lọc cho chỉ mục (thông qua .loc.ix) và các cột trong ví dụ của bạn không tương đương. df.ix['2014-01-01':'2014-02-01']bao gồm 2014-02-01trong khi df[(df['date'] > '2013-01-01') & (df['date'] < '2013-02-01')]không bao gồm 2013-02-01, nó sẽ chỉ khớp với các hàng lên đến 2013-01-31.
Rafael Barbosa

4
Cuộc gọi này không được chấp nhận ngay bây giờ!
Mohamed Taher Alrefaie

6
Điều gì xảy ra nếu một người không muốn lọc trên phạm vi ngày, nhưng trên nhiều thời gian?
Salem Ben Mabrouk

53

Câu trả lời trước đây không đúng theo kinh nghiệm của tôi, bạn không thể truyền cho nó một chuỗi đơn giản, cần phải là một đối tượng datetime. Vì thế:

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

16
Tôi hoàn toàn có thể vượt qua một chuỗi không có vấn đề.
Ninjakannon

9
Bộ chỉ mục ix không được dùng nữa, hãy sử dụng loc - pandas.pydata.org/pandas-docs/urdy/ Kẻ
Nick

3
gấu trúc sẽ chuyển đổi bất kỳ chuỗi "datetime" nào thành đối tượng datetime .. vì vậy nó chính xác
janscas 16/03/18

8
Tôi nhận được lỗi sau khi sử dụng lỗi này: TypeError: '<' không được hỗ trợ giữa các phiên bản của 'int' và 'datetime.date'
Haris Khaliq

41

Và nếu ngày của bạn được chuẩn hóa bằng cách nhập gói datetime, bạn chỉ cần sử dụng:

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

Để chuẩn hóa chuỗi ngày của bạn bằng gói datetime, bạn có thể sử dụng chức năng này:

import datetime
datetime.datetime.strptime

5
Đó là khuyến cáo để sử dụng df[(df['date']>pd.Timestamp(2016,1,1)) & (df['date']<pd.Timestamp(2016,3,1))].
Vì vậy,

20

Nếu cột datetime của bạn có loại datetime Pandas (ví dụ datetime64[ns]), để lọc đúng, bạn cần đối tượng pd.Timestamp , ví dụ:

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]


7

Bạn có thể sử dụng pd.Timestamp để thực hiện truy vấn và tham chiếu cục bộ

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")')

với đầu ra

                 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

Hãy xem tài liệu về gấu trúc cho DataFrame.query , cụ thể là đề cập đến @tiền tố udsing tham chiếu địa phương . Trong trường hợp này, chúng tôi tham chiếu pd.Timestampbằng cách sử dụng bí danh cục bộ tsđể có thể cung cấp chuỗi dấu thời gian


Bạn có thể vượt qua một liên kết cho tài liệu cho các chức năng @ts?
Glen Moutrie

6

Vì vậy, khi tải tệp dữ liệu csv, chúng tôi sẽ cần đặt cột ngày làm chỉ mục ngay bây giờ như bên dưới, để lọc dữ liệu dựa trên phạm vi ngày. Điều này là không cần thiết cho phương thức không dùng nữa: pd.DataFrame.from_csv ().

Nếu bạn chỉ muốn hiển thị dữ liệu trong hai tháng từ tháng 1 đến tháng 2, ví dụ: 2020-01-01 đến 2020-02-29, bạn có thể làm như vậy:

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

Điều này đã được thử nghiệm làm việc cho Python 3.7. Hy vọng bạn sẽ tìm thấy điều này hữu ích.


1
index_colphải là stringmột danh sách không. mydata = pd.read_csv('mydata.csv',index_col='date')
Sharl Sherif

5

Cách sử dụng pyjanitor

Nó có các tính năng mát mẻ.

Sau pip install pyjanitor

import janitor

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

2

Cách ngắn nhất để lọc khung dữ liệu của bạn theo ngày: Giả sử cột ngày của bạn là loại 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

Tôi chưa được phép viết bất kỳ bình luận nào, vì vậy tôi sẽ viết câu trả lời, nếu ai đó sẽ đọc tất cả các bình luận đó và tiếp cận ý kiến ​​này.

Nếu chỉ mục của tập dữ liệu là datetime và bạn muốn lọc chỉ sau (ví dụ) tháng, bạn có thể thực hiện như sau:

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

Điều đó sẽ lọc dữ liệu cho bạn vào tháng ba.


1

Nếu bạn đã chuyển đổi chuỗi thành định dạng ngày bằng pd.to_datetime, bạn chỉ có thể sử dụng:

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


0

Bạn chỉ có thể chọn phạm vi thời gian bằng cách thực hiện: df.loc ['start_date': 'end_date']

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.