假设我有两个数据帧:
#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
我想删除df2
中df1
中时间指数高达+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中的时间范围排除项有用。
答案 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
请注意,默认匹配是在向后方向中执行的,这意味着选择发生在右侧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)