
本文介绍使用 pandas 的 `str.split()` 和 `explode()` 方法,高效地将 dataframe 中多个字符串型列表列(如 "ms" 和 "ds")按元素一一配对展开为独立行,自动处理长度不等时的缺失值填充(如 `none`)。
在数据分析中,常遇到将含逗号分隔字符串的多列同步“爆炸”(explode)为多行的需求——尤其当各列代表一一对应的属性(如价格与对应天数),但原始数据以字符串形式存储且长度可能不一致。直接使用 zip_longest 易出错,关键在于:先解析字符串为列表,再构造配对元组,最后统一 explode。
以下是推荐的清晰、可复现的解决方案:
import pandas as pd
from itertools import zip_longest
# 示例数据
df = pd.DataFrame({
'ID': [654, 131, 598],
'MS': ['1500,10000,20000,30000', '1500,10000,20000', '1500,10000,20000,30000'],
'DS': ['60,365,730', '60,365,730', '60,365,730']
})
# 步骤 1:将 MS 和 DS 列拆分为列表(注意:split 后元素仍为字符串)
df[['MS', 'DS']] = df[['MS', 'DS']].apply(lambda x: x.str.split(','), axis=1)
# 步骤 2:对每行,用 zip_longest 配对两个列表(短者补 None)
df['paired'] = df.apply(lambda row: list(zip_longest(row['MS'], row['DS'])), axis=1)
# 步骤 3:explode 展开 paired 列,得到每对 (MS_val, DS_val)
df_exploded = df.explode('paired')
# 步骤 4:将元组解包回 MS 和 DS 列
df_exploded[['MS', 'DS']] = pd.DataFrame(df_exploded['paired'].tolist(), index=df_exploded.index)
# 可选:清理中间列,并重置索引
df_final = df_exploded.drop(columns=['paired']).reset_index(drop=True)✅ 输出结果与预期一致:每行 ID 对应一组 MS/DS 值,MS 较长时 DS 自动补 None(注意:fillvalue=None 是 zip_longest 默认行为;若需 'Nan' 字符串,请显式写 fillvalue='Nan')。
⚠️ 注意事项:
立即学习“Python免费学习笔记(深入)”;
- str.split(',') 返回的是字符串列表(如 ['1500', '10000']),后续数值计算前建议用 .astype(float) 或 .astype(int) 转换;
- explode() 要求目标列为 list/tuple 类型,不可直接对字符串列调用;
- 若多列长度差异大且需严格对齐(如笛卡尔积),应改用 merge 或 pd.concat + repeat,而非 zip_longest;
- 性能敏感场景下,避免 apply(..., axis=1),可考虑 pd.Series.explode 配合 map 分步处理。
该方法简洁、健壮,是处理多列同步展开任务的标准实践。










