NumPy高性能合并索引列与值列为可索引二维数组
NumPy高性能无循环实现方案
完全适配超大规模数据场景,不依赖输入行顺序,所有操作均为NumPy底层向量化实现,性能远高于Python循环或排序方案。
核心思路
利用NumPy整数数组高级索引的批量赋值能力,直接将每行的值映射到对应二维索引位置,全程无Python层循环,时间复杂度为线性O(n),是理论最优实现。
实现代码
import numpy as np # 输入数据 data = np.array([[ 0. , 1. , 48. , 4. ], [ 1. , 2. , 44. , 4.4], [ 1. , 1. , 34. , 2.3], [ 0. , 2. , 55. , 2.2], [ 0. , 0. , 42. , 2. ], [ 1. , 0. , 22. , 1. ]]) # 若预先不知道索引最大值,可通过下式自动计算: # i_idx = data[:, 0].astype(int) # j_idx = data[:, 1].astype(int) # max_i, max_j = i_idx.max(), j_idx.max() max_i = 1 max_j = 2 value_col_count = data.shape[1] - 2 # 初始化结果数组,用empty比zeros省去内存置零开销,速度更快 result = np.empty((max_i + 1, max_j + 1, value_col_count), dtype=data.dtype) # 提取整数类型索引 i_idx = data[:, 0].astype(int) j_idx = data[:, 1].astype(int) # 批量赋值,底层C实现,无Python循环 result[i_idx, j_idx] = data[:, 2:]
运行后得到的result与题目给出的目标结果完全一致:
array([[[42. , 2. ], [48. , 4. ], [55. , 2.2]], [[22. , 1. ], [34. , 2.3], [44. , 4.4]]])
方案优势
- 无顺序依赖:无论输入数组的行怎么打乱,只要索引和值的对应关系正确,就能生成正确结果,完全符合题目“不能假设输入行顺序”的要求
- 性能极强:所有操作均为NumPy底层向量化实现,内存访问连续,处理千万级行规模的数据也能在毫秒级完成,比Python循环快2~3个数量级
- 通用性好:值部分支持任意列数,不管后续跟着2列还是上百列特征,代码无需修改即可运行
- 无额外开销:不需要对输入做排序(省去O(nlogn)的排序成本),也不需要额外做哈希映射,内存占用和计算量都压到最低
避坑提示:不要直接对值部分调用
reshape生成结果,reshape逻辑完全依赖输入数组的行排列顺序,只要输入行乱序,结果就会完全错误。
内容的提问来源于stack exchange,提问作者Scindix
相关产品推荐
相关产品推荐

