Python 是否可以对数据帧中的行的条件计数使用矢量化?

Python 是否可以对数据帧中的行的条件计数使用矢量化?,python,pandas,dataframe,vectorization,Python,Pandas,Dataframe,Vectorization,我有一个包含通话数据的数据框。每个电话都有一个唯一的ID,每个客户都有一个ID(但可以有多个电话)。第三栏是一天。对于每个客户,我想计算7天内拨打的最大电话数 我一直在使用以下代码计算每行通话后7天内的通话次数: df['ContactsIN7Days'] = df.apply(lambda row: len(df[(df['PersonID']==row['PersonID']) & (abs(df['Day'] - row['Day']) <=7)]), axis=1) 这是

我有一个包含通话数据的数据框。每个电话都有一个唯一的ID,每个客户都有一个ID(但可以有多个电话)。第三栏是一天。对于每个客户,我想计算7天内拨打的最大电话数

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

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

这是可行的,但这将应用于大数据集。有没有办法让这更有效。通过矢量化?

IIUC这是一个复杂的问题,但我认为有效的解决方案。请注意,数据帧的顺序因此被修改,并且
Day
列被修改为timedelta数据类型:

从数据帧开始
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
首先,将
修改为时间增量序列:

df['Day'] = pd.to_timedelta(df['Day'], unit='d')
然后,使用,将数据帧与每个人在7天内的呼叫数合并。要获得此信息,请使用
groupby
,频率为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
   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