2016-11-09 27 views
5

Giả sử tôi có hai dataframes:gấu trúc: Hủy bỏ tất cả các hàng trong khoảng thời gian chỉ số thời gian của loạt khác (tức là phạm vi loại trừ thời gian)

#df1 
time 
2016-09-12 13:00:00.017 1.0 
2016-09-12 13:00:03.233 1.0 
2016-09-12 13:00:10.256 1.0 
2016-09-12 13:00:19.605 1.0 

#df2 
time 
2016-09-12 13:00:00.017 1.0 
2016-09-12 13:00:00.233 0.0 
2016-09-12 13:00:01.016 1.0 
2016-09-12 13:00:01.505 0.0 
2016-09-12 13:00:06.017 1.0 
2016-09-12 13:00:07.233 0.0 
2016-09-12 13:00:08.256 1.0 
2016-09-12 13:00:19.705 0.0 

Tôi muốn loại bỏ tất cả các hàng trong df2 được lên đến 1 giây của các chỉ số thời gian trong df1, vì vậy năng suất:

#result 
time 
2016-09-12 13:00:01.505 0.0 
2016-09-12 13:00:06.017 1.0 
2016-09-12 13:00:07.233 0.0 
2016-09-12 13:00:08.256 1.0 

Cách hiệu quả nhất để làm điều này là gì? Tôi không thấy bất kỳ điều gì hữu ích cho loại trừ phạm vi thời gian trong API.

Trả lời

11

Bạn có thể sử dụng pd.merge_asof là một bao gồm mới bắt đầu bằng 0.19.0 và cũng chấp nhận đối số khoan dung để đối sánh +/- khoảng thời gian được chỉ định.

# Assuming time to be set as the index axis for both df's 
df1.reset_index(inplace=True) 
df2.reset_index(inplace=True) 

df2.loc[pd.merge_asof(df2, df1, on='time', tolerance=pd.Timedelta('1s')).isnull().any(1)] 

enter image description here

Lưu ý rằng phù hợp với mặc định sẽ được thực hiện trong ngược hướng, có nghĩa là lựa chọn xuất hiện ở hàng cuối cùng trong DataFrame phải (df1) mà "on" chính (mà là "time") nhỏ hơn hoặc bằng phím trái (df2). Do đó, thông số tolerance chỉ mở rộng theo hướng này (lạc hậu) dẫn đến phạm vi kết hợp phù hợp với -.

Để có cả mong cũng như ngược tra cứu có thể, bắt đầu với 0.20.0 này có thể đạt được bằng cách sử dụng direction='nearest' đối số và bao gồm nó trong lời gọi hàm. Do đó, tolerance cũng được mở rộng theo cả hai cách dẫn đến phạm vi kết hợp băng thông +/-.

+1

đánh bại tôi vào nó ... – piRSquared

+2

haha..Xác nhận về bình luận của @ MaxU vài ngày trước về thông số dung sai của nó. –

1

Một cách để làm điều đó sẽ được tra cứu qua thời gian lập chỉ mục (giả sử cả thời gian cột là chỉ số):

td = pd.to_timedelta(1, unit='s') 
df2.apply(lambda row: df1[row.name - td:row.name].size > 0, axis=1) 
4

ý tưởng tương tự như @Nickil Maveli, nhưng sử dụng reindex để xây dựng một indexer Boolean:

df2 = df2[df1.reindex(df2.index, method='nearest', tolerance=pd.Timedelta('1s')).isnull()] 

Các kết quả đầu ra:

time 
2016-09-12 13:00:01.505 0.0 
2016-09-12 13:00:06.017 1.0 
2016-09-12 13:00:07.233 0.0 
2016-09-12 13:00:08.256 1.0 
Các vấn đề liên quan