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

使用concat和split高效计算Pandas DataFrame的内存优化方案咨询

解决大规模数据下Pandas内存耗尽问题的优化方案

嘿,我明白你现在遇到的问题——当数据量达到千万级的时候,Pandas的pd.concat循环确实会把内存吃光,毕竟每次循环生成小DataFrame再拼接,背后都是一次次的内存复制,太耗资源了。这里有几个可行的优化方案,帮你在不爆内存的前提下得到想要的结果:

方案1:用生成器流式处理+from_records直接构建(纯Pandas)

核心思路是避免在循环中创建大量小DataFrame,而是用生成器逐个生成拆分后的记录,最后一次性构建完整的DataFrame。这种方式不会把所有数据同时加载到内存,内存占用只保留当前处理的元素。

步骤:

  1. 编写生成器函数,遍历hDF的每个元素,拆分字符串并附加id:
def generate_flat_records(hDF):
    for item in hDF:
        main_id = item[0]
        # 遍历每个需要拆分的字符串
        for s in item[2]:
            # 拆分字符串:先按@分割,再按/分割经纬度
            point_id, lon_lat_str = s.split('@')
            lon, lat = lon_lat_str.split('/')
            # 生成单个记录的元组
            yield (point_id, lon, lat, main_id)
  1. 用pd.DataFrame.from_records直接从生成器构建DataFrame:
import pandas as pd

# 指定列名和数据类型(可选,但能进一步减少内存)
column_names = ['point_id', 'lon', 'lat', 'id']
dtypes = {
    'point_id': 'int64',
    'lon': 'float32',  # 地理坐标用float32足够,比float64省一半内存
    'lat': 'float32',
    'id': 'int64'
}

DF = pd.DataFrame.from_records(
    generate_flat_records(hDF),
    columns=column_names,
    dtype=dtypes
)

为什么这个方案更高效?

  • 生成器是惰性迭代,每次只处理一个元素,不会把所有拆分后的数据一次性加载到内存;
  • from_records直接从迭代器构建DataFrame,内存分配更高效,避免了pd.concat循环中的多次内存复制;
  • 替换了正则表达式split('\@|/'),改用两次普通split,既提升了速度,又减少了正则处理的内存开销。

方案2:用Dask处理超大规模数据(10^7级以上)

如果数据量真的达到千万级甚至更大,纯Pandas可能还是会有内存压力,这时候可以用Dask DataFrame——它能自动将数据分块处理,不需要把所有数据加载到内存中。

示例代码:

import dask.bag as db
import dask.dataframe as dd

# 将hDF转为Dask Bag,用于并行处理
bag = db.from_sequence(hDF)

# 映射拆分逻辑,扁平化数据
flat_bag = bag.map(
    lambda item: [
        (s.split('@')[0], *s.split('@')[1].split('/'), item[0])
        for s in item[2]
    ]
).flatten()

# 转为Dask DataFrame,指定列名和数据类型
df = flat_bag.to_dataframe(
    columns=['point_id', 'lon', 'lat', 'id'],
    meta={
        'point_id': 'int64',
        'lon': 'float32',
        'lat': 'float32',
        'id': 'int64'
    }
)

# 按需计算或导出
# 如果内存足够,可以转为Pandas DataFrame
# pd_df = df.compute()
# 或者直接导出到文件(比如CSV/Parquet)
df.to_csv('output.csv', single_file=True)

优势:

  • Dask会自动将数据分成小块,并行处理,内存占用可控;
  • 支持直接导出到文件,不需要把完整数据加载到内存;
  • 语法和Pandas高度兼容,学习成本低。

额外优化建议

  • 数据类型优化:尽可能用更小的数据类型,比如用float32代替float64,用int32代替int64(如果数值范围允许),用category类型处理重复的字符串字段;
  • 避免不必要的中间变量:尽量在生成记录的时候直接处理,不要保存拆分后的中间列表;
  • 分批处理:如果不想用Dask,也可以手动将hDF分成若干批次,处理一批就导出一批到文件,最后再合并文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 22:02:33