Python 将三维阵列切片为多个二维阵列

Python 将三维阵列切片为多个二维阵列,python,numpy,Python,Numpy,我有一个形状的numpy数组(64,64,3)。我们如何获得三个维度(64,64)的数组 您可以使用moveaxis将拆分轴一直向左移动,然后使用序列解包: x,y,z = np.moveaxis(arr, -1, 0) 您可以使用moveaxis将拆分轴一直向左移动,然后使用序列解包: x,y,z = np.moveaxis(arr, -1, 0) 这是迭代的另一种情况,对于一些步骤来说,迭代是不错的 In [145]: arr = np.ones((64,64,3)) 打开列表: In

我有一个形状的numpy数组(64,64,3)。我们如何获得三个维度(64,64)的数组

您可以使用
moveaxis
将拆分轴一直向左移动,然后使用序列解包:

x,y,z = np.moveaxis(arr, -1, 0)

您可以使用
moveaxis
将拆分轴一直向左移动,然后使用序列解包:

x,y,z = np.moveaxis(arr, -1, 0)

这是迭代的另一种情况,对于一些步骤来说,迭代是不错的

In [145]: arr = np.ones((64,64,3))
打开列表:

In [146]: a,b,c = [arr[:,:,i] for i in range(3)]
In [147]: a.shape
Out[147]: (64, 64)
解包转置阵列:

In [148]: a,b,c = np.moveaxis(arr,-1,0)
In [149]: a.shape
Out[149]: (64, 64)
这样一个小例子的时间安排并非开创性的,但它们暗示了这两种方法的相对优势:

In [150]: timeit a,b,c = [arr[:,:,i] for i in range(3)]
3.02 µs ± 10.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [151]: timeit a,b,c = np.moveaxis(arr,-1,0)
18.4 µs ± 946 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
阵列解包(第1维)需要将阵列转换为包含3个子阵列的列表,这可以从以下类似计时中看出:

In [154]: timeit a,b,c = list(np.moveaxis(arr,-1,0))
17.8 µs ± 15.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [155]: timeit a,b,c = [i for i in np.moveaxis(arr,-1,0)]
17.9 µs ± 14.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
花费时间的不是解包或迭代。这是
moveaxis

In [156]: timeit np.moveaxis(arr,-1,0)
14 µs ± 4.41 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
查看其代码,我们看到它使用了
转置
,首先从参数构建了
顺序

直接调用
transpose
速度很快(因为它只涉及改变形状和步幅):

解包这个转置比我原来理解列表的速度要快一点

In [158]: timeit a,b,c = arr.transpose(2,0,1)
2.78 µs ± 9.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

因此,相对于任务的其余部分,
moveaxis
有很大的开销。也就是说,它可能不会随着阵列的侧面而增加。这是一个固定的开销。

这是另一种情况,在这种情况下,迭代对于几个步骤来说是不错的

In [145]: arr = np.ones((64,64,3))
打开列表:

In [146]: a,b,c = [arr[:,:,i] for i in range(3)]
In [147]: a.shape
Out[147]: (64, 64)
解包转置阵列:

In [148]: a,b,c = np.moveaxis(arr,-1,0)
In [149]: a.shape
Out[149]: (64, 64)
这样一个小例子的时间安排并非开创性的,但它们暗示了这两种方法的相对优势:

In [150]: timeit a,b,c = [arr[:,:,i] for i in range(3)]
3.02 µs ± 10.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [151]: timeit a,b,c = np.moveaxis(arr,-1,0)
18.4 µs ± 946 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
阵列解包(第1维)需要将阵列转换为包含3个子阵列的列表,这可以从以下类似计时中看出:

In [154]: timeit a,b,c = list(np.moveaxis(arr,-1,0))
17.8 µs ± 15.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [155]: timeit a,b,c = [i for i in np.moveaxis(arr,-1,0)]
17.9 µs ± 14.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
花费时间的不是解包或迭代。这是
moveaxis

In [156]: timeit np.moveaxis(arr,-1,0)
14 µs ± 4.41 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
查看其代码,我们看到它使用了
转置
,首先从参数构建了
顺序

直接调用
transpose
速度很快(因为它只涉及改变形状和步幅):

解包这个转置比我原来理解列表的速度要快一点

In [158]: timeit a,b,c = arr.transpose(2,0,1)
2.78 µs ± 9.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

因此,相对于任务的其余部分,
moveaxis
有很大的开销。也就是说,它可能不会随着阵列的侧面而增加。这是一个固定的开销。

[arr[:,:,i]for i in range(3)]
抱歉,它不起作用。另外,我正在寻找一种方法来实现这一点,使用矢量化,而不使用任何for循环。
x,y,z=np.moveaxis(arr,-1,0)
谢谢Paul,这很有效。如果你能把它写下来作为答案,我会把它标记为接受。对于这个小问题,我发现
moveaxis
实际上速度较慢。但比速度更重要的是可理解性。你明白被接受的答案吗?你能适应其他情况吗?
[arr[:,:,i]for i in range(3)]
对不起,它不起作用了。另外,我正在寻找一种方法来实现这一点,使用矢量化,而不使用任何for循环。
x,y,z=np.moveaxis(arr,-1,0)
谢谢Paul,这很有效。如果你能把它写下来作为答案,我会把它标记为接受。对于这个小问题,我发现
moveaxis
实际上速度较慢。但比速度更重要的是可理解性。你明白被接受的答案吗?你能适应其他情况吗?界面可能不太漂亮,但是
np。转置
更快(开销更小)。@hpaulj我从未声称过其他;-)接口可能不是很漂亮,但是
np.transpose
更快(开销更小)。@hpaulj我从来没有说过其他的;-)用生成器表达式代替列表表达式怎么样?这有区别吗?用生成器表达式代替列表理解怎么样?这有区别吗?