计算大型数据集中某个元素的所有过去出现次数

Posted

技术标签:

【中文标题】计算大型数据集中某个元素的所有过去出现次数【英文标题】:Count all past occurences of an element in a large dataset 【发布时间】:2017-06-22 09:51:24 【问题描述】:

我有一个相当大的数据框(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 秒左右!

我想知道如何扩展它,以便我可以有效地创建一列。

【问题讨论】:

【参考方案1】:

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

【讨论】:

@PeterMartigny,不客气。如果您认为 accepting 回答了您的问题,请考虑 accepting 的答案【参考方案2】:

如果我理解正确,你可以:

date_of_service对数据进行排序 创建一个包含过去事件的空字典 遍历所有已排序的行: past_occurences.get(user_id, 0) 拥有您需要的信息 past_occurences[user_id] = past_occurences.get(user_id, 0) + 1 将更新字典。

在所有步骤中,排序是最慢的。其余的应该相当快。

PS:您也可以使用defaultdict。这是example。

【讨论】:

以上是关于计算大型数据集中某个元素的所有过去出现次数的主要内容,如果未能解决你的问题,请参考以下文章

机器学习是否有可能从数据集中找到所有元素的概率分布?

excel如何统计某个字段内所有出现的字段的次数

Python:计算python数据框中每个数字的出现次数

从大型数据集中提取唯一数据

机器学习算法(KNN)

为基于 2D 条件的子集索引大型 3D HDF5 数据集