【发布时间】:2019-04-26 02:57:44
【问题描述】:
我有一个包含 3 列的数据框。
UserId | ItemId | Rating
(其中 Rating 是用户对项目的评分。它是 np.float16。2 个 Id 是 np.int32)
您如何最好地使用 python pandas 计算项目之间的相关性?
我的做法是先旋转表格(宽格式),然后应用 pd.corr
df = df.pivot(index='UserId', columns='ItemId', values='Rating')
df.corr()
它适用于小型数据集,但不适用于大型数据集。
第一步创建了一个大矩阵数据集,其中大部分是缺失值。它非常占用内存,我无法使用更大的数据帧运行它。
难道没有更简单的方法可以直接在长数据集上计算相关性,而无需进行透视?
(我查看了 pd.groupBy,但这似乎只拆分了数据框,而不是我要查找的内容。)
编辑:过度简化的数据和工作中枢代码
import pandas as pd
import numpy as np
d = {'UserId': [1,2,3, 1,2,3, 1,2,3],
'ItemId': [1,1,1, 2,2,2, 3,3,3],
'Rating': [1.1,4.5,7.1, 5.5,3.1,5.5, 1.1,np.nan,2.2]}
df = pd.DataFrame(data=d)
df = df.astype(dtype={'UserId': np.int32, 'ItemId': np.int32, 'Rating': np.float32})
print(df.info())
pivot = df.pivot(index='UserId', columns='ItemId', values='Rating')
print('')
print(pivot)
corr = pivot.corr()
print('')
print(corr)
EDIT2:大型随机数据生成器
def randDf(size = 100):
## MAKE RANDOM DATAFRAME, df =======================
import numpy as np
import pandas as pd
import random
import math
dict_for_df = {}
for i in ('UserId','ItemId','Rating'):
dict_for_df[i] = {}
for j in range(size):
if i=='Rating': val = round( random.random()*5, 1)
else: val = round( random.random() * math.sqrt(size/2) )
dict_for_df[i][j] = val # store in a dict
# print(dict_for_df)
df = pd.DataFrame(dict_for_df) # after the loop convert the dict to a dataframe
# print(df.head())
df = df.astype(dtype={'UserId': np.int32, 'ItemId': np.int32, 'Rating': np.float32})
# df = df.astype(dtype={'UserId': np.int64, 'ItemId': np.int64, 'Rating': np.float64})
## remove doubles -----
df.drop_duplicates(subset=['UserId','ItemId'], keep='first', inplace=True)
## show -----
print(df.info())
print(df.head())
return df
# =======================
df = randDf()
【问题讨论】:
-
您能否提供一些示例数据和预期输出,并更详细地解释您所说的“项目之间的相关性”是什么意思?您是否有兴趣寻找其中的情况,例如,用户 A 喜欢第 1 项和第 2 项(特定用户对两种不同产品的评分相关)?另外,您总共有多少用户、项目和评分?每个用户是否对每个项目只评分过一次?
-
@PeterLeimbigler 问题中添加的小示例(但不考虑数据类型)。我的数字是约 5 万件商品和约 20 万用户约 2000 万的评分。不,不是“完全”一次:最多一次。 (因此一次或永远)
标签: python pandas dataframe correlation