pandas:在另一个系列的时间索引(即时间范围排除)的时间间隔内删除所有行

时间:2016-11-09 17:09:37

标签: python pandas

假设我有两个数据帧:

#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

我想删除df2df1中时间指数高达+1秒的所有行,因此产生:

#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

最有效的方法是什么?我没有看到API中的时间范围排除项有用。

3 个答案:

答案 0 :(得分:11)

您可以使用pd.merge_asof这是一个以# 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)] 开头的新包含,并且还接受一个容差参数,以匹配 +/- 指定的时间间隔。

df1

enter image description here

请注意,默认匹配是在向后方向中执行的,这意味着选择发生在右侧DataFrame("on")的最后一行,其"time"键( df2)小于或等于左(tolerance)键。因此,-参数仅在此方向上延伸(向后),从而导致direction='nearest'范围的匹配。

要使转发以及向后查找成为可能,从0.20.0开始,这可以通过使用tolerance参数和在函数调用中包含它。因此,+/-也会双向扩展,从而导致{{1}}带宽范围匹配。

答案 1 :(得分:4)

与@Nickil Maveli类似的想法,但使用reindex构建布尔索引器:

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

结果输出:

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

答案 2 :(得分:1)

一种方法是通过时间索引进行查找(假设两个时间列都是索引):

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