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

Pandas中如何同时拆分不等长的phones与emails列?

多列不等条目拆分多行解决方案

需要将DataFrame中的phones和emails两列拆分成多行,核心要求是:两列条目数不一致时,以条目数多的列为基准生成行,条目数少的列按序填充后剩余行留空。单独拆分一列可实现,但同时拆分时出现报错。

示例数据

many columnsphonesemails
row 1A,B,CA,B
row 2D,E,F

预期结果

many columnsphonesemails
row 1AA
row 1BB
row 1C
row 2D
row 2E
row 2F

尝试代码及报错

# 将单元格内容转为列表而非字符串
df0['phones'] = df0['phones'].str.split(";", expand=False)
df0['emails'] = df0['emails'].str.split(",", expand=False)
df0 = df0.apply(pd.Series.explode) # 无法运行

运行后报错:

ValueError: cannot reindex on an axis with duplicate labels

解决方案

问题出在apply(pd.Series.explode)会同时对两列执行拆分,但两列长度不一致时会导致索引冲突。正确做法是先计算每行需要扩展的行数(取两列列表的最大长度),再逐行扩展并填充对应值:

import pandas as pd

# 构造示例数据
data = {
    'many columns': ['row 1', 'row 2'],
    'phones': ['A,B,C', ''],
    'emails': ['A,B', 'D,E,F']
}
df0 = pd.DataFrame(data)

# 处理空值,将字符串分割为列表(空值转为空列表)
df0['phones'] = df0['phones'].apply(lambda x: x.split(',') if x.strip() else [])
df0['emails'] = df0['emails'].apply(lambda x: x.split(',') if x.strip() else [])

# 计算每行需要扩展的行数(取两列列表的最大长度)
df0['expand_len'] = df0.apply(lambda row: max(len(row['phones']), len(row['emails'])), axis=1)

# 定义函数:将单行扩展为指定长度的多行,并填充对应列的值
def expand_row(row):
    # 复制其他列到对应行数
    base_df = pd.DataFrame({
        col: [row[col]] * row['expand_len'] 
        for col in df0.columns if col not in ['phones', 'emails']
    })
    # 填充phones列,不足的行补空字符串
    base_df['phones'] = row['phones'] + [''] * (row['expand_len'] - len(row['phones']))
    # 填充emails列,不足的行补空字符串
    base_df['emails'] = row['emails'] + [''] * (row['expand_len'] - len(row['emails']))
    return base_df

# 合并所有扩展后的行,重置索引
result_df = pd.concat([expand_row(row) for _, row in df0.iterrows()], ignore_index=True)
# 删除临时的扩展长度列
result_df = result_df.drop('expand_len', axis=1)

print(result_df)

运行后即可得到符合预期的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 14:15:32