You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从含字符串的pandas DataFrame按正确顺序创建数据透视表

问题描述

现有如下结构的DataFrame:
示例数据截图

可直接复制使用的表格格式示例数据:

SourceName     SourceType   Edge       TargetName      TargetType
cardiac myosin     DISEASE  induce     myocarditis     DISEASE
cardiac myosin     DISEASE  induce     heart disease   DISEASE
nitric             CHEMICAL inhibit    chrysin         CHEMICAL
peptide magainin   CHEMICAL exhibited  tumor           DISEASE

可直接复制使用的字典格式示例数据:

{'id': [1, 2, 3, 4],
 'SourceName': ['cardiac myosin',
  'cardiac myosin',
  'nitric',
  'peptide magainin'],
 'SourceType': ['DISEASE', 'DISEASE', 'CHEMICAL', 'CHEMICAL'],
 'Edge': ['induce', 'induce', 'inhibit', 'exhibited'],
 'TargetName': ['myocarditis',
  'heart disease',
  'chrysin',
  'tumor'],
 'TargetType': ['DISEASE', 'DISEASE', 'CHEMICAL', 'DISEASE']}

使用如下代码做数据透视时,出现类型匹配错误:例如peptide magainin本身属于CHEMICAL类型,却被错误归类到DISEASE分类下,输出不符合预期。

df1 = df.groupby(["id","SourceType","TargetType"])['SourceName', 'Edge', 'TargetName'].aggregate(lambda x: x).unstack().reset_index()
df1.columns=df1.columns.tolist()

错误输出样例截图

期望得到的正确输出如下:
期望输出截图


问题原因

原代码同时将SourceType和TargetType作为分组键,unstack操作会生成两种类型的全量组合索引,没有和当前分组匹配的字段会被填充为空,同时SourceName和SourceType的绑定关系没有被固定,最终出现值错位、类型匹配错误的问题。


解决方案

不要同时把两个类型字段作为分组键做展开,先固定源实体属性(SourceName、SourceType)和id的绑定关系,再按目标类型做透视即可,参考代码如下:

import pandas as pd

# 构造示例数据(可跳过,直接用你自己的df)
df = pd.DataFrame({'id': [1, 2, 3, 4],
 'SourceName': ['cardiac myosin',
  'cardiac myosin',
  'nitric',
  'peptide magainin'],
 'SourceType': ['DISEASE', 'DISEASE', 'CHEMICAL', 'CHEMICAL'],
 'Edge': ['induce', 'induce', 'inhibit', 'exhibited'],
 'TargetName': ['myocarditis',
  'heart disease',
  'chrysin',
  'tumor'],
 'TargetType': ['DISEASE', 'DISEASE', 'CHEMICAL', 'DISEASE']})

# 新增辅助序号列,避免同类型多个目标值时出现行冲突
df["row_tag"] = df.groupby(["id", "TargetType"]).cumcount()

# 透视数据
df1 = df.pivot_table(
    index=["id", "SourceName", "SourceType", "row_tag"],
    columns="TargetType",
    values=["Edge", "TargetName"],
    aggfunc="first"
).reset_index()

# 整理多层列名
df1.columns = [f"{col[1]}_{col[0]}" if col[1] else col[0] for col in df1.columns]
# 删除辅助列
df1 = df1.drop("row_tag", axis=1)

运行后输出结果和预期结构一致,不会出现类型匹配错误的问题,若同一个源实体对应多个同类型目标,代码也会自动拆分为多行展示,不会丢失数据。


内容的提问来源于stack exchange,提问作者Mathew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 23:36:27