Julia中多维数组按逆维度顺序遍历索引的更简便方法
问题
在Julia 1.9.0中需要遍历多维数组的每个元素,常规通过CartesianIndices的遍历是第一维度优先(顺序为(1,1,1)→(2,1,1)...),但希望实现最后一维优先的遍历顺序((1,1,1)→(1,1,2)...)。目前已通过permutedims实现需求,询问是否有更简便的实现方式。
常规实现代码
T = rand(3,3,3) for idx in CartesianIndices(Tuple(size(T))) @show idx end # 输出顺序: # idx = CartesianIndex(1,1,1) # idx = CartesianIndex(2,1,1) # idx = CartesianIndex(3,1,1) # ... # idx = CartesianIndex(3,3,3)
本人实现代码
T = rand(3,3,3) D = ndims(T) for idx in permutedims(CartesianIndices(Tuple(size(T))), D:-1:1) @show idx end # 输出顺序: # idx = CartesianIndex(1,1,1) # idx = CartesianIndex(1,1,2) # idx = CartesianIndex(1,1,3) # ... # idx = CartesianIndex(3,3,3)
更简便的实现方式
方法1:反转维度构造索引并转换分量
无需创建额外的CartesianIndices数组,直接通过反转维度的索引范围生成遍历序列,再将每个索引的分量反转回原数组的索引格式:
T = rand(3,3,3) # 按反转的维度顺序生成索引 for idx_rev in CartesianIndices(reverse(size(T))) # 将反转后的索引分量转回原数组的索引 idx = CartesianIndex(reverse(idx_rev.I)) @show idx end
这种方式避免了permutedims带来的数组复制,内存效率更高,逻辑也更直观。
方法2:动态适配任意维度的遍历序列
针对任意维度的数组,可通过反转数组的轴范围,用Iterators.product生成遍历序列后再转换为原索引:
T = rand(3,3,3) # 按最后一维到第一维的顺序生成遍历元组 for idx_tuple in Iterators.product(reverse(axes(T))...) # 将元组反转后转换为原数组的CartesianIndex idx = CartesianIndex(reverse(idx_tuple)) @show idx end
这种写法无需手动指定维度数量,适配任意维度的数组,灵活性更强。
方法3:线性索引转换(内存连续场景优化)
如果数组是内存连续的,可构造最后一维优先的线性索引范围,再转换为原数组的CartesianIndex:
T = rand(3,3,3) # 基于反转维度构造线性索引 lin_indices = LinearIndices(reverse(size(T))) for lin_idx in lin_indices idx_rev = CartesianIndices(reverse(size(T)))[lin_idx] idx = CartesianIndex(reverse(idx_rev.I)) @show idx end
该方式在大型连续数组的遍历中可能有微小性能优势,适合对性能敏感的场景。
内容的提问来源于stack exchange,提问作者Sakurai.JJ
相关产品推荐
相关产品推荐

