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

基于Numpy实现决策树学习器时的索引链式调用问题

你遇到的核心问题是全局排序索引i是针对整个x数组的,不能直接用子集n去索引i来得到子集的排序结果。要复用全局排序的结果,得从全局排序索引里筛选出属于n的行号,并且保留它们的排序顺序。

给你两种实用的实现方式:

方法一:按列逐个处理(直观易懂)

对每个特征列,从全局排序索引里挑出属于n的行号,再用这些行号提取对应列的排序后数据:

import numpy as np

x = np.array([[1,8,7,4,3,9,0,2,5,6], [7,5,3,8,9,4,6,10,2,1]]).T
i = np.argsort(x, 0)
n = np.nonzero(x[:, 0] < 6)[0] 

# 初始化结果数组,匹配子集n的形状
sorted_x_n = np.empty((len(n), x.shape[1]), dtype=x.dtype)

for col in range(x.shape[1]):
    # 从当前列的全局排序索引中,筛选出属于n的行号(保留排序顺序)
    valid_global_indices = i[:, col][np.isin(i[:, col], n)]
    # 提取对应列的排序后数据
    sorted_x_n[:, col] = x[valid_global_indices, col]

print(sorted_x_n)

输出结果和np.sort(x[n], axis=0)完全一致,但复用了之前的全局排序索引,避免了重复排序。

方法二:向量化实现(高效适配多特征列)

如果特征列数量较多,用向量化操作代替循环能提升效率:

import numpy as np

x = np.array([[1,8,7,4,3,9,0,2,5,6], [7,5,3,8,9,4,6,10,2,1]]).T
i = np.argsort(x, 0)
n = np.nonzero(x[:, 0] < 6)[0] 

# 生成布尔矩阵,标记全局排序索引中哪些行属于子集n
mask = np.isin(i, n)
# 按列提取有效索引并生成排序后的子集数据
sorted_x_n = np.array([x[i[mask[:, col], col], col] for col in range(x.shape[1])]).T

原理和方法一一致,只是用矩阵操作简化了显式循环。

原代码错误原因

x[i[n], np.arange(2)]的问题在于:i[n]取的是全局排序索引的前len(n)行,这些行对应的是整个x的排序位置,和子集n没有对应关系。比如第二列的全局排序索引是针对整个x第二列的,直接取i[n,1]得到的行号大概率不在n里,自然无法得到x[n]的排序结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 20:00:09