Nic*_*nov 7 python split numpy matrix
将 NumPy 矩阵(二维数组)垂直和水平拆分为相等块的最pythonic 方法是什么?
例如 :
aa = np.reshape(np.arange(270),(18,15)) # a 18x15 matrix
Run Code Online (Sandbox Code Playgroud)
然后是一个“功能”,比如
ab = np.split2d(aa,(2,3))
Run Code Online (Sandbox Code Playgroud)
将产生一个由 6 个矩阵组成的列表,每个矩阵形状为 (9,5)。第一个猜测是结合 hsplit、map 和 vsplit,但是如果要为其定义两个参数,则必须如何应用 mar,例如:
map(np.vsplit(@,3),np.hsplit(aa,2))
Run Code Online (Sandbox Code Playgroud)
这是留在 NumPy 环境中的一种方法 -
def view_as_blocks(arr, BSZ):
# arr is input array, BSZ is block-size
m,n = arr.shape
M,N = BSZ
return arr.reshape(m//M, M, n//N, N).swapaxes(1,2).reshape(-1,M,N)
Run Code Online (Sandbox Code Playgroud)
样品运行
1)验证形状的实际大案例:
In [41]: aa = np.reshape(np.arange(270),(18,15))
In [42]: view_as_blocks(aa, (9,5)).shape
Out[42]: (6, 9, 5)
Run Code Online (Sandbox Code Playgroud)
2)手动验证值的小案例:
In [43]: aa = np.reshape(np.arange(36),(6,6))
In [44]: aa
Out[44]:
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23],
[24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35]])
In [45]: view_as_blocks(aa, (2,3)) # Blocks of shape (2,3)
Out[45]:
array([[[ 0, 1, 2],
[ 6, 7, 8]],
[[ 3, 4, 5],
[ 9, 10, 11]],
[[12, 13, 14],
[18, 19, 20]],
[[15, 16, 17],
[21, 22, 23]],
[[24, 25, 26],
[30, 31, 32]],
[[27, 28, 29],
[33, 34, 35]]])
Run Code Online (Sandbox Code Playgroud)
如果您愿意与其他图书馆合作,scikit-image可以在这里使用,就像这样 -
from skimage.util import view_as_blocks as viewB
out = viewB(aa, tuple(BSZ)).reshape(-1,*BSZ)
Run Code Online (Sandbox Code Playgroud)
运行时测试 -
In [103]: aa = np.reshape(np.arange(270),(18,15))
# @EFT's soln
In [99]: %timeit split_2d(aa, (2,3))
10000 loops, best of 3: 23.3 µs per loop
# @glegoux's soln-1
In [100]: %timeit list(get_chunks(aa, 2,3))
100000 loops, best of 3: 3.7 µs per loop
# @glegoux's soln-2
In [111]: %timeit list(get_chunks2(aa, 9, 5))
100000 loops, best of 3: 3.39 µs per loop
# Proposed in this post
In [101]: %timeit view_as_blocks(aa, (9,5))
1000000 loops, best of 3: 1.86 µs per loop
Run Code Online (Sandbox Code Playgroud)
请注意,我已经使用了(2,3)forsplit_2d并且get_chunks根据他们的定义,他们将其用作块数。在我的情况下view_as_blocks,我有BSZ指示块大小的参数。所以,我(9,5)有。get_chunks2遵循相同的格式view_as_blocks。输出应该在那里表示相同。
您可以使用np.split& np.concatenate,后者允许在一个步骤中进行第二次分割:
def split_2d(array, splits):
x, y = splits
return np.split(np.concatenate(np.split(array, y, axis=1)), x*y)
ab = split_2d(aa,(2,3))
ab[0].shape
Out[95]: (9, 5)
len(ab)
Out[96]: 6
Run Code Online (Sandbox Code Playgroud)
这似乎也应该相对简单地推广到 n 维的情况,尽管我还没有完全遵循这个想法。
编辑:
对于单个数组作为输出,只需添加np.stack:
np.stack(ab).shape
Out[99]: (6, 9, 5)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2846 次 |
| 最近记录: |