NumPy高级索引:花式索引与布尔索引性能对比
请对比NumPy中花式索引(Fancy Indexing)和布尔索引(Boolean Indexing)的实现机制和性能差异。给出以下场景的推荐做法:
- 从1000×1000数组中选取特定行和列
- 筛选出所有大于阈值的元素
- 用索引数组重新排列矩阵的行
花式索引返回的是副本还是视图?如何避免拷贝?
回答
我还是少年
花式索引:用整数数组/列表索引,总是返回副本(非视图),因为无法用跨度(strides)表达不连续的选取。
arr[[0, 2, 4]] # 副本
arr[:, [1, 3, 5]] # 副本
布尔索引:用布尔数组筛选,总是返回副本。
arr[arr > 0.5] # 副本,一维结果
性能对比:
| 操作 | 花式索引 | 布尔索引 |
|------|---------|---------|
| 选取特定行 | arr[[0,2,4]] 快 | 需先构造布尔数组 |
| 阈值筛选 | 不适用 | arr[arr>0.5] 直观 |
| 重排列 | arr[idx] 简便 | 不适用 |
推荐做法:
- 阈值筛选用布尔索引(最直观)
- 按索引重排用花式索引
- 避免在循环中多次使用花式索引
- 如需视图,考虑使用
np.take()(花式索引的底层函数)
零拷贝技巧:无法完全避免,但可用np.ndarray.take()和np.ndarray.compress(),底层实现更高效。