我正在尝试实现一个函数,它可以将一个三维的numpy数组分割成8块,同时保持顺序不变。从本质上说,我需要分裂:
G[:21, :18,:25]
G[21:, :18,:25]
G[21:, 18:,:25]
G[:21, 18:,:25]
G[:21, :18,25:]
G[21:, :18,25:]
G[21:, 18:,25:]
G[:21, 18:,25:]这个矩阵的原始大小应该是42,36,50。怎么可能概括这8个“切片”,这样我就不必全部硬编码了?本质上是将:移动到每个可能的位置。
谢谢!
发布于 2016-05-01 16:10:04
您可以将一维切片应用于连续的(列表)维度。
用一个更小的3d阵列
In [147]: X=np.arange(4**3).reshape(4,4,4)复合列表理解产生嵌套列表。这里我用的是最简单的双分裂
In [148]: S=[np.split(z,2,0) for y in np.split(X,2,2) for z in np.split(y,2,1)]在本例中,所有子列表都具有相同的大小,因此我可以将其转换为一个数组,以便方便查看:
In [149]: SA=np.array(S)
In [150]: SA.shape
Out[150]: (4, 2, 2, 2, 2)有8个子数组,但分组(4,2)。
In [153]: SAA = SA.reshape(8,2,2,2)
In [154]: SAA[0]
Out[154]:
array([[[ 0, 1],
[ 4, 5]],
[[16, 17],
[20, 21]]])
In [155]: SAA[1]
Out[155]:
array([[[32, 33],
[36, 37]],
[[48, 49],
[52, 53]]])命令对吗?我可以通过改变3分裂操作中的轴来改变它。
另一种方法是将索引表达式编写为元组。
In [156]: x,y,z = 2,2,2 # define the split points
In [157]: ind = [(slice(None,x), slice(None,y), slice(None,z)),
(slice(x,None), slice(None,y), slice(None,z)),]
# and so on
In [158]: S1=[X[i] for i in ind]
In [159]: S1[0]
Out[159]:
array([[[ 0, 1],
[ 4, 5]],
[[16, 17],
[20, 21]]])
In [160]: S1[1]
Out[160]:
array([[[32, 33],
[36, 37]],
[[48, 49],
[52, 53]]])看上去和我以前收到的一样。
元组的ind列表可以通过某种迭代和/或列表理解来生成。甚至可以使用itertools.product或np.mgrid来生成排列。
一个itertools.product版本可能看起来类似于
In [220]: def foo(i):
return [(slice(None,x) if j else slice(x,None))
for j,x in zip(i,[2,2,2])]
In [221]: SAA = np.array([X[foo(i)] for i in
itertools.product(range(2),range(2),range(2))])
In [222]: SAA[-1]
Out[222]:
array([[[ 0, 1],
[ 4, 5]],
[[16, 17],
[20, 21]]])product以最快的速度迭代最后一个值,因此列表会反转(与目标相比)。
为了生成特定的顺序,可以更容易地明确列出元组,例如:
In [227]: [X[foo(i)] for i in [(1,1,1),(0,1,1),(0,0,1)]]
Out[227]:
[array([[[ 0, 1],
[ 4, 5]],
[[16, 17],
[20, 21]]]), array([[[32, 33],
[36, 37]],
[[48, 49],
[52, 53]]]), array([[[40, 41],
[44, 45]],
[[56, 57],
[60, 61]]])]这突出了一个事实,即存在两个不同的问题--生成迭代模式,并根据该模式拆分数组。
https://stackoverflow.com/questions/36965876
复制相似问题