Numpy省略号(...)切片访问速度慢,求兼容语法的优化方案
为什么
...索引会变慢? 这确实是数组类库(比如NumPy)里存在的已知性能问题。...(Ellipsis)的本质是让解释器动态推断需要匹配的维度数量——每次你用spline_data[x, y, ..., 0]时,代码都得先检查数组的总维度数,计算...对应多少个:,再把零散的索引片段拼接成完整的索引元组。这个动态计算的过程单次开销不大,但在循环里反复调用时,累计的耗时就会被放大,最终导致比直接写完整索引慢好几倍。
保留
...语义同时优化性能的方法 下面几个方案既能保留“匹配前面所有维度”的便捷性,又能消除动态解析的开销:
提前构造固定索引元组
先根据数组的维度数,把...对应的语义转化为静态的索引元组,循环里直接复用这个元组:# 假设spline_data是N维数组,我们要实现[x, y, ..., 0]的语义 total_dims = spline_data.ndim # 计算需要补全的维度数:总维度 - 2(x、y) -1(最后一维的0) fill_dims = total_dims - 3 # 构造固定索引:x, y + fill_dims个: + 0 fixed_index = (x, y) + (slice(None),) * fill_dims + (0,) # 循环里直接用这个预定义的索引 for _ in range(your_loop_times): value = spline_data[fixed_index]这样就把动态解析
...的工作提前到循环外完成,循环内只做直接索引,性能和写完整索引几乎一致。预创建数组视图
如果你的场景里,..., 0的索引逻辑是固定的(每次都取最后一维的第0个元素),可以提前创建一个视图,循环里直接访问视图的局部索引:# 一次性创建视图,等价于spline_data[..., 0] spline_view = spline_data[..., 0] # 循环里直接访问视图的x、y位置,无需再处理... for _ in range(your_loop_times): value = spline_view[x, y]视图本身不占额外内存,只是对原数组的引用,后续访问完全跳过了
...的解析步骤,性能最优。升级数组库版本
部分数组库(比如NumPy)在新版本中对Ellipsis索引的性能做了针对性优化,如果你用的是较旧的版本,可以尝试升级到最新稳定版,说不定能在不修改代码的情况下缓解性能问题——不过上面两种主动优化的方法,可靠性会更高。
内容的提问来源于stack exchange,提问作者Luca
相关产品推荐
相关产品推荐

