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

如何解决DataFrame创建大量列时的PerformanceWarning碎片化问题

解决DataFrame碎片化警告的可行方案

原代码循环给DataFrame添加972列,每次赋值都会触发一次列插入操作,反复调整内存布局导致碎片化,除了忽略警告,还有以下几种更优的解决方式:

1. 批量生成拆分列后一次性拼接(官方推荐方案)

不要逐列修改原DataFrame,先把所有拆分后的列生成独立的Series,再用pd.concat一次性拼接,同时明确指定数据类型避免默认的object类型:

首先整理好所有切片的起止位置(按你的规则补全剩余切片即可):

# 示例:按你的切片规则整理的起止位置列表
slice_ranges = [
    (0, 2), (2, 4), (4, 13), (13, 22), (22, 31), (31, 40),
    # ... 补充剩下的966个切片范围
    (4994, None)  # 最后一列的切片
]

修改后的解析函数:

import pandas as pd

def parse_long_string(df):
    split_columns = []
    for idx, (start, end) in enumerate(slice_ranges, 1):
        col_name = f"a{idx:03d}"
        # 提取切片并指定为string类型,比默认object更高效
        col_data = df['long_string'].str.slice(start, end).astype('string')
        split_columns.append(col_data.rename(col_name))
    
    # 一次性拼接原DataFrame和所有拆分列
    return pd.concat([df] + split_columns, axis=1)

这种方式只做一次内存合并操作,彻底避免多次插入列导致的碎片化,同时指定string类型能降低内存占用、提升后续操作性能。

2. 用Numpy批量切片,极致优化性能

对于百万行的超大数据集,用Numpy的字符数组操作比Pandas的str方法效率更高:

import pandas as pd
import numpy as np

def parse_long_string(df):
    # 将字符串列转为Numpy固定长度字符数组
    str_np = df['long_string'].to_numpy(dtype='U5000')
    
    split_data = []
    col_names = []
    for idx, (start, end) in enumerate(slice_ranges, 1):
        col_names.append(f"a{idx:03d}")
        # Numpy批量切片,性能远高于循环调用Pandas str方法
        if end is None:
            split_col = str_np[:, start:]
        else:
            split_col = str_np[:, start:end]
        split_data.append(split_col)
    
    # 将Numpy数组转为DataFrame,指定string类型
    split_df = pd.DataFrame(np.column_stack(split_data), columns=col_names, dtype='string', index=df.index)
    
    return pd.concat([df, split_df], axis=1)

Numpy的数组操作是底层批量处理,能大幅减少循环带来的性能开销,同时避免Pandas动态列插入的碎片化问题。

3. 预分配空DataFrame后填充数据

如果不想用pd.concat,可以提前创建包含所有目标列的空DataFrame,再批量填充数据,避免动态扩容:

import pandas as pd

def parse_long_string(df):
    # 预定义所有列名
    col_names = [f"a{idx:03d}" for idx in range(1, 973)]
    # 提前创建空DataFrame,指定索引和数据类型
    split_df = pd.DataFrame(index=df.index, columns=col_names, dtype='string')
    
    # 批量填充每一列
    for idx, (start, end) in enumerate(slice_ranges, 1):
        col_name = f"a{idx:03d}"
        split_df[col_name] = df['long_string'].str.slice(start, end)
    
    return pd.concat([df, split_df], axis=1)

这种方式提前分配了完整的内存空间,不会因为逐列添加而反复调整内存布局,同样能避免碎片化警告。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 23:32:09