如何排查Python中特定代码行的内存占用问题?
查看Python代码段内存占用的方法
- 使用
memory_profiler库:给包含目标代码的函数加上@profile装饰器,运行脚本时执行python -m memory_profiler your_script.py,就能看到每一行代码的内存变化细节。 - 监控DataFrame内存:pandas的DataFrame自带
.memory_usage(deep=True)方法,能计算各列的实际内存占用(包括对象类型的深层内存),直接打印结果即可了解数据框的内存开销。 - 关键节点内存快照:用
psutil库在代码的关键步骤(比如merge前后)打印当前进程的内存占用:import psutil process = psutil.Process() print(f"merge前内存: {process.memory_info().rss / 1024**2:.2f} MB") # 执行merge操作 print(f"merge后内存: {process.memory_info().rss / 1024**2:.2f} MB")
针对你的merge内存问题的优化建议
你的判断是对的,1e5行的df和1e7行的df2merge直接做merge,很容易生成超大规模的中间数据,导致内存溢出。可以试试这些优化手段:
- 提前过滤无关数据:先提取df中存在的
vid集合,过滤df2merge只保留这些vid的数据,减少merge的规模:valid_vids = df['vid'].unique() df2merge_filtered = df2merge[df2merge['vid'].isin(valid_vids)] - 分块处理数据:把df拆成多个小批次,逐个批次和过滤后的df2merge做merge,最后合并结果:
import numpy as np chunks = np.array_split(df, 10) # 拆成10块,可根据内存调整数量 result_parts = [] for chunk in chunks: temp = chunk.reset_index().merge(df2merge_filtered, on='vid', suffixes=['','_x']) temp['proportions'] = temp[['first','first_x']].min(axis=1) - temp[['second','second_x']].max(axis=1) temp = temp[temp['proportions'] >= 0] part = temp.groupby('index')['proportions'].sum() result_parts.append(part) df["value_weighted_average"] = pd.concat(result_parts) - 优化数据类型:将列类型改为更节省内存的格式,比如把字符串类型的
vid改成category(如果vid的唯一值不多),数值型列从float64改成float32:df['vid'] = df['vid'].astype('category') df2merge['vid'] = df2merge['vid'].astype('category') for col in ['first', 'second']: df[col] = df[col].astype('float32') df2merge[col] = df2merge[col].astype('float32') - 改用大数据框架:如果数据量持续超大,可以用
dask.dataframe或pyspark处理,它们支持分块/分布式计算,不会把所有数据加载到内存中。
内容的提问来源于stack exchange,提问作者roulette01
相关产品推荐
相关产品推荐

