本文介绍一种纯 NumPy 向量化方法,无需 Python 循环,即可根据标签数组 y 将特征数组 x 拆分为多个子数组,适用于分类数据预处理、批量索引等场景。
本文介绍一种纯 numpy 向量化方法,无需 python 循环,即可根据标签数组 `y` 将特征数组 `x` 拆分为多个子数组,适用于分类数据预处理、批量索引等场景。
在机器学习与科学计算中,常需根据类别标签(如 y)对特征矩阵(如 x)进行分组切片——例如提取所有类别为 0 的样本、类别为 1 的样本等。若使用循环或列表推导式,代码冗长且性能较差;而 NumPy 提供了完全向量化、无显式循环的高效解法。
核心思路是:先按 y 排序 x,再依据各类别频次确定分割点,最后一次性切分。整个过程仅调用 np.unique、np.argsort、np.cumsum 和 np.array_split 四个内置函数,全部运行于 C 层,兼顾简洁性与高性能。
以下为完整实现:
import numpy as np
x = np.array([[2, 3, 5, 6],
[1, 2, 4, 3],
[1, 5, 6, 4],
[2, 8, 9, 5]])
y = np.array([1, 0, 1, 2])
# 步骤 1:获取 y 中唯一值及其出现次数
labels, counts = np.unique(y, return_counts=True)
# 步骤 2:对 x 按 y 的升序排列(保持 x-y 对应关系)
x_sorted = x[np.argsort(y)]
# 步骤 3:计算累计频次(排除最后一项),作为 array_split 的分割点
split_indices = np.cumsum(counts[:-1])
# 步骤 4:切分并构建成字典:{label → subarray}
grouped = dict(zip(labels, np.array_split(x_sorted, split_indices)))
print(grouped)输出结果为:
功能列表:底层程序与前台页面分离的效果,对页面的修改无需改动任何程序代码。完善的标签系统,支持自定义标签,公用标签,快捷标签,动态标签,静态标签等等,支持标签内的vbs语法,原则上运用这些标签可以制作出任何想要的页面效果。兼容原来的栏目系统,可以很方便的插入一个栏目或者一个栏目组到页面的任何位置。底层模版解析程序具有非常高的效率,稳定性和容错性,即使模版中有错误的标签也不会影响页面的显示。所有的标
{
0: array([[1, 2, 4, 3]]),
1: array([[2, 3, 5, 6],
[1, 5, 6, 4]]),
2: array([[2, 8, 9, 5]])
}✅ 关键优势说明:
- 零循环:全程基于 NumPy 向量化操作,避免 for 或 list comprehension,适合大规模数据;
- 自动适配:无论 y 中有多少类、每类多少样本,或 x 是二维/一维数组,均通用;
- 内存友好:np.array_split 返回视图或副本(取决于底层内存布局),不额外深拷贝;
- 可扩展性强:返回字典结构便于后续遍历(如 for label, X_sub in grouped.items(): ...)或转为 list、tuple 等。
⚠️ 注意事项:
- np.array_split 在分割点超出数组长度时会静默调整,但本方案中 split_indices 由 counts 严格生成,确保安全;
- 若需保持原始 y 中标签的出现顺序(而非升序),可改用 np.unique(y, return_index=True) 配合 np.take 实现稳定排序;
- 对于超大数据集,若内存受限,可考虑结合 dask.array 或分块处理,但本方法在 GB 级以内数据中仍表现优异。
该方法是 NumPy “以索引驱动操作” 思维的典型实践——不关注“怎么循环”,而聚焦于“如何构造正确索引”,真正发挥数组编程的表达力与效率。









