假设有两个熊猫Series
(或DataFrames
)都包含不同的datetime
值。例如,一个系列/框架包含消息,而另一个包含特定事件。现在,我想过滤掉所有在之后发布的消息(意思是:事件发生后n
分钟之内)。我该如何使用熊猫呢?
(除了使用两个包裹的for
循环外,我还希望有一些熊猫风格的东西,也许更有效。像使用groupby
或类似的东西。) >
一些样本数据可能是:
import pandas as pd
messages = pd.DataFrame([
[pd.to_datetime("2000-01-01 09:00:00"), "non-relevant msg 1"],
[pd.to_datetime("2000-01-01 09:02:11"), "non-relevant msg 2"],
[pd.to_datetime("2000-01-01 09:03:30"), "relevant msg 1"],
[pd.to_datetime("2000-01-01 09:04:30"), "relevant msg 2"],
[pd.to_datetime("2000-01-01 09:10:11"), "non-relevant msg 3"],
[pd.to_datetime("2000-01-01 10:00:15"), "relevant again 1"],
[pd.to_datetime("2000-01-01 10:03:15"), "relevant again 2"],
[pd.to_datetime("2000-01-01 10:07:00"), "non-relevant msg 4"],
], columns=["created_at", "text"])
events = pd.Series([
pd.to_datetime("2000-01-01 09:02:59"),
pd.to_datetime("2000-01-01 10:00:00"),
])
n = pd.Timedelta("5min")
应提供以下输出:
output = pd.DataFrame([
[pd.to_datetime("2000-01-01 09:03:30"), "relevant msg 1"],
[pd.to_datetime("2000-01-01 09:04:30"), "relevant msg 2"],
[pd.to_datetime("2000-01-01 10:00:15"), "relevant again 1"],
[pd.to_datetime("2000-01-01 10:03:15"), "relevant again 2"],
], columns=["created_at", "text"])
答案 0 :(得分:1)
这是我对您的问题的理解,但是如果您发布答案应该是什么样,将会更加清楚。
filtered_dfs = []
for event in events:
condition = messages.created_at.between(event,event+n)
filtered_dfs.append(messages.loc[condition])
这是两个df的外观:
#Output
created_at text
2 2000-01-01 09:03:30 relevant msg 1
3 2000-01-01 09:04:30 relevant msg 2
created_at text
5 2000-01-01 10:00:15 relevant again 1
6 2000-01-01 10:03:15 relevant again 2
答案 1 :(得分:1)
如果我正确理解,应该有几种方法可以解决您的问题-在这里找到有效的方法确实是个问题。
我可能会使用apply
和for循环,并使用类似这样的函数:
def follows_event(time, events=events, gap = pd.Timedelta('5min')):
follows = False
for i in list(events):
if i < time and i+gap > time:
follows = True
break
return follows
设置完成后,您可以简单地使用它来创建一列,告诉您在数据之前的5分钟内是否有事件发生,然后按照您的意愿进行处理。
df['follows_event'] = df.created_at.apply(follows_event)
如果要在此间隔内删除那些,请使用:
df_filtered = df[df.follows_event != True]
答案 2 :(得分:1)
“我希望有一些熊猫般的东西,也许更高效” 。是的,通过使用numpy
和pandas
功能可以更有效地获得预期结果。
受this答案启发的聚会。
a = messages['created_at'].to_numpy()
bh = (events + n).to_numpy()
bl = events.to_numpy()
i, j = np.where((a[:, None] >= bl) & (a[:, None] <= bh))
messages.loc[i].reset_index(drop=True)
created_at text
0 2000-01-01 09:03:30 relevant msg 1
1 2000-01-01 09:04:30 relevant msg 2
2 2000-01-01 10:00:15 relevant again 1
3 2000-01-01 10:03:15 relevant again 2
说明
首先,我们将created_at
列创建为一个numpy数组,并创建日期的高阈值和低阈值。低= events
和高= events+n
。
然后,我们使用np.where
有条件地遍历messages
数据框的行,并存储与日期时间在阈值之间的条件匹配的行的索引。我们将这些索引存储在i
中。
由于有了索引,我们可以简单地使用.loc
来获取所需的行。
注意,如果您的熊猫版本低于0.24.0,请使用.values
而不是to_numpy
。