我正在尝试实现一个函数,它可以将3维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"切片"所以我不必硬编码所有这些?基本上将:
移到每个可能的位置。
谢谢!
答案 0 :(得分:1)
您可以将1d切片应用于连续(维度列表)。
使用较小的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]]])]
这突出了这样一个事实,即存在两个不同的问题 - 生成迭代模式,并根据此模式拆分数组。