如何调整numpy数组形状且保留原有元素的索引位置不变
解决方案
你可以通过切片截取(缩小场景) + np.pad填充(放大场景) 组合实现,完全不需要手动写循环,而且可以保证原元素的索引位置完全不变。
核心逻辑说明
- 缩小数组:直接沿目标轴截取前N个元素即可,原生切片操作天然保留原元素索引
- 放大数组:用
np.pad沿目标轴的末尾填充指定值(默认补0),原数组元素位置完全不动
通用实现代码
import numpy as np def resize_axis(arr: np.ndarray, axis: int, target_len: int, fill_value=0) -> np.ndarray: orig_len = arr.shape[axis] # 长度相同直接返回 if orig_len == target_len: return arr.copy() # 缩小场景:沿目标轴切片 elif orig_len > target_len: slices = [slice(None)] * arr.ndim slices[axis] = slice(target_len) return arr[tuple(slices)].copy() # 放大场景:沿目标轴末尾填充 else: pad_width = [(0, 0)] * arr.ndim pad_width[axis] = (0, target_len - orig_len) return np.pad(arr, pad_width, mode="constant", constant_values=fill_value)
调用示例
首先构造你给出的示例数组:
arr = np.repeat(np.arange(1, 10).reshape(3, 3)[np.newaxis, :], 3, axis=0) print("原数组shape:", arr.shape) # 输出:原数组shape: (3, 3, 3)
示例1:沿axis=2缩小到长度2
res1 = resize_axis(arr, axis=2, target_len=2) print(res1)
输出和你要求的完全一致:
[[[1 2] [4 5] [7 8]] [[1 2] [4 5] [7 8]] [[1 2] [4 5] [7 8]]]
示例2:沿axis=1放大到长度4
res2 = resize_axis(arr, axis=1, target_len=4) print(res2)
输出和你要求的完全一致:
[[[1 2 3] [4 5 6] [7 8 9] [0 0 0]] [[1 2 3] [4 5 6] [7 8 9] [0 0 0]] [[1 2 3] [4 5 6] [7 8 9] [0 0 0]]]
为什么np.resize不符合需求
np.resize的实现逻辑是先将整个数组拉平为一维数组,再重新填充到目标形状,会完全打乱原有元素的维度索引关系,和你需要的沿指定轴调整长度的逻辑完全不匹配,所以会出现元素位置错乱的问题。
内容的提问来源于stack exchange,提问作者eejakobowski
相关产品推荐
相关产品推荐

