如何用Python Pandas生成指定规则的类别共现表?
解决方案:生成指定规则的类别共现表
首先,我们明确核心需求:只关注那些出现过Category1的ID,统计这些ID在各类别中的出现/共现情况,最终生成行和列均包含所有类别的矩阵。下面分步骤实现:
步骤1:筛选目标ID及其对应记录
先提取所有包含Category1的ID,再筛选这些ID的所有相关记录:
import pandas as pd # 原数据集 df = pd.DataFrame([["1001","Category1"],["1001","Category1"],["1001","Category2"],["1002","Category1"],["1002","Category3"],["1001","Category3"],["1002", "Category2"],["1001", "Category3"],["1001","Category4"]], columns=['Id','Cat']) # 获取所有出现过Category1的ID target_ids = df[df['Cat'] == 'Category1']['Id'].unique() # 筛选这些ID的所有记录 filtered_df = df[df['Id'].isin(target_ids)]
步骤2:准备基础统计数据
我们需要两类数据:
- 每个类别在目标ID中的总出现次数(用于填充矩阵对角线)
- 每个ID对应的唯一类别集合(用于统计不同类别之间的共现ID数量)
# 统计每个类别的总出现次数 cat_total_counts = filtered_df['Cat'].value_counts().sort_index() # 生成每个ID对应的唯一类别集合 id_unique_cats = filtered_df.groupby('Id')['Cat'].unique().reset_index()
步骤3:构建共现矩阵
初始化矩阵后,分别填充对角线(总出现次数)和非对角线(共现ID数量):
# 获取所有唯一类别,作为矩阵的行和列索引 all_cats = cat_total_counts.index # 创建空的共现矩阵 cooccurrence_matrix = pd.DataFrame(index=all_cats, columns=all_cats, dtype=int) # 填充对角线:类别自身的总出现次数 for cat in all_cats: cooccurrence_matrix.loc[cat, cat] = cat_total_counts[cat] # 填充非对角线:同时拥有行类别和列类别的ID数量 for cat_x in all_cats: for cat_y in all_cats: if cat_x != cat_y: # 统计同时包含cat_x和cat_y的ID数量 count = id_unique_cats[id_unique_cats['Cat'].apply(lambda x: cat_x in x and cat_y in x)].shape[0] cooccurrence_matrix.loc[cat_x, cat_y] = count
最终结果
运行上述代码后,得到的矩阵如下:
Category1 Category2 Category3 Category4 Category1 3 2 2 1 Category2 2 2 2 1 Category3 2 2 3 1 Category4 1 1 1 1
这个结果和你给出的示例表几乎一致,唯一差异是Category1行的Category1值为3(原数据中该类别总出现次数确实是3次),推测是你示例表的笔误。
补充说明
如果你的需求是非对角线单元格也用总共现次数(而非ID数量),可以改用矩阵乘法的方式:
# 构建ID-类别的频次表 id_cat_counts = filtered_df.pivot_table(index='Id', columns='Cat', values='Cat', aggfunc='count', fill_value=0) # 计算共现矩阵:每对类别的总共现次数 cooccurrence_matrix = id_cat_counts.T.dot(id_cat_counts)
这种方式会统计所有目标ID中,行类别和列类别出现次数的乘积之和,适合需要更细致频次统计的场景。
内容的提问来源于stack exchange,提问作者Taylrl
相关产品推荐
相关产品推荐

