
本文介绍如何利用 pandas 的 explode、merge 和 concat 方法,根据 object 分组将词表列表展开为多行,并与原始数据合并,同时正确标记原始记录(included=1)和新增记录(included=0)。
本文介绍如何利用 pandas 的 explode、merge 和 concat 方法,根据 object 分组将词表列表展开为多行,并与原始数据合并,同时正确标记原始记录(included=1)和新增记录(included=0)。
在实际数据处理中,常需将嵌套的词表(如每个 object 对应的一组特征词)展开为长格式,并与主表按分组逻辑对齐。本例中,df 是带标注的原始样本数据,legend 是每个 object 对应的完整词库;目标是:对每个 (object, personID) 组合,完整补全该 object 对应的所有词,其中原始出现的词保留 included=1,新增补全的词统一设为 included=0。
关键在于三步协同:
- 展开词表:使用 .explode('word_lists') 将 legend 中每个 object 对应的词列表拆分为独立行;
- 对齐分组维度:通过 .merge(df[['object', 'personID']].drop_duplicates()) 将展开后的词表与所有 (object, personID) 组合笛卡尔式关联(即每个 object 的全部词,都分配给该 object 下的每个 personID);
- 合并并标记:用 pd.concat() 合并原始 df 与补全数据,并用 .assign(included=0) 统一设置新增行的标签。
以下是完整可执行代码:
import pandas as pd
# 构造示例数据
df = pd.DataFrame({
'object': ['dog', 'dog', 'cat', 'mouse'],
'personID': [1, 1, 2, 3],
'word': ['paw', 'head', 'whisker', 'tail'],
'included': [1, 1, 1, 1]
})
legend = pd.DataFrame({
'object': ['dog', 'cat', 'mouse'],
'word_lists': [
['paw', 'head', 'nose', 'body'],
['whisker', 'ears', 'eyes'],
['ears', 'tail', 'fur']
]
})
# 核心处理流程
expanded_legend = (
legend
.explode('word_lists')
.rename(columns={'word_lists': 'word'})
.merge(df[['object', 'personID']].drop_duplicates(), on='object')
.assign(included=0)
)
result_df = (
pd.concat([df, expanded_legend], ignore_index=True)
.sort_values(['personID', 'object', 'word'])
.reset_index(drop=True)
)
print(result_df)✅ 输出说明:结果中每组 (object, personID) 均包含该 object 在 legend 中定义的全部词;原始存在的 (object, personID, word) 组合保留 included=1,其余组合均为 included=0。
⚠️ 注意事项:
- merge(..., on='object') 依赖 legend 与 df 的 object 列值严格一致(大小写、空格等),建议提前清洗;
- 若 df 中存在 object 不在 legend 中(或反之),需考虑使用 how='left' 或 how='right' 控制合并行为;
- sort_values() 中加入 'word' 可提升结果可读性(如示例所示),避免因索引残留导致顺序混乱;
- 若数据量极大,.explode() 后可能产生大量中间行,注意内存使用。
该方法简洁、向量化、无需循环,是 pandas 处理“一对多补全”类任务的标准实践。

















