Pandas - 根据条件计算相关事件

我想创建 DataFrame,可能是稀疏的,它测量用户之间的相关性。在这里,我对 和 之间相关性的定义user_1是user_2它们action在同一天执行相同的次数。


我将尝试用一个例子更好地解释自己。假设我有以下数据框:


date    action  user

6   2019-05-05  b   user_3

9   2019-05-05  b   user_2

1   2019-05-06  b   user_2

5   2019-05-06  a   user_1

0   2019-05-07  b   user_3

7   2019-05-07  a   user_2

8   2019-05-07  a   user_1

2   2019-05-08  c   user_2

4   2019-05-08  c   user_1

3   2019-05-09  c   user_3

可以使用以下代码段生成:


import numpy as np

import pandas as pd


np.random.seed(12)

users = np.random.choice(['user_1', 'user_2', 'user_3'], size=10)

actions = np.random.choice(['a', 'b', 'c'], size=10)

date = np.random.choice(pd.date_range(start='2019-05-05', end='2019-05-10', freq='D'), size=10)


df = pd.DataFrame(dict(date=date, action=actions, user=users))

df.date = pd.to_datetime(df.date)

df = df.sort_values('date')

user_1和之间的相关性user_2是2因为它们都执行a了当天的07操作和c当天的操作08。user_2和之间的相关性user_3是1因为他们b在 day执行了操作05。其余的都是NaN. 他们输出我正在寻找的DataFrame如下:


        user_1  user_2  user_3

user_1  NaN     NaN     NaN

user_2  2.0     NaN     NaN

user_3  NaN     1.0     NaN

我创建此 DataFrame 的低效方法如下:


from itertools import combinations

df_result = pd.DataFrame(columns=['user_1', 'user_2', 'user_3'],

                         index=['user_1', 'user_2', 'user_3'], dtype=np.float64)    


for index, group in df.groupby(['date', 'action']):

    for x, y in combinations(list(group.user.values), 2):

        if np.isnan(df_result.loc[x,y]):

            df_result.loc[x, y] = 1

        else:

            df_result.loc[x, y] = df_result.loc[x, y] + 1

这种方法的问题是在我的用例中变慢了。


Helenr
浏览 109回答 1
1回答

宝慕林4294392

这是一种潜在的方法,使用, 在和merge上自我加入。然后使用, 过滤掉两边用户相等的地方,最后用于输出。dateactionquerypivot_tabledf_corr = (df.merge(df, on=['date', 'action'])           .query('user_x != user_y')           .pivot_table(index='user_x', columns='user_y', aggfunc='size'))[出去]user_y  user_1  user_2  user_3user_x                        user_1     NaN     2.0     NaNuser_2     2.0     NaN     1.0user_3     NaN     1.0     NaN如果仅需要显示相关矩阵的下三角形,则可以NaN使用以下方法输出上半部分:mask = np.triu_indices_from(df_corr)df_corr.values[mask] = np.nan[出去]user_y  user_1  user_2  user_3user_x                        user_1     NaN     NaN     NaNuser_2     2.0     NaN     NaNuser_3     NaN     1.0     NaN
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python