在行中列出的时间之前,按时间对Pandas进行分组和求和

3

有趣的问题!

我有一个数据框,其中包含许多列,但相关的列是:id、event_time

这些id是可重复的。我尝试计算在每行中id发生的时间之前数据框中出现id的次数。因此,如果id = 43且event_time = 2016-01-01 12:00:00,则我想知道在此event_time之前id 43出现的所有次数。event_time已经通过pd.to_datetime()进行了格式化,但它不是索引。

这个循环解决了这个问题,但对于超过400k行的数据非常慢。

occs=[]
for ix in range(len(df)):
    cur=df.iloc[[ix]]
    occurrences=df[(df.id==cur.id.values[0])&
    (df.event_time < cur.event_time.values[0])]
    occs.append(len(occurrences))
df['total_occ']=occs

我知道肯定有更好的方法,可能需要使用group by。关键是它只能在事件发生前,并且它们的顺序不是按照时间顺序排列。

谢谢大家!

* 编辑示例数据 *

 id      |        event_time        |      count
 11               2016-11-09                1
 8                2016-11-10                1
 32               2016-11-08                0
 11               2016-11-08                0
 8                2016-11-11                2
 8                2016-11-07                0

尽管计数将大幅增加,达到数千个......但计数是所需的输出。


1
你能添加一些数据样本并提供期望输出吗? - jezrael
2个回答

5
我认为这可能是你想要的:

我认为这可能是您需要的内容:

#sort df by id and datetime
df.sort_values(['id','event_time'],inplace=True)
#add cumulative count for each id.
df['count'] = df.groupby('id').cumcount()

df
Out[1114]: 
   id event_time  count
5   8 2016-11-07      0
1   8 2016-11-10      1
4   8 2016-11-11      2
3  11 2016-11-08      0
0  11 2016-11-09      1
2  32 2016-11-08      0

1
那正是我正在寻找的。它运行时间不到1秒,而且工作得非常好。你是个英雄,艾伦! - Lois Keller
没关系,@LoisKeller。很高兴能帮到你。 - Allen Qin

0
从你的代码中,我猜测你的意思是要计算出在与给定的id第一次出现的event_time之前的event_timeid出现的次数。
因此,需要找出这些事件发生的时间:
first_event_times = df.groupby('id', as_index = False).event_time.first().rename(columns = {'first_event':'first_event_time'})

将这些第一次事件时间与数据框合并,并仅保留相关列:
df0 = df[['id','event_time']].merge(first_event_times)

筛选出 event_time < first_event_time 的行:

df0 = df0[df0.event_time < df0.first_event_time]

获取剩余内容中每个 id 的行数:

df0.groupby(['id','first_event_time']).size().to_frame('count') # gives you the desired output

所以在第一行代码中,我得到了一个 TypeError: 'set' object is not callable 的错误,但我认为合并是正确的想法。 - Lois Keller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接