python - 从一列 pandas 创建一个 NxN 矩阵
问题描述
我有数据框,每一行都有一个列表值。
id list_of_value
0 ['a','b','c']
1 ['d','b','c']
2 ['a','b','c']
3 ['a','b','c']
我必须用一行和所有其他行计算分数
例如:
Step 1: Take value of id 0: ['a','b','c'],
Step 2: find the intersection between id 0 and id 1 ,
resultant = ['b','c']
Step 3: Score Calculation => resultant.size / id.size
在 id 0 和 id 1,2,3 之间重复步骤 2,3,对所有 id 类似。
并创建一个 N x N 数据框;像这样:
- 0 1 2 3
0 1 0.6 1 1
1 1 1 1 1
2 1 1 1 1
3 1 1 1 1
现在我的代码只有一个 for 循环:
def scoreCalc(x,queryTData):
#mathematical calculation
commonTData = np.intersect1d(np.array(x),queryTData)
return commonTData.size/queryTData.size
ids = list(df['feed_id'])
dfSim = pd.DataFrame()
for indexQFID in range(len(ids)):
queryTData = np.array(df.loc[df['id'] == ids[indexQFID]]['list_of_value'].values.tolist())
dfSim[segmentDfFeedIds[indexQFID]] = segmentDf['list_of_value'].apply(scoreCalc,args=(queryTData,))
有一个更好的方法吗?我可以只写一个应用函数而不是进行for循环迭代吗?我可以让它更快吗?
解决方案
如果您的数据不是太大,您可以使用get_dummies
对值进行编码并进行矩阵乘法:
s = pd.get_dummies(df.list_of_value.explode()).sum(level=0)
s.dot(s.T).div(s.sum(1))
输出:
0 1 2 3
0 1.000000 0.666667 1.000000 1.000000
1 0.666667 1.000000 0.666667 0.666667
2 1.000000 0.666667 1.000000 1.000000
3 1.000000 0.666667 1.000000 1.000000
更新:这是代码的简短说明。主要思想是将给定的列表转换为单热编码:
a b c d
0 1 1 1 0
1 0 1 1 1
2 1 1 1 0
3 1 1 1 0
一旦我们有了它,两行交集的大小,比如说,0
和1
只是它们的点积,因为一个字符属于两行当且仅当它在两行1
中都由 表示。
考虑到这一点,首先使用
df.list_of_value.explode()
将每个单元格变成一个系列并连接所有这些系列。输出:
0 a
0 b
0 c
1 d
1 b
1 c
2 a
2 b
2 c
3 a
3 b
3 c
Name: list_of_value, dtype: object
现在,我们使用pd.get_dummies
该系列将其转换为单热编码数据帧:
a b c d
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
1 0 0 0 1
1 0 1 0 0
1 0 0 1 0
2 1 0 0 0
2 0 1 0 0
2 0 0 1 0
3 1 0 0 0
3 0 1 0 0
3 0 0 1 0
如您所见,每个值都有自己的行。由于我们想将属于同一原始行的那些合并为一行,我们可以通过原始索引将它们相加。因此
s = pd.get_dummies(df.list_of_value.explode()).sum(level=0)
给出我们想要的二进制编码数据帧。下一行
s.dot(s.T).div(s.sum(1))
就像您的逻辑一样:s.dot(s.T)
按行计算点积,然后.div(s.sum(1))
按行除计数。
推荐阅读
- git - 在 CentOS 服务器上安装作曲家时,无法使用 Git 读取私有仓库
- angular - 如何判断组件是否用作 MatFormField
- node.js - Mongodb,解析一个变量作为查询条件
- unity3d - Agora Unity SDK,我无法静音取消静音用户音频/视频
- java - Spring Boot JdbcTemplate - 禁用语句缓存?
- python - 当我的机器人或其他机器人在命令中使用时,如何让我的机器人说话?(discord.py)
- python-3.x - 如何让 AWS cognito 刷新令牌到期?
- python - 打印 eval 无法从字符串打印变量
- r - 使用正则表达式选择性地提取 R 中的子字符串
- html - 过滤字段而不在 Directus 中搜索 HTML 标记