我可以用掩码拆分 numpy 数组吗?
can I split numpy array with mask?
我想将数组拆分为带有掩码和索引的数组
如下所示
a = array([ 0, 1, 2, 3, 4, 5]))
b = [0,2,3]
进入
c = array([[0, 2, 3], [1, 3, 4], [2, 4, 5]])
我可以不用循环吗?
编辑:
更多示例...
说,我们有一个数组 a
,形状为 [10, 10, 10]
其中 a[x, y, :] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
现在给定面具b = [0, 3, 7]
我希望输出为一个数组 c
,形状为 [10, 10, 3, 3]
其中 c[x, y, :, :] = [[0, 3, 7], [1, 4, 8], [2, 5, 9]]
您可以生成 b
作为所需索引和移位向量之间的广播总和。然后你可以再次广播到更大的尺寸。由于您示例中的输出不依赖于 a
数组,因此我忽略了这一点。
from numpy import array, broadcast_to, arange
from numpy.random import random
a = random((10,10,10)) # not used on the code at all.... don't understand what it is for...
b = [0,2,3]
b_array = array(b)
b_shifts = arange(3).reshape(-1,1)
c_cell= b+b_shifts # here, they are broadcasted toegether. one is a row-vector and one is a column-vector...
c = broadcast_to(c_cell,(10,10,3,3))
您可能想根据步长等使用其他方法创建 b_shifts
...
编辑
根据您的评论,似乎更准确的答案是:
from numpy import array, arange
a = arange(2*2*10).reshape((2,2,10)) # some example input
b = array([0,2,3]) # the 'template' to extract
shifts = arange(3).reshape(-1,1) # 3 is the number of repeats
indexer = b+shifts # broadcasted sum makes a matrix
c = a[:,:,indexer] # extract
这会将b
数组作为一种模板,并以一定的移位重复。最后,它将从每个数组 a[i,j,:]
中提取这些条目到 c[i,j,:,:]
中。上面的输出是:
print(a)
[[[ 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 36 37 38 39]]]
print(c)
[[[[ 0 2 3]
[ 1 3 4]
[ 2 4 5]]
[[10 12 13]
[11 13 14]
[12 14 15]]]
[[[20 22 23]
[21 23 24]
[22 24 25]]
[[30 32 33]
[31 33 34]
[32 34 35]]]]
移动windows方法使用as_strided
:
In [1]: a = np.arange(6)
In [2]: a
Out[2]: array([0, 1, 2, 3, 4, 5])
In [3]: as_strided = np.lib.stride_tricks.as_strided
对于这个一班,strides
参数很简单。 shape
需要更多思考——我们期望多少行,以及最大索引:
In [5]: b = as_strided(a, shape=(3,4), strides=(8,8))
In [6]: b
Out[6]:
array([[0, 1, 2, 3],
[1, 2, 3, 4],
[2, 3, 4, 5]])
然后 select 列:
In [8]: b[:,[0,2,3]]
Out[8]:
array([[0, 2, 3],
[1, 3, 4],
[2, 4, 5]])
为了将其扩展到 3d 情况,我将从 、LudvigH 的回答
开始
In [10]: a = np.arange(2*2*10).reshape((2,2,10)) # some example input
...: b = np.array([0,2,3])
In [11]: a
Out[11]:
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, 36, 37, 38, 39]]])
In [12]: a.shape
Out[12]: (2, 2, 10)
In [13]: a.strides
Out[13]: (160, 80, 8)
In [18]: a1 = as_strided(a, shape=(2,2,3,4), strides=(160,80,8,8))
In [19]: a1
Out[19]:
array([[[[ 0, 1, 2, 3],
[ 1, 2, 3, 4],
[ 2, 3, 4, 5]],
[[10, 11, 12, 13],
[11, 12, 13, 14],
[12, 13, 14, 15]]],
[[[20, 21, 22, 23],
[21, 22, 23, 24],
[22, 23, 24, 25]],
[[30, 31, 32, 33],
[31, 32, 33, 34],
[32, 33, 34, 35]]]])
这只是第一种情况的延伸,前两个维度只是顺带一提。这是扩展到 2d window.
的最后一个维度
再次 select 列的子集:
In [20]: a1[:,:,:,b]
Out[20]:
array([[[[ 0, 2, 3],
[ 1, 3, 4],
[ 2, 4, 5]],
[[10, 12, 13],
[11, 13, 14],
[12, 14, 15]]],
[[[20, 22, 23],
[21, 23, 24],
[22, 24, 25]],
[[30, 32, 33],
[31, 33, 34],
[32, 34, 35]]]])
as_strided
步骤很有效,创建了 view
。但是索引会制作一个副本。我们必须做一些计时来根据 LudvigH 的移位索引方法对其进行测试。
我想将数组拆分为带有掩码和索引的数组
如下所示
a = array([ 0, 1, 2, 3, 4, 5]))
b = [0,2,3]
进入
c = array([[0, 2, 3], [1, 3, 4], [2, 4, 5]])
我可以不用循环吗?
编辑:
更多示例...
说,我们有一个数组 a
,形状为 [10, 10, 10]
其中 a[x, y, :] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
现在给定面具b = [0, 3, 7]
我希望输出为一个数组 c
,形状为 [10, 10, 3, 3]
其中 c[x, y, :, :] = [[0, 3, 7], [1, 4, 8], [2, 5, 9]]
您可以生成 b
作为所需索引和移位向量之间的广播总和。然后你可以再次广播到更大的尺寸。由于您示例中的输出不依赖于 a
数组,因此我忽略了这一点。
from numpy import array, broadcast_to, arange
from numpy.random import random
a = random((10,10,10)) # not used on the code at all.... don't understand what it is for...
b = [0,2,3]
b_array = array(b)
b_shifts = arange(3).reshape(-1,1)
c_cell= b+b_shifts # here, they are broadcasted toegether. one is a row-vector and one is a column-vector...
c = broadcast_to(c_cell,(10,10,3,3))
您可能想根据步长等使用其他方法创建 b_shifts
...
编辑 根据您的评论,似乎更准确的答案是:
from numpy import array, arange
a = arange(2*2*10).reshape((2,2,10)) # some example input
b = array([0,2,3]) # the 'template' to extract
shifts = arange(3).reshape(-1,1) # 3 is the number of repeats
indexer = b+shifts # broadcasted sum makes a matrix
c = a[:,:,indexer] # extract
这会将b
数组作为一种模板,并以一定的移位重复。最后,它将从每个数组 a[i,j,:]
中提取这些条目到 c[i,j,:,:]
中。上面的输出是:
print(a)
[[[ 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 36 37 38 39]]]
print(c)
[[[[ 0 2 3]
[ 1 3 4]
[ 2 4 5]]
[[10 12 13]
[11 13 14]
[12 14 15]]]
[[[20 22 23]
[21 23 24]
[22 24 25]]
[[30 32 33]
[31 33 34]
[32 34 35]]]]
移动windows方法使用as_strided
:
In [1]: a = np.arange(6)
In [2]: a
Out[2]: array([0, 1, 2, 3, 4, 5])
In [3]: as_strided = np.lib.stride_tricks.as_strided
对于这个一班,strides
参数很简单。 shape
需要更多思考——我们期望多少行,以及最大索引:
In [5]: b = as_strided(a, shape=(3,4), strides=(8,8))
In [6]: b
Out[6]:
array([[0, 1, 2, 3],
[1, 2, 3, 4],
[2, 3, 4, 5]])
然后 select 列:
In [8]: b[:,[0,2,3]]
Out[8]:
array([[0, 2, 3],
[1, 3, 4],
[2, 4, 5]])
为了将其扩展到 3d 情况,我将从
In [10]: a = np.arange(2*2*10).reshape((2,2,10)) # some example input
...: b = np.array([0,2,3])
In [11]: a
Out[11]:
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, 36, 37, 38, 39]]])
In [12]: a.shape
Out[12]: (2, 2, 10)
In [13]: a.strides
Out[13]: (160, 80, 8)
In [18]: a1 = as_strided(a, shape=(2,2,3,4), strides=(160,80,8,8))
In [19]: a1
Out[19]:
array([[[[ 0, 1, 2, 3],
[ 1, 2, 3, 4],
[ 2, 3, 4, 5]],
[[10, 11, 12, 13],
[11, 12, 13, 14],
[12, 13, 14, 15]]],
[[[20, 21, 22, 23],
[21, 22, 23, 24],
[22, 23, 24, 25]],
[[30, 31, 32, 33],
[31, 32, 33, 34],
[32, 33, 34, 35]]]])
这只是第一种情况的延伸,前两个维度只是顺带一提。这是扩展到 2d window.
的最后一个维度再次 select 列的子集:
In [20]: a1[:,:,:,b]
Out[20]:
array([[[[ 0, 2, 3],
[ 1, 3, 4],
[ 2, 4, 5]],
[[10, 12, 13],
[11, 13, 14],
[12, 14, 15]]],
[[[20, 22, 23],
[21, 23, 24],
[22, 24, 25]],
[[30, 32, 33],
[31, 33, 34],
[32, 34, 35]]]])
as_strided
步骤很有效,创建了 view
。但是索引会制作一个副本。我们必须做一些计时来根据 LudvigH 的移位索引方法对其进行测试。