numpy.transpose后flatten的实现逻辑及复现方法问询
如何复现Numpy中transpose+flatten的元素顺序逻辑?
我尝试自己实现Numpy的transpose+flatten处理流程:仅交换目标维度与最后一维完成转置,再将元素位置转换为线性索引,但得到的元素顺序和numpy.flatten()输出不一致。想知道Numpy是怎么实现这一逻辑的,以及如何做到和它行为一致。以下是具体示例:
示例步骤
步骤1:创建一维数组
import numpy as np 1d_Arr = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
步骤2:重塑为3D数组
3d_Arr = 1d_Arr.reshape((2,2,4))
步骤3:转置后展平
row_transpose = 3d_Arr.transpose((2,1,0)).flatten() col_transpose = 3d_Arr.transpose((0,2,1)).flatten() depth_transpose = 3d_Arr.transpose((0,1,2)).flatten()
步骤4:索引与线性索引获取代码
# 返回元素在数组中的位置,例如(2,0,1) # i:数组元素的值 indices = np.where(anArray == i) # 返回给定索引对应的线性索引 linear_idx = np.ravel_multi_index(indices, anArray.shape)
期望输出
row-transpose-flatten = [ 0 8 4 12 1 9 5 13 2 10 6 14 3 11 7 15] col-transpose-flatten = [ 0 4 1 5 2 6 3 7 8 12 9 13 10 14 11 15] depth-transpose-flatten = [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
Numpy的核心实现逻辑
1. transpose本质是轴顺序重排
Numpy的transpose(axes)参数定义的是新数组的轴与原数组轴的对应关系。比如transpose((2,1,0))表示:新数组的第0轴对应原数组的第2轴,新数组的第1轴对应原数组的第1轴,新数组的第2轴对应原数组的第0轴。
2. flatten默认按行优先(C顺序)遍历
flatten()默认使用order='C',也就是最后一个轴最快遍历的顺序读取元素。举个例子:
- 对
transpose((0,2,1))后的数组,新轴顺序是原轴0→原轴2→原轴1,展平时会先固定原轴0,遍历原轴2(列)的所有元素,再遍历原轴1(行)的下一个位置,以此类推。
3. 线性索引的计算规则
Numpy内部计算线性索引时,是基于新数组的轴顺序和行优先规则。比如原数组索引为(z, y, x)(对应轴0、1、2),经过transpose((2,1,0))后,新数组的索引是(x, y, z),新数组形状为(4,2,2),对应的线性索引公式为:
linear_idx = x * (2*2) + y * 2 + z
遍历所有x、y、z的可能取值,就能得到展平后的元素顺序。
4. 手动实现的正确方式
如果要自己实现和Numpy一致的逻辑,不需要先交换维度再转线性索引,直接按新轴的行优先顺序遍历原数组即可。比如实现row_transpose_flatten:
result = [] # 按新轴顺序x(原轴2) → y(原轴1) → z(原轴0)遍历 for x in range(4): for y in range(2): for z in range(2): # 原一维数组的索引计算:z*2*4 + y*4 + x result.append(1d_Arr[z*8 + y*4 + x]) # 结果与Numpy输出一致 print(result) # [0,8,4,12,1,9,5,13,2,10,6,14,3,11,7,15]
内容的提问来源于stack exchange,提问作者comp1023us
相关产品推荐
相关产品推荐

