如何在无内存重复的情况下将Polars DataFrame用于XGBoost训练?
将Polars DataFrame用于XGBoost训练的高效零拷贝方案
不需要通过冗余的Numpy转换(或可实现零拷贝的Numpy视图转换),以下两种方案能最大程度避免内存开销,是当前的最优选择:
方案1:零拷贝生成Numpy视图
Polars的to_numpy()方法支持zero_copy_only=True参数,当数据布局满足Numpy的连续内存要求时,会直接返回原始数据的Numpy视图,完全不产生内存拷贝。如果布局不满足,该方法会抛出错误(这种场景极少出现,通常调整数据类型即可解决)。
示例代码:
import polars as pl import xgboost as xgb # 假设已完成Polars数据处理流程 processed_df = pl.read_csv("your_data.csv") X = processed_df.drop("target_column") y = processed_df["target_column"] # 零拷贝获取特征和标签的Numpy视图 X_np = X.to_numpy(zero_copy_only=True) y_np = y.to_numpy(zero_copy_only=True) # 构建XGBoost训练用DMatrix dtrain = xgb.DMatrix(X_np, label=y_np)
方案2:直接传入Arrow格式数据
XGBoost原生支持Arrow数据结构,而Polars底层基于Arrow实现,因此可以直接将Polars转换为Arrow表格/数组传入DMatrix,全程几乎无拷贝。
示例代码:
# 提取Arrow格式的特征和标签 X_arrow = X.to_arrow() y_arrow = y.to_arrow() # 直接用Arrow数据构建DMatrix dtrain = xgb.DMatrix(X_arrow, label=y_arrow)
额外说明
- 避免直接转Pandas DataFrame:Polars转Pandas默认会产生内存拷贝,即便使用PyArrow扩展数组,开销也远大于上述两种方案。
- 验证零拷贝:可以用
numpy.shares_memory()检查Numpy视图与Polars原始数据是否共享内存,确认无拷贝发生:import numpy as np print(np.shares_memory(X.to_numpy(zero_copy_only=True), X.to_arrow()["your_feature_col"].to_numpy())) # 输出True表示内存共享,无拷贝
内容的提问来源于stack exchange,提问作者Lucas Morin
相关产品推荐
相关产品推荐

