假设我们有一些3维的numpy数组A
,其形状为(X, Y, Z)
。我想创建一个新数组B
,它也将具有形状(X, Y, Z)
。
我们希望:n
的第n个切片(B
)沿第零个轴对应于::m
的第m个切片(A
)沿第零轴。
我们还希望n:2*n
的切片B
对应于m+1
的每个第1::m
个切片(A
)。对于数组的其余部分,依此类推。
使用向量化numpy计算来实现此目标的最佳方法是什么?
通过一个示例可以最好地理解上述陈述。因此,让我们开始设置一些示例数组A
:
import numpy as np
# Create array A with shape (15, 3, 3)
n = 3; m = 5
a = np.array([i * np.eye(3) for i in range(1, 1+m)])
A = np.tile(a, (n, 1, 1))
如果我们看一下A
的第零个切片,就会发现:
print(A[0])
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
print(A[1])
[[2. 0. 0.]
[0. 2. 0.]
[0. 0. 2.]]
...
print(A[4])
[[5. 0. 0.]
[0. 5. 0.]
[0. 0. 5.]]
print(A[5])
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
以此类推。
A
中的值并不重要,但应有助于说明原始语句。
我想知道我们是否只能使用numpy函数创建矩阵B
。数组B
应该具有切片:
print(B[0])
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
print(B[1])
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
print(B[2])
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
print(B[3])
[[2. 0. 0.]
[0. 2. 0.]
[0. 0. 2.]]
以此类推。
有什么方法可以通过纯粹的numpy解决方案从B
生成A
?
以下内容根据需要提供B
,但是随着m
变大,它变得很乏味:
# vstack solution
B = np.vstack((A[::m], A[1::m], A[2::m], A[3::m], A[4::m]))
使用列表推导也可以,但是我想避免使用循环:
# List comprehension solution
B = np.vstack([A[i::m] for i in range(m)])
答案 0 :(得分:1)
我认为这可以满足您的要求
import numpy as np
# Create array A with shape (15, 3, 3)
a = np.array([i * np.eye(3) for i in range(1, 6)])
A = np.tile(a, (3, 1, 1))
B = np.swapaxes(A.reshape(3, 5, 3, 3), 0, 1)
B = B.reshape(-1, 3, 3)
print(B)
# [[[1. 0. 0.]
# [0. 1. 0.]
# [0. 0. 1.]]
#
# [[1. 0. 0.]
# [0. 1. 0.]
# [0. 0. 1.]]
#
# [[1. 0. 0.]
# [0. 1. 0.]
# [0. 0. 1.]]
#
# [[2. 0. 0.]
# [0. 2. 0.]
# [0. 0. 2.]]
# ...
答案 1 :(得分:1)
据我了解,也许您可以只使用numpy.sort
:
B = np.sort(A, axis = 0)
答案 2 :(得分:1)
设置
n = 3; m = 5
a = np.array([i * np.eye(n) for i in range(1, 1+m)])
代替tile
,沿轴0使用np.repeat
,并使用Fortran样式排序进行整形。
np.repeat(a, n, 0).reshape(m*n, n, n, order='F')
array([[[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]],
[[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]],
[[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]],
[[2., 0., 0.],
[0., 2., 0.],
[0., 0., 2.]],
...
[[5., 0., 0.],
[0., 5., 0.],
[0., 0., 5.]]])
验证
# your approach
A = np.tile(a, (n, 1, 1))
B = np.vstack((A[::m], A[1::m], A[2::m], A[3::m], A[4::m]))
# my approach
usr_B = np.repeat(a, n, 0).reshape(m*n, n, n, order='F')
>>> np.array_equal(B, usr_B)
True
时间
%%timeit
A = np.tile(a, (n, 1, 1))
B = np.vstack((A[::m], A[1::m], A[2::m], A[3::m], A[4::m]))
19 µs ± 57.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%%timeit
A = np.tile(a, (3, 1, 1))
B = np.swapaxes(A.reshape(3, 5, 3, 3), 0, 1)
B = B.reshape(-1, 3, 3)
11 µs ± 74.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit np.repeat(a, n, 0).reshape(m*n, n, n, order='F')
2.68 µs ± 21.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)