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

Pandas DataFrame含NaN时拆分多字符串列为多行的问题

解决DataFrame多列按分隔符拆分为多行的问题

问题场景

现有如下示例DataFrame:

track_idtrack_datestatusstatus_info
track_12021-01-01approvedNone
track_22021-01-02Noneaccredited
track_32021-01-03approvedaccredited
track_42021-01-04approvedapproved
track_52021-01-05approved|approvedaccredited|cancelled
track_62021-01-06Noneaccredited|cancelled

需要将status和status_info两列按|拆分为多行,得到如下预期结果:

track_idtrack_datestatusstatus_info
track_12021-01-01approvedNone
track_22021-01-02Noneaccredited
track_32021-01-03approvedaccredited
track_42021-01-04approvedapproved
track_52021-01-05approvedaccredited
track_52021-01-05approvedcancelled
track_62021-01-06Noneaccredited
track_62021-01-06Nonecancelled

原代码错误分析

你尝试的代码报错ValueError: cannot reindex from a duplicate axis,核心原因是拆分后两列的元素数量不一致:

  • 比如track_6的status拆分为1个元素,status_info拆分为2个元素,导致new_status和new_status_info的索引匹配失败,concat时无法对齐行数据。

正确实现方法

方法1:对齐列表长度后使用explode

先将两列拆分为列表,对齐每行两个列表的长度(短列表重复元素补全),再通过explode拆分多行:

import pandas as pd

# 构造示例DataFrame
data = {
    'track_id': ['track_1', 'track_2', 'track_3', 'track_4', 'track_5', 'track_6'],
    'track_date': ['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04', '2021-01-05', '2021-01-06'],
    'status': ['approved', 'None', 'approved', 'approved', 'approved|approved', 'None'],
    'status_info': ['None', 'accredited', 'accredited', 'approved', 'accredited|cancelled', 'accredited|cancelled']
}
df = pd.DataFrame(data)

# 1. 将列拆分为列表
df['status'] = df['status'].str.split('|')
df['status_info'] = df['status_info'].str.split('|')

# 2. 对齐每行两个列表的长度
def align_list_length(row):
    status_len = len(row['status'])
    info_len = len(row['status_info'])
    if status_len < info_len:
        row['status'] = row['status'] * info_len
    elif info_len < status_len:
        row['status_info'] = row['status_info'] * status_len
    return row

df = df.apply(align_list_length, axis=1)

# 3. 拆分多行并重置索引
df = df.explode(['status', 'status_info'], ignore_index=True)

# 可选:将字符串'None'转为实际的None值
df = df.replace('None', None)

print(df)

方法2:使用stack+merge(适合复杂场景)

通过保留原始索引,拆分后按索引合并:

import pandas as pd

df = pd.DataFrame(data)

# 拆分status并保留原始索引
status_split = df['status'].str.split('|', expand=True).stack().reset_index(level=1, drop=True).rename('status')
# 拆分status_info并保留原始索引
info_split = df['status_info'].str.split('|', expand=True).stack().reset_index(level=1, drop=True).rename('status_info')

# 按原始索引合并,自动补全缺失值
split_df = pd.merge(status_split, info_split, left_index=True, right_index=True, how='outer')

# 合并回原数据
result = df.drop(['status', 'status_info'], axis=1).join(split_df).reset_index(drop=True)
result = result.replace('None', None)

print(result)

两种方法都能得到预期的输出结果,方法1更直观易读,适合大多数场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:25:01