解决DataFrame碎片化警告及批量添加列性能优化问题
高效批量将特征图矩阵值映射到DataFrame的解决方案
核心优化思路
彻底抛弃逐行循环,利用Pandas的向量化字符串处理+NumPy的批量索引能力,一次性完成所有列的赋值,效率比逐行操作提升几十甚至上百倍。
具体实现步骤
- 批量拆分
pix列为row和col整数列
不用循环处理每个元素,直接用Pandas字符串方法批量解析:
# 处理pix列:去掉首尾括号,拆分出row和col并转成整数 df_new[['row', 'col']] = df_new['pix'].str.strip('()').str.split(',', expand=True).astype(int)
- 批量提取特征矩阵值并赋值
利用NumPy的花式索引,直接根据row和col列的值批量获取对应位置的元素,一次性完成所有新列的赋值:
# 批量赋值所有特征列 df_new['Aridity'] = arr3[df_new['row'], df_new['col']] df_new['Trend in PDSI'] = arr4[df_new['row'], df_new['col']] df_new['rainfall seasonality'] = arr5[df_new['row'], df_new['col']] df_new['Precipitation variability'] = arr6[df_new['row'], df_new['col']] df_new['Trend in Precipitation'] = arr7[df_new['row'], df_new['col']] df_new['rainfall at coldest quarter'] = arr8[df_new['row'], df_new['col']] df_new['rainfall at hottest quarter'] = arr9[df_new['row'], df_new['col']] df_new['Temperature seasonality'] = arr10[df_new['row'], df_new['col']] df_new['Elevation'] = arr11[df_new['row'], df_new['col']] df_new['Depth of water table'] = arr12[df_new['row'], df_new['col']] df_new['Depth to bedrock'] = arr13[df_new['row'], df_new['col']] # 可选:处理完成后删除临时的row、col列 df_new.drop(columns=['row', 'col'], inplace=True)
为什么这个方法更快?
- 原逐行循环的问题:每次赋值都会触发Pandas内部的DataFrame结构检查与修改,导致数据碎片化;同时Python循环本身开销极大,4万行数据会产生大量重复操作。
- 向量化操作的优势:Pandas字符串处理、NumPy花式索引都是底层用C实现的批量操作,完全避免了Python循环的额外开销,4万行数据的处理通常只需要几秒甚至更短时间。
额外冗余优化(可选)
如果所有特征矩阵arr3到arr13维度一致,可以合并成三维数组,进一步简化代码:
# 将所有特征矩阵合并为三维数组(维度:高×宽×特征数) feature_arrays = np.stack([arr3, arr4, arr5, arr6, arr7, arr8, arr9, arr10, arr11, arr12, arr13], axis=-1) # 定义特征列名列表 feature_names = [ 'Aridity', 'Trend in PDSI', 'rainfall seasonality', 'Precipitation variability', 'Trend in Precipitation', 'rainfall at coldest quarter', 'rainfall at hottest quarter', 'Temperature seasonality', 'Elevation', 'Depth of water table', 'Depth to bedrock' ] # 一次性批量赋值所有特征列 df_new[feature_names] = feature_arrays[df_new['row'], df_new['col']]
内容的提问来源于stack exchange,提问作者孟泽楷
相关产品推荐
相关产品推荐

