如何将Pandas生成的宝可梦属性共现矩阵转为对称矩阵?
解决宝可梦属性共现矩阵的对称化问题
核心思路
你已经通过np.sort对type1和type2列排序,使得所有属性对都以[A, B](A ≤ B)的形式存储,因此pd.crosstab生成的矩阵仅右上三角有值。要生成对称矩阵,关键是避免对角线重复计算,同时将右上三角的值镜像到左下三角。
方法一:矩阵运算高效实现(推荐大数据集)
利用矩阵转置与对角线修正,一步生成对称矩阵:
import pandas as pd import numpy as np # 假设已完成type1和type2的排序,生成原始共现矩阵 df[['type1', 'type2']] = np.sort(df[['type1', 'type2']], axis=1) co_occur = pd.crosstab(df['type1'], df['type2']) # 生成对称矩阵 co_occur_t = co_occur.T # 转置矩阵 # 提取原始矩阵的对角线值(避免重复计算) diag_matrix = pd.DataFrame(np.diag(np.diag(co_occur.values)), index=co_occur.index, columns=co_occur.columns) # 原始矩阵 + 转置矩阵 - 对角线矩阵(抵消对角线的重复相加) sym_co_occur = co_occur + co_occur_t - diag_matrix
逻辑说明:
- 原始矩阵的对角线是单属性宝可梦的数量(
type1与type2相同的情况),转置矩阵的对角线与原始完全一致,相加会导致对角线数值翻倍,因此需要减去一次对角线矩阵恢复原值。 - 非对角线位置:原始矩阵右上三角有值、左下三角为0,转置矩阵则相反,相加后正好填满左下三角,实现完全对称。
方法二:遍历填充(逻辑直观,适合小数据集)
直接将右上三角的值复制到左下三角对应位置:
sym_co_occur = co_occur.copy() # 遍历左下三角的所有位置 for row_idx in range(sym_co_occur.shape[0]): for col_idx in range(row_idx): # 将右上三角的值复制到左下三角 sym_co_occur.iloc[row_idx, col_idx] = sym_co_occur.iloc[col_idx, row_idx]
验证对称效果
执行以下代码确认矩阵是否对称:
print(sym_co_occur.equals(sym_co_occur.T))
内容的提问来源于stack exchange,提问作者Matheus
相关产品推荐
相关产品推荐

