Python 在Numpy中拆分多维数组

Python 在Numpy中拆分多维数组,python,arrays,numpy,multidimensional-array,split,Python,Arrays,Numpy,Multidimensional Array,Split,我正在尝试拆分多维数组(array) 将numpy导入为np 形状=(3,4,4,2) 数组=np.random.randint(0,10,形状) 进入一个数组(new_array),形状为(3,2,2,2,2),其中维度1已拆分为2(维度1和2),而数组中的维度2已拆分为2(维度3和4) 到目前为止,我得到了一种工作方法,即: div_x=2 div_y=2 new\u dim\u x=shape[1]//div\u x new\u dim\u y=shape[2]//div\u y 新的_

我正在尝试拆分多维数组(
array

将numpy导入为np
形状=(3,4,4,2)
数组=np.random.randint(0,10,形状)
进入一个数组(
new_array
),形状为
(3,2,2,2,2)
,其中维度1已拆分为2(维度1和2),而
数组中的维度2已拆分为2(维度3和4)

到目前为止,我得到了一种工作方法,即:

div_x=2
div_y=2
new\u dim\u x=shape[1]//div\u x
new\u dim\u y=shape[2]//div\u y
新的_数组_split=np.数组([np.split(每个_sub,轴=2,索引_或_部分=div_y)用于np.split中的每个_sub(数组[:,:(新_dim_x*div_x),:(新_dim_y*div_y)],轴=1,索引_或_部分=div_x)])
我还考虑使用
重塑

new_array_reformate=array[:,:(div_x*new_dim_x),:(div_y*new_dim_y),…]重塑(shape[0],div_x,div_y,new_dim_x,new_dim_y,shape[-1])。转置(1,2,0,3,4,5)
重塑
方法比
拆分
方法更快:

%timeit数组[:,:(div_x*new_dim_x),:(div_y*new_dim_y),…]重塑(shape[0],div_x,div_y,new_dim_x,new_dim_y,shape[-1])。转置(1,2,0,3,4,5)
每个回路2.16µs±44.1 ns(7次运行的平均值±标准偏差,每个100000个回路)
%timeit np.数组([np.split(每个_sub,轴=2,索引_或_部分=div_y)用于np.split中的每个_sub(数组[:,:(新尺寸x*div_x),:(新尺寸y*div_y)],轴=1,索引_或_部分=div_x)])
每个回路58.3µs±2.13µs(7次运行的平均值±标准偏差,每个10000个回路)
但是,由于最后一个维度,我无法得到相同的结果:

print(‘重塑方法’)
打印(新阵列形状[1,0,0,…])
打印(“\n打印方法”)
打印(新数组分割[1,0,0,…])
整形法
[[[2 2]
[4 3]]
[[3 5]
[5 9]]]
分裂法
[[[2 2]
[4 3]]
[[5 3]
[9 8]]]
split方法完全符合我的要求,我确实逐个检查了数字,它实现了我想要的拆分类型,但速度不是我想要的

问题

是否有一种方法可以使用“重塑”或任何其他方法获得与“拆分”方法相同的结果

上下文

数组实际上是来自图像处理的数据流,其中
数组
的第一个维度是时间,第二个维度是坐标x(4),第三个维度是坐标y(4),第四个维度(2)是流的大小和相位

我想将图像(坐标x和y)分割成子图像,形成一个2x2的图片数组,这样我可以更局部地分析流,执行平均值、聚类等

这个过程(分割)将被执行很多次,这就是为什么我要寻找一个最佳和有效的解决方案。我相信方法可能是使用
重塑
,但我愿意接受任何其他选择。

-


对于您的用例,我不确定
重塑
是否是最佳选择。如果希望能够进行局部平均和聚类,则可能需要一个窗口函数:

from skimage.util import view_as_windows

def window_over(arr, size = 2, step = 2, axes = (1, 2) ):
    wshp = list(arr.shape)
    for a in axes:
        wshp[a] = size
    return view_as_windows(arr, wshp, step).squeeze()

window_over(test).shape
Out[]: (2, 2, 3, 2, 2, 2)
然后可以使用
转置
重新排列输出轴。这样做的好处是,您可以获得中间窗口:

window_over(test, step = 1).shape
Out[]: (3, 3, 3, 2, 2, 2)
这包括重叠的2x2窗口,因此可以得到3x3个结果

由于可以重叠,因此也不需要窗口可以被尺寸大小整除:

window_over(test, size = 3).shape
Out[]: (2, 2, 3, 3, 3, 2)

听起来你甚至想在中间的二维空间上使用(nxn)窗口函数?这将使您能够更轻松地进行空间平均和聚类。可以让你被任何形状的窗户“分开”是的,这就是我想要的。如果您愿意,请检查Divakar解决方案!不过,
重塑
并不是这样做的。检查我的答案。我就快到了!!我的代码是
数组。重塑(3,2,2,2,2,2)…转置(1,2,0,3,4,5)
因此新维度似乎正好位于拆分维度之后。。。这是有道理的。。。我不知道为什么我以前没有想到这一点。非常感谢你!嗨,Daniel F.你能进一步说明为什么我不应该使用整形吗?我想使用窗口函数,您可以只获取阵列上的视图,而无需修改它。这就是你的意思吗?回答也很好!我确实看过函数
view\u as\u windows
,但我认为我没有完全正确地理解它的用途。
window_over(test, size = 3).shape
Out[]: (2, 2, 3, 3, 3, 2)