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

如何将Pandas DataFrame中含回车的单元格拆分为多行?

解决方案

首先,你遇到的第一个错误是代码里的低级失误:计算拆分长度时用了split(','),但实际分隔符是\r,这导致lens的计算完全错误,进而引发数组长度不匹配的报错。

第二个错误是因为实际数据中Name和Age的组合存在重复,设置为索引后出现非唯一多级索引,apply+explode无法处理这种情况。

下面针对你的需求提供两种可行方案:

方案一:过滤无效值后批量拆分展开

这个方案会先去掉拆分后产生的空字符串、纯空格内容,再将每个列的有效元素展开为新行,其他列重复原行数据。如果同一行多个列拆分后的有效元素长度不一致,会生成所有元素的组合(笛卡尔积)。

import pandas as pd

# 定义拆分并清理无效值的函数
def split_clean(s):
    # 按\r拆分,去除空字符串和纯空格内容
    return [item.strip() for item in s.split('\r') if item.strip()]

# 复制原DataFrame避免修改原始数据
df_clean = df.copy()

# 对需要拆分的列应用拆分清理函数
split_cols = ['Roll No per Class', 'Highest Scores']
for col in split_cols:
    df_clean[col] = df_clean[col].apply(split_clean)

# 依次对每个拆分列执行explode
for col in split_cols:
    df_clean = df_clean.explode(col, ignore_index=True)

print(df_clean)

运行示例数据后会得到:

Roll No per Class  Name  Age Highest Scores
0                 8   tom   10             55
1                 8   tom   10             62
2                 8   tom   10             75
3                18  nick   15             77
4                18  nick   15             25
5                18  nick   15             85
6                 9  nick   15             77
7                 9  nick   15             25
8                 9  nick   15             85
9                17  juli   14             55
10               19  juli   14             55
11               18  juli   14             55
12               17  juli   14             75
13               19  juli   14             75
14               18  juli   14             75
15               17  juli   14             85
16               19  juli   14             85
17               18  juli   14             85

方案二:按位置对齐拆分元素(一一对应)

如果你的数据中,每行的Roll No per Class和Highest Scores拆分后的元素是一一对应的(比如第一个学号对应第一个分数),可以用这个方案,长度不一致时会用NaN补全:

import pandas as pd
import numpy as np

def split_clean(s):
    return [item.strip() for item in s.split('\r') if item.strip()]

# 对需要拆分的列应用函数
df['Roll Clean'] = df['Roll No per Class'].apply(split_clean)
df['Scores Clean'] = df['Highest Scores'].apply(split_clean)

# 对每行的拆分结果按位置对齐,生成新行
result = df.explode(['Roll Clean', 'Scores Clean'], ignore_index=True)

# 替换空值并还原原列名
result = result.rename(columns={'Roll Clean': 'Roll No per Class', 'Scores Clean': 'Highest Scores'})
result = result.drop(columns=['Roll No per Class', 'Highest Scores'], axis=1).rename(columns={'Roll Clean': 'Roll No per Class', 'Scores Clean': 'Highest Scores'})

# 处理长度不一致的情况,补全缺失值
max_len = result.groupby(level=0).size().max()
result = result.reindex(pd.MultiIndex.from_product([result.index.unique(), range(max_len)], names=['orig_idx', 'pos']))
result['Name'] = result['Name'].ffill()
result['Age'] = result['Age'].ffill()
result = result.dropna(subset=['Roll No per Class', 'Highest Scores'], how='all').reset_index(drop=True)

print(result)

关键注意事项

  • 优先清理拆分后的无效值(空字符串、纯空格),这是解决长度不匹配的核心前提。
  • 如果数据量很大(15000行),方案一的效率更高,因为explode是Pandas内置的高效操作。
  • 若实际数据中每行的拆分元素是一一对应的,务必使用方案二,避免生成不必要的冗余数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 22:01:03