我有一个非常大的数据帧(300万行),如下所示:
df = pd.DataFrame({'user_id' : ['100','101','102','103','104'],
'service_id' : ['73', '73', '46', '12', '12'],
'date_of_service' : ['2015-06-10 17:00:00',
'2014-09-27 17:00:00',
'2015-01-12 17:00:00',
'2012-08-22 17:00:00',
'2013-03-07 17:00:00']})
df
我有一个用户ID列。用户提供服务,每个服务具有id(service_id)。每个服务都有一个日期(date_of_service)。
我想创建一个列,为每行计算用户过去所做的服务数量(包括当前服务),即我想要以下结果数据帧:
df = pd.DataFrame({'user_id' : ['100','101','102','103','104'],
'service_id' : ['73', '73', '46', '12', '12'],
'date_of_service' : ['2015-06-10 17:00:00',
'2014-09-27 17:00:00',
'2015-01-12 17:00:00',
'2012-08-22 17:00:00',
'2013-03-07 17:00:00'],
'number_of_past_services' : [2, 1, 1, 1, 2]})
df
我做了什么
我使用了groupby和count:
df['count_services'] = df.ix[:, 1:].groupby('user_id').transform('count')
问题是,在这里,我计算整个数据集中的所有事件。我想要的是过去的事件!
我尝试使用类似sql的操作进行过滤,例如:
len(df[df.date_of_service < df['date_of_service'][0]][df.user_id == df.user_id[0]])
为第一行提供了良好的结果。但是,这个计算只需要一行,大约需要1秒!
我想知道如何扩展它,以便我可以有效地创建一个列。
答案 0 :(得分:2)
IIUC你可以这样做:
In [69]: df['number_of_past_services'] = df.sort_values('date_of_service') \
.assign(x=1) \
.groupby('service_id')['x'].cumsum()
In [70]: df
Out[70]:
date_of_service service_id user_id number_of_past_services
0 2015-06-10 17:00:00 73 100 2
1 2014-09-27 17:00:00 73 101 1
2 2015-01-12 17:00:00 46 102 1
3 2012-08-22 17:00:00 12 103 1
4 2013-03-07 17:00:00 12 104 2
答案 1 :(得分:0)
如果我理解正确,你可以:
date_of_service
past_occurences.get(user_id, 0)
包含您需要的信息past_occurences[user_id] = past_occurences.get(user_id, 0) + 1
将更新字典。在所有步骤中,排序将是最慢的。其余的应该相当快。
PS:你也可以使用defaultdict
。这是example。