XGBoost Python 数据输入全指南:支持矩阵、数据分发机制与最佳实践
【免费下载链接】xgboostScalable, Portable and Distributed Gradient Boosting (GBDT, GBRT or GBM) Library, for Python, R, Java, Scala, C and more. Runs on single machine, Hadoop, Spark, Dask, Flink and DataFlow项目地址: https://gitcode.com/gh_mirrors/xg/xgboost
本文围绕 XGBoost 官方文档 doc/python/data_input.rst 中维护的「Supported Python data structures」支持矩阵展开,系统梳理 XGBoost Python 包支持的全部输入类型——从 NumPy、SciPy 稀疏矩阵、pandas 到 cuDF、CuPy、PyTorch、pyarrow、polars 等——并深入解析底层数据分发(dispatch)机制、DMatrix/QuantileDMatrix/inplace_predict三种使用路径的差异,以及每种数据类型在特征、标签(Meta Info)、多标签、原位预测等场景下的支持边界。读完本文,你将能准确判断自己的数据能否直接送入 XGBoost、应该走哪条构造路径,并理解转换失败时的错误来源。
1. 官方支持矩阵:一张表看懂所有输入类型
data_input.rst的本质是一张"支持矩阵"(support matrix),按数据类型与使用场景两个维度交叉,回答一个最常见的问题:我的数据能不能直接喂给 XGBoost?
矩阵中的列对应五种使用场景:
| 列名 | 含义 |
|---|---|
DMatrix X | 能否作为xgboost.DMatrix(或xgb.train)的特征矩阵X |
QuantileDMatrix X | 能否作为xgboost.QuantileDMatrix的特征矩阵 |
Sklearn X | 能否直接传给XGBClassifier/XGBRegressor/XGBRF*等 scikit-learn 风格估计器的fit(X, ...)/predict(X) |
Meta Info | 能否作为标签、权重等元信息(label、weight、base_margin等) |
Inplace prediction | 能否直接传给Booster.inplace_predict()做原位预测 |
Multi Label | 能否作为多目标学习中的 2 维标签 |
矩阵中的标记符号含义如下(原文定义):
- T:Supported,原生支持。
- F:Not supported,不支持。
- NE:Invalid type for the use case(类型本身合法,但对该场景无意义),例如
pandas.Series不能作为多目标标签。 - NPA:Support with the help of numpy array,借助 NumPy 数组支持(内部先转成
np.ndarray再继续)。 - AT:Support with the help of arrow table,借助 pyarrow Table 支持。
- CPA:Support with the help of cupy array,借助 CuPy 数组支持。
- SciCSR:Support with the help of scipy sparse CSR,借助
scipy.sparse.csr_matrix支持——转换可能成功也可能失败,失败时抛出类型错误。 - FF:Future Feature,若社区提出需求,短期内有望支持。
- empty:To be filled in,待补充。
表头补充说明:
X指预测器矩阵(特征矩阵);Meta Info 指 label、weight 等元信息;Multi Label 指多目标场景下的 2 维标签;Others 指未显式列出的其他格式(如lil、dia、bsr),XGBoost 会尝试将其转换为 scipy CSR。
2. 完整支持矩阵数据表
以下表格完整继承了原文档的矩阵内容,并保持符号语义不变:
| Name | DMatrix X | QuantileDMatrix X | Sklearn X | Meta Info | Inplace prediction | Multi Label |
|---|---|---|---|---|---|---|
numpy.ndarray | T | T | T | T | T | T |
scipy.sparse.csr | T | T | T | NE | T | F |
scipy.sparse.csc | T | F | T | NE | F | F |
scipy.sparse.coo | SciCSR | F | SciCSR | NE | F | F |
uri | T | F | F | F | NE | F |
list | NPA | NPA | NPA | NPA | NPA | T |
tuple | NPA | NPA | NPA | NPA | NPA | T |
pandas.DataFrame | NPA | NPA | NPA | NPA | NPA | NPA |
pandas.Series | NPA | NPA | NPA | NPA | NPA | NE |
cudf.DataFrame | T | T | T | T | T | T |
cudf.Series | T | T | T | T | FF | NE |
cupy.ndarray | T | T | T | T | T | T |
torch.Tensor | T | T | T | T | T | T |
dlpack | CPA | CPA | CPA | FF | FF | |
modin.DataFrame | NPA | FF | NPA | NPA | FF | |
modin.Series | NPA | FF | NPA | NPA | FF | |
pyarrow.Table | T | T | T | T | T | T |
polars.DataFrame | AT | AT | AT | AT | AT | AT |
polars.LazyFrame(WARN) | AT | AT | AT | AT | AT | AT |
polars.Series | AT | AT | AT | AT | AT | NE |
__array__ | NPA | F | NPA | NPA | H | |
Others | SciCSR | F | F | F |
针对该矩阵,有几点值得特别强调:
- 全场景(T)类型只有四个:
numpy.ndarray、cudf.DataFrame、cupy.ndarray、pyarrow.Table(以及torch.Tensor)。这意味着它们是 CPU/GPU 上最"通用"的载体。 polars.LazyFrame带 (WARN) 标记:原文档特别说明,polarsLazyFrame.collect支持从查询引擎选择到类型强转等多种配置,XGBoost 只是简单地使用默认参数调用collect。若需要更精细的控制,请先自行调用collect得到DataFrame再传入 XGBoost(源码中的警告逻辑见 python-package/xgboost/data.py)。torch.Tensor全 T:矩阵中torch.Tensor一行除 dlpack 相关外全部标记为 T。XGBoost 通过统一的数组接口/协议识别 PyTorch 张量并直接消费其底层缓冲区。__array__协议类型标记为 H(inplace prediction 列),表示持有该协议的对象在原位预测中会被识别处理(下文第 7 节会结合源码说明)。
3. 标记背后的三条转换路径
支持矩阵之所以有 NPA / AT / CPA / SciCSR 这些"借助 XX 支持"的标记,是因为 XGBoost 的 Python 数据入口dispatch_data_backend()本质上是一个按类型优先级依次判定的分发器。以DMatrix的构造路径为例,源码 python-package/xgboost/data.py 展示了如下判定顺序:
- scipy CSR / CSC / COO → 直接走
_from_scipy_csr/_from_scipy_csc/_from_scipy_csr(data.tocsr()); - 持有
__array_interface__的对象(NumPy 数组及其视图)→_from_numpy_array; - 字符串 /
os.PathLike→ 作为 URI 交给XGDMatrixCreateFromURI由 C++ 侧加载(支持 LibSVM 等文本格式及分布式文件系统路径); list/tuple→ 先np.array(data)转成 NumPy 再走第 2 条;- polars(含
Series/DataFrame/LazyFrame)→ 先df.to_arrow()转成 Arrow Table 再走列式路径(_from_polars_df); - pyarrow Table →
_from_arrow_table,直接走XGDMatrixCreateFromColumnar列式接口; - pandas / modin DataFrame →
_from_pandas_df,同样走XGDMatrixCreateFromColumnar; - cuDF / CuPy / dlpack → 走 CUDA 侧接口
XGDMatrixCreateFromCudaColumnar/XGDMatrixCreateFromCudaArrayInterface; - 持有
__array__协议的其他对象 →np.asarray(data)兜底转 NumPy; - 其余未知类型 → 警告后尝试
scipy.sparse.csr_matrix(data),失败则抛出TypeError: Not supported type for data.。
从这组源码可以看出两个关键事实:
- "借助 numpy 支持"(NPA)并非虚构:list/tuple、pandas、modin 最终都会落入 numpy 或列式转换路径;cudf.pandas 模式也会先解包为
_fsproxy_fast再走对应分支。 - 列式路径是 CPU 端 DataFrame 的主通道:pandas / pyarrow / polars 最终都调用
XGDMatrixCreateFromColumnar,按列零拷贝或近零拷贝地把数据交给 C++ 侧(见 python-package/xgboost/data.py),这也是官方文档反复强调"内存友好"的原因。
4. CPU 端主流类型逐个拆解
4.1 numpy.ndarray:最基础的全能选手
NumPy 是 XGBoost 最原生的输入。_from_numpy_array在 python-package/xgboost/data.py 中先校验二维形状(_check_data_shape会抛出Please reshape the input data into 2-dimensional matrix.),再统一 dtype 后通过XGDMatrixCreateFromDense创建。
使用要点:
- 特征矩阵必须是二维;一维数组需先
reshape(-1, 1)。 - dtype 会被规整为受支持的数值类型;
bool会被映射为整数类型(bool在 pandas dtype 映射表中对应"i")。 - 缺省值
missing参数:构造DMatrix(data, missing=np.nan)时 NaN 被视作缺失值;若传入非 NaN 的missing,对 NumPy 等"非列式"输入会触发_warn_unused_missing警告(见 python-package/xgboost/data.py)。
4.2 scipy 稀疏矩阵:CSR 为首选,CSC/COO 各有取舍
- csr_matrix:全支持(T/T/T),且是唯一在
QuantileDMatrix、原位预测中都支持 T 的稀疏格式。它走XGDMatrixCreateFromCSR(见 python-package/xgboost/data.py),构造前会通过transform_scipy_sparse校验indices与data长度一致并统一 dtype。 - csc_matrix:
DMatrix与 sklearn 可用,但QuantileDMatrix与原位预测不支持(F)。它在dispatch_proxy_set_data中会被tocsr()转换后再交给 CSR 路径。 - coo_matrix:标记为 SciCSR——
DMatrix构造时直接tocsr();其余场景看转换是否可行。 - Meta Info 列均为 NE:稀疏矩阵不能作为 label/weight 等元信息输入(语义上无意义)。
- 矩阵中未列出的
lil、dia、bsr等"Others"格式:XGBoost 会尝试scipy.sparse.csr_matrix(data)转换,成功则按 CSR 处理,失败抛类型错误——这正是 SciCSR 标记的源码实现(python-package/xgboost/data.py)。
4.3 pandas:DataFrame/Series 的列式转换与类型约束
pandas 输入走_transform_pandas_df→PandasTransformed→XGDMatrixCreateFromColumnar的列式路径,并在 python-package/xgboost/data.py 中维护了一张 dtype 映射表:
| pandas dtype | 映射的 feature type |
|---|---|
int8/16/32/64、uint8/16/32/64 | int |
float16/32/64 | float |
bool | i |
Int8…UInt64、Float32/64、boolean(nullable 扩展类型) | 同上对应映射 |
int8[pyarrow]等 pandas pyarrow 扩展类型 | 同上对应映射 |
关键行为与约束(均有源码依据):
- dtype 白名单:
DataFrame.dtypes必须是 int、float、bool 或 category,否则抛出ValueError(_invalid_dataframe_dtype,见 python-package/xgboost/data.py)。 - 重复列名直接报错:
Duplicate column names are not supported.(python-package/xgboost/data.py)。 - category 列需要
enable_categorical=True:否则报错提示设置该参数(_ENABLE_CAT_ERR,见 python-package/xgboost/data.py)。 - pandas Sparse 扩展类型会被转成 dense 并发出
Sparse arrays from pandas are converted into dense.警告。 - pyarrow dictionary 类型(
dtype为 DictionaryType)在 pandas 中不被支持,源码会抛pyarrow dictionary type is not supported. Use pandas category instead.(python-package/xgboost/data.py)。 - MultiIndex 列名会被拍平为空格连接的字符串作为 feature_names。
- feature_names / feature_types 自动推断:列名自动成为
feature_names,类型映射自动成为feature_types,无需手动指定。 pandas.Series作特征时被包成单列 DataFrame;作元信息时直接走_meta_from_pandas_series(转np.float32、NaN 保留);但 Series 不能做多目标标签(Multi Label 列为 NE)。
4.4 pyarrow.Table:列式零拷贝通道
pyarrow.Table是矩阵中少数几个全 T 的类型之一。它直接由_from_arrow_table处理,同样经XGDMatrixCreateFromColumnar进入 C++ 侧,几乎零拷贝消费 Arrow 缓冲区(见 python-package/xgboost/data.py)。细节包括:
BooleanArray会被 cast 成int8(位压缩数组不受支持);- Arrow
DictionaryArray(字符串类别)只有在enable_categorical=True时才被接受,否则报 dtype 错误; - 数值类型映射与 pandas 一致(
_arrow_dtype,见 python-package/xgboost/data.py)。
4.5 polars:通过 Arrow 桥接 + LazyFrame 警告
polars DataFrame / Series / LazyFrame 在矩阵中全部标记为 AT(借助 Arrow Table 支持)。源码链路为:_from_polars_df→df.to_arrow()→_transform_arrow_table(python-package/xgboost/data.py)。
值得注意的实战约束:
polars.Categorical不被支持:因为其编码可能稀疏,源码会直接抛错建议改用polars.Enum(_reject_polars_categorical,见 python-package/xgboost/data.py),对应测试见 tests/python/test_with_polars.py。LazyFrame传入会发出 UserWarning:XGBoost 使用collect()的默认参数(查询引擎、类型强转等均取默认),若需要精确控制,请自行collect后再传入。这与原文档末尾的说明完全一致。- 依赖
pyarrow,未安装时会抛ImportError: pyarrow is required for polars.。 polars.Series作多目标标签不可用(NE)。
5. GPU 端类型:cuDF、CuPy、dlpack 与 PyTorch
5.1 cudf.DataFrame / cudf.Series:GPU 原生列式
cuDF 数据全 T(cudf.Series的 Inplace prediction 为 FF 除外)。源码_from_cudf_df走XGDMatrixCreateFromCudaColumnar(python-package/xgboost/data.py),在 GPU 上按列构造,避免 CPU-GPU 往返拷贝。细节:
- bool 列会被转成
uint8(源码中注释引用了上游 issue 的 workaround); - 类别列同样要求
enable_categorical=True,否则报_ENABLE_CAT_ERR; - MultiIndex 列名拍平规则与 pandas 一致。
5.2 cupy.ndarray 与 dlpack:CUDA 数组接口
cupy.ndarray全 T。走XGDMatrixCreateFromCudaArrayInterface,依赖__cuda_array_interface__(见 python-package/xgboost/data.py)。- dlpack在矩阵中标记为 CPA:
_is_dlpack通过检查PyCapsule类型与dltensor字符串识别,_transform_dlpack用cupy.from_dlpack将其转成 CuPy 数组后再走 CUDA 路径(python-package/xgboost/data.py)。因此 dlpack 的可用性事实上取决于 cupy 是否安装。 torch.Tensor全 T:PyTorch 张量通过其缓冲协议被 XGBoost 直接识别消费(矩阵中无任何受限标记)。
5.3 modin:pandas API 的分布式替代
modin DataFrame/Series 全部标记为 NPA(QuantileDMatrix列为 FF)。源码中 modin 输入会被当作 pandas 处理(_from_pandas_df/_meta_from_pandas_df),依赖 modin 的 pandas API 兼容层完成转换。若你使用 modin,注意QuantileDMatrix与原位预测暂不可用(FF)。
5.4 设备匹配提醒
sklearn 估计器的fit()文档明确提醒:当tree_method='hist'时内部会用QuantileDMatrix省内存,但如果输入数据所在设备与训练算法不匹配(例如 CPU 上的 numpy 数组配cuda训练),数据会先在 CPU 处理再传输到 GPU,带来性能损耗(见 python-package/xgboost/sklearn.py)。inplace_predict同样有该语义:输入数据的 device ordinal 与 booster 配置不一致时,数据会被拷贝到 booster 所在设备(python-package/xgboost/core.py)。
6. Meta Info 与多标签(Multi Label)的边界
Meta Info指DMatrix(label=..., weight=..., base_margin=..., ...)中传入的标签与样本权重等信息,底层统一由dispatch_meta_backend分发(python-package/xgboost/data.py)。支持类型与特征矩阵基本一致(numpy、list/tuple、pandas、cudf、cupy、arrow、polars 均可用),但注意:
- scipy 稀疏矩阵作为 Meta Info 标记为 NE(语义不成立);
- 元信息的形状校验严格:除
label、base_margin这两个可矩阵化的字段外,其余字段只允许一维或 (n, 0)/(n, 1) 形状(_validate_meta_shape,见 python-package/xgboost/data.py)。
Multi Label(多目标)需要 2 维标签。矩阵显示:numpy、list、tuple、cudf.DataFrame、cupy、pyarrow.Table、polars 全支持;而pandas.Series、cudf.Series、polars.Series、scipy稀疏矩阵均为 NE/F(单维或稀疏结构天然无法表达多目标标签)。需要多目标建模时,应优先使用 DataFrame 或二维 numpy 作为标签载体。
7. Inplace prediction 原位预测:支持面与原理
Booster.inplace_predict(data)(python-package/xgboost/core.py)与常规predict最大的区别是:不做预测结果缓存,可避免为一次性预测构造DMatrix的开销,因此矩阵中大部分类型都能原位预测。其内部同样复用数据分发逻辑:pandas/polars/arrow 会先做列式变换,numpy/scipy/cupy 直接走各自接口。
几个容易踩坑的点:
- scipy.csc / scipy.coo 不支持原位预测(F):需要先
tocsr()转换后再调用; - cudf.Series 为 FF:暂不可用;
- dlpack 为 FF;
__array__协议类型标记为 H:源码中凡持有__array__协议的对象会被np.asarray兜底转换后参与原位预测(python-package/xgboost/data.py);- URI(文件路径)标记为 NE:
inplace_predict不接受文件路径输入; - 线程安全语义:仅单独调用
inplace_predict时多线程安全(无锁),但不能与训练等其他操作并发(见 python-package/xgboost/core.py)。
此外,sklearn 风格的估计器(XGBClassifier等)在booster != "gblinear"时默认使用inplace_predict,仅在设备不匹配等失败场景下回退到DMatrix(python-package/xgboost/sklearn.py)——这就是矩阵中 sklearn 列大部分标记为 T 的落地机制。
8. QuantileDMatrix:支持面更窄、内存更省
QuantileDMatrix是为hist树方法设计的内存友好矩阵,训练时直接以分位数草图形式消费数据。矩阵显示其支持面比DMatrix更窄:
- 不支持:
scipy.sparse.csc、scipy.sparse.coo、uri、__array__协议对象、modin(FF)、dlpack 需借助 cupy(CPA)、Others格式; - 支持:numpy、scipy.csr、pandas、cudf、cupy、torch、pyarrow、polars(AT)。
sklearn 估计器在tree_method='hist'且非 gblinear 时,会优先尝试构造QuantileDMatrix省内存,遇到TypeError再回退DMatrix(python-package/xgboost/sklearn.py)。验证/测试集需传入ref=指向训练集矩阵(见 python-package/xgboost/core.py 的QuantileDMatrix文档),这也解释了为什么矩阵对QuantileDMatrix X单独列出一列——它的输入约束与DMatrix并不等价。QuantileDMatrix的迭代器版本DataIter支持在DMatrix/QuantileDMatrix构造中分批喂数据(测试见 tests/python/test_data_iterator.py),进一步扩展了可接受的数据来源。
9. 实践决策速查
综合支持矩阵与源码分发逻辑,给出如下选择建议:
- 通用首选:CPU 上用
numpy.ndarray或pandas.DataFrame;GPU 上用cudf.DataFrame或cupy.ndarray;需要列式互操作时用pyarrow.Table。 - 稀疏数据:优先
scipy.sparse.csr_matrix(全场景 T 最多),避免直接使用csc/coo做QuantileDMatrix或原位预测。 - 超大数据 / 内存敏感:用
QuantileDMatrix(hist 方法自动启用),验证集记得传ref。 - polars 用户:先自行
collect()得到DataFrame再传入,避免 LazyFrame 的默认 collect 行为与警告;类别列请使用polars.Enum而非polars.Categorical。 - 类别特征:pandas/cudf/arrow 的 category/dictionary 列必须在构造时设置
enable_categorical=True。 - 在线/流式预测:优先
inplace_predict(避免 DMatrix 构造与缓存开销),注意其线程安全前提与类型限制。 - 不确认类型时:优先查本支持矩阵;未知类型会先尝试转 scipy CSR,失败后抛
TypeError,错误信息会直接给出实际类型。
10. 相关源码与测试导航
- 支持矩阵文档:doc/python/data_input.rst
- 数据分发主入口
dispatch_data_backend/dispatch_meta_backend/dispatch_proxy_set_data:python-package/xgboost/data.py - 类型判定工具(pandas/cudf/polars/arrow/modin 惰性识别):python-package/xgboost/compat.py
inplace_predict实现:python-package/xgboost/core.pyQuantileDMatrix/ExtMemQuantileDMatrix:python-package/xgboost/core.py- sklearn 估计器数据路径:python-package/xgboost/sklearn.py(QDM 自动选择)、python-package/xgboost/sklearn.py(inplace_predict 自动选择)
- 各类型测试用例:tests/python/test_with_scipy.py、tests/python/test_with_pandas.py、tests/python/test_with_polars.py、tests/python/test_with_arrow.py、tests/python/test_quantile_dmatrix.py、tests/python/test_data_iterator.py
【免费下载链接】xgboostScalable, Portable and Distributed Gradient Boosting (GBDT, GBRT or GBM) Library, for Python, R, Java, Scala, C and more. Runs on single machine, Hadoop, Spark, Dask, Flink and DataFlow项目地址: https://gitcode.com/gh_mirrors/xg/xgboost
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考