访问二维numpy数组的最佳实践是什么?是否适用于高维数组?
结论
你的认知完全正确,array[r,c]是NumPy数组索引的官方推荐写法,优势非常明显。
推荐array[r,c]的核心原因
性能更优
array[r][c]本质是执行了两次独立的索引操作:先取出第r行生成一个临时的一维数组,再从这个临时数组中取出第c列的元素。如果数组规模大,临时对象会产生额外的内存和计算开销,极端场景下如果中间生成的是副本而非视图,性能损耗会更明显。
而array[r,c]是单次索引操作,NumPy会直接根据两个维度的索引值计算目标元素的内存地址,一步完成取值,没有额外开销。功能灵活性更强
array[r,c]支持多维度的复杂索引组合,包括切片、布尔索引、花式索引的混合使用,很多需求用两次索引根本无法实现或者会得到错误结果:
比如你要取所有行的第2、5列,用array[:, [2,5]]可以直接得到正确结果,但如果写array[:][[2,5]],实际逻辑是先取所有行,再从所有行里取第2、5行,完全不符合预期。
类似布尔索引、条件索引的组合写法,也只有逗号分隔的单次索引能正确支持。语义更清晰,易维护
array[r,c]直接表明是对二维数组的两个维度同时做索引,代码意图一目了然。而array[r][c]的写法和Python原生嵌套列表的索引方式一致,很容易让阅读代码的人混淆当前操作的是NumPy数组还是原生列表,也更容易因为索引逻辑理解错误写出bug。
高维数组的适配性
这个最佳实践完全适用于三维及更高维度的NumPy数组,甚至优势会更明显。
比如访问三维数组的第i通道、第r行、第c列,推荐写array[i, r, c],而不是array[i][r][c]。涉及多维度切片、混合索引的场景下,单次逗号索引的写法逻辑更清晰,出错概率极低,性能也更好。
小提示:如果是Python原生的嵌套列表,只能使用
list[r][c]的写法,原生列表不支持逗号分隔的多维索引,不要和NumPy数组的写法混淆。
内容的提问来源于stack exchange,提问作者albert chen

