是否可以将矢量化用于Pandas Dataframe中的条件计数?

时间:2018-04-24 19:36:18

标签: python pandas dataframe vectorization

我有一个Pandas Dataframe,其中包含有关通话的数据。每个呼叫都有一个唯一的ID,每个客户都有一个ID(但可以有多个呼叫)。第三栏给出了一天。对于每个客户,我想计算7天内的最大通话次数。

我一直在使用以下代码计算每行通话后7天内的通话次数:

df['ContactsIN7Days'] = df.apply(lambda row: len(df[(df['PersonID']==row['PersonID']) & (abs(df['Day'] - row['Day']) <=7)]), axis=1)

输出:

CallID  Day PersonID    ContactsIN7Days
6       2   3           2
3       14  2           2
1       8   1           1
5       1   3           2
2       12  2           2
7       100 3           1

这有效,但这将适用于大数据集。是否有办法提高效率。通过矢量化?

1 个答案:

答案 0 :(得分:0)

IIUC这是一个令人费解的问题,但我认为你的问题是有效的解决方案。请注意,结果会修改数据框的顺序,并将Day列修改为timedelta dtype:

从您的数据框df开始:

   CallID  Day  PersonID
0       6    2         3
1       3   14         2
2       1    8         1
3       5    1         3
4       2   12         2
5       7  100         3

首先将Day修改为timedelta系列:

df['Day'] = pd.to_timedelta(df['Day'], unit='d')

然后,使用pd.merge_asof,将您的数据框与7天内每个人的通话计数合并。要实现此目的,请使用groupbypd.Grouper,频率为7天:

new_df = (pd.merge_asof(df.sort_values(['Day']),
                        df.sort_values(['Day'])
                        .groupby([pd.Grouper(key='Day', freq='7d'), 'PersonID'])
                        .size()
                        .to_frame('ContactsIN7Days')
                        .reset_index(),
                        left_on='Day', right_on='Day',
                        left_by='PersonID', right_by='PersonID',
                        direction='nearest'))

您生成的new_df将如下所示:

   CallID      Day  PersonID  ContactsIN7Days
0       5   1 days         3                2
1       6   2 days         3                2
2       1   8 days         1                1
3       2  12 days         2                2
4       3  14 days         2                2
5       7 100 days         3                1