python - 以保持元素索引/位置相同的方式更改 numpy 数组的形状
问题描述
假设我有以下 numpy 数组
[[[1 2 3]
[4 5 6]
[7 8 9]]
[[1 2 3]
[4 5 6]
[7 8 9]]
[[1 2 3]
[4 5 6]
[7 8 9]]]
我希望能够调整此数组的大小(使其沿轴变小或变大),但现有元素具有与调整大小之前相同的索引。因此,如果我将轴 2 的大小减少一个元素,它会如下所示:
[[[1 2]
[4 5]
[7 8]]
[[1 2]
[4 5]
[7 8]]
[[1 2]
[4 5]
[7 8]]]
如果我增加轴 1 的大小,它看起来像这样:
[[[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]]]
如果不自己实现所有循环和所有内容,我将如何做到这一点?
作为参考,如果我使用 Numpy resize() 函数,并将np.resize(my_array, (3, 3, 2))
轴 2 的大小从 3 减小到 2,Numpy 只会更改维度的大小并且不会重新组织数组数据本身,这意味着元素的索引不保存:
[[[1 2]
[3 4]
[5 6]]
[[7 8]
[9 1]
[2 3]]
[[4 5]
[6 7]
[8 9]]]
解决方案
我会使用np.pad
或np.zeros
。
- 使用 np.pad:
构建示例数组:
>>> import numpy as np
>>>
>>> A = np.resize(np.r_[1:10],(3,3,3))
>>> A
array([[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]],
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]],
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]])
定义函数
>>> def recut_pad(A,shp):
... return np.pad(A[tuple(map(slice,shp))],[(0,max(0,sn-so)) for sn,so in zip(shp,A.shape)])
试试看:
>>> recut_pad(A,(2,4,5))
array([[[1, 2, 3, 0, 0],
[4, 5, 6, 0, 0],
[7, 8, 9, 0, 0],
[0, 0, 0, 0, 0]],
[[1, 2, 3, 0, 0],
[4, 5, 6, 0, 0],
[7, 8, 9, 0, 0],
[0, 0, 0, 0, 0]]])
>>> recut_pad(A,(4,2,2))
array([[[1, 2],
[4, 5]],
[[1, 2],
[4, 5]],
[[1, 2],
[4, 5]],
[[0, 0],
[0, 0]]])
- 使用
np.zeros
和切片:
定义函数:
>>> def recut_zeros(A,shp):
... out = np.zeros(shp,A.dtype)
... out[tuple(map(slice,A.shape))] = A[tuple(map(slice,shp))]
... return out
核实:
>>> np.all(recut_pad(A,(1,5,4))==recut_zeros(A,(1,5,4)))
True
>>> np.all(recut_pad(A,(7,2,3))==recut_zeros(A,(7,2,3)))
True
推荐阅读
- node.js - Mongoose NodeJS Express - 如何将数据推送到特定的子文档对象数组
- javascript - 为什么 setTimout 在渲染反应组件时在浏览器中显示一个随机整数,以及如何解决这个问题?
- python - 这个神经网络实现的错误在哪里?
- dns - 将子域指向 Vercel 上的 Next.js 页面
- django - django-tables2:显示字典
- r - 在ggplot中缩放两个y轴
- cuda - Cuda中的静态关键字
- react-native - 如何使用本机反应悬停在文本下划线?
- android - Android searchview在搜索后隐藏在recyclerview中
- vue.js - 我如何在 vue 中做一个等效的 JS?(n 个数的增量)