多组下的成对矩阵操作与变量构建
如何把「组-个人」分数数据转成「个人-个人对」的平方误差和数据?
嘿,我来帮你搞定这个数据转换的需求!先理清楚咱们的输入和目标:
输入数据(组-个人级别)
咱们手头的初始数据是这样的:
| group_id | person_id | score |
|---|---|---|
| 1 | 1 | 3 |
| 1 | 2 | 1 |
| 1 | 3 | 5 |
| 2 | 1 | 3 |
| 2 | 2 | 3 |
| 2 | 3 | 6 |
目标数据(个人-个人对级别)
我们要生成每一对个人的sumsquarederror——也就是两人在所有组里的分数差值平方之和,最终输出是这样:
| person_id1 | person_id2 | sumsquarederror |
|---|---|---|
| 1 | 2 | 4 |
| 1 | 3 | 13 |
| 2 | 3 | 25 |
简单说,这个指标的计算公式就是:对每一对个人i和j,把每个组里他俩分数差的平方加起来,公式写出来就是:
$$\text{sumsquarederror}(i,j) = \sum_{g} (score_{i,g} - score_{j,g})^2$$
两种实用的实现方法
我给你准备了两种常用的实现方式,你可以根据自己用的工具来选:
方法1:用SQL搞定
如果你是在数据库里处理数据,用自连接+分组求和就可以轻松实现:
SELECT a.person_id AS person_id1, b.person_id AS person_id2, SUM(POWER(a.score - b.score, 2)) AS sumsquarederror FROM your_table a JOIN your_table b ON a.group_id = b.group_id AND a.person_id < b.person_id GROUP BY a.person_id, b.person_id ORDER BY a.person_id, b.person_id;
这里划几个重点:
- 用
a.person_id < b.person_id是为了避免重复计算(比如(1,2)和(2,1)算同一对),还能排除自己和自己配对的情况 POWER函数是用来算平方的,不同数据库可能写法不一样,比如MySQL用POW,或者你直接写(a.score - b.score)*(a.score - b.score)也完全没问题- 最后按两个人的ID分组求和,就能得到每一对的平方误差和啦
方法2:用Python Pandas处理
如果是用Python做数据分析,用Pandas的透视表+循环遍历就能搞定:
import pandas as pd # 先把初始数据装进DataFrame data = pd.DataFrame({ 'group_id': [1,1,1,2,2,2], 'person_id': [1,2,3,1,2,3], 'score': [3,1,5,3,3,6] }) # 转成透视表,行是组,列是个人,值是分数,这样方便后续计算 pivot_df = data.pivot(index='group_id', columns='person_id', values='score') # 初始化一个空列表存结果 result = [] # 拿到所有个人ID的列表 persons = pivot_df.columns.tolist() # 遍历所有不重复的个人对 for i in range(len(persons)): for j in range(i+1, len(persons)): p1 = persons[i] p2 = persons[j] # 计算每个组的差值平方,然后求和 sse = ((pivot_df[p1] - pivot_df[p2])**2).sum() result.append({'person_id1': p1, 'person_id2': p2, 'sumsquarederror': sse}) # 把结果转成DataFrame,看看输出 result_df = pd.DataFrame(result) print(result_df)
运行这段代码后,输出的结果就和咱们的目标格式完全一致啦!
顺便验证一下计算过程
怕你担心结果不对,咱们拿几个例子核对一下:
- 个人1和个人2:组1里(3-1)²=4,组2里(3-3)²=0,加起来就是4,和目标一致
- 个人2和个人3:组1里(1-5)²=16,组2里(3-6)²=9,总和25,也和目标对上了
这样你就能放心用啦!
内容的提问来源于stack exchange,提问作者km5041
相关产品推荐
相关产品推荐

