Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 熊猫-根据条件统计相关事件_Python_Python 3.x_Pandas_Numpy_Data Science - Fatal编程技术网

Python 熊猫-根据条件统计相关事件

Python 熊猫-根据条件统计相关事件,python,python-3.x,pandas,numpy,data-science,Python,Python 3.x,Pandas,Numpy,Data Science,我想创建DataFrame,可能是稀疏的,用于测量用户之间的相关性。这里,我对user_1和user_2之间相关性的定义是它们在同一天执行相同操作的次数 我会尝试用一个例子来更好地解释我自己。假设我有以下数据帧: 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

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

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

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
,因为他们都在
07
天执行动作
a
,在
08
天执行动作
c
user_2
user_3
之间的相关性是
1
,因为他们在
05
天执行了
b
操作。其余的都是
NaN
。它们输出的数据帧如下所示:

        user_1  user_2  user_3
user_1  NaN     NaN     NaN
user_2  2.0     NaN     NaN
user_3  NaN     1.0     NaN
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

我创建此数据帧的低效方法如下:

        user_1  user_2  user_3
user_1  NaN     NaN     NaN
user_2  2.0     NaN     NaN
user_3  NaN     1.0     NaN
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

这种方法的问题是在我的用例中速度太慢。

这里有一种潜在的方法,使用,在
日期和
操作时自动加入。然后使用,过滤出用户在两侧相等的位置,最后用于输出

df_corr = (df.merge(df, on=['date', 'action'])
           .query('user_x != user_y')
           .pivot_table(index='user_x', columns='user_y', aggfunc='size'))
[外]


如果仅显示相关矩阵的下三角是一项要求,则可以使用以下方法
NaN
显示上部分:

mask = np.triu_indices_from(df_corr)
df_corr.values[mask] = np.nan
[外]


您的数据框架有多大?大约有20万个不同的用户,数据框架中有几十亿行。非常感谢,我非常喜欢您的方法。我不需要考虑较低的三角形(实际上是对角线的下方,所以我跳过了查询)。我面临一个
ValueError:Unstacked DataFrame太大,导致int32溢出
错误,原因是
pivot\u表
。我想知道我想要的是不是只能用RAM来实现。我的秘密希望是熊猫会用稀疏表示来管理内存,但我可能太乐观了。是的,我在发布这篇文章后才看到了你数据的大小。。。它相当大!我完全同意你的看法,我可能会尝试用图形表示法。不过,对于大小合理的数据(对于虚拟数据集上的性能提高10倍的记录),您的答案还是非常准确的