应用相同形状的蒙版时 Numpy 数组丢失尺寸
Numpy array losing dimensions when applying mask of same shape
我创建了一个名为 mask
的 2D 蒙版,其形状与数组 data
相同,我想将其应用于数组。但是,当我这样做时,数据会失去它的形状并变成一维的。
我认为,由于轴 0 的每个级别都是相同的(显示为使用循环理解创建 mask
),因此输出将产生形状为 (837, 10)
的输出
我想知道是否有任何 numpy 技巧可用于在不使用 reshape 的情况下实现此目标?
>>> data.shape
(837, 44)
>>> m = altitudes < 50000
>>> m.shape
(44,)
>>> np.sum(m) # calculates my expected dimension for axis 1
10
>>> mask = [m for i in range(data.shape[0])]
>>> mask.shape
(837, 44)
>>> new_data = data[mask]
>>> new_data.shape
(8370,) # same as 837 * 10 (dimension wanted)
如果这不能实现,为什么会这样?
相信你想做的事,打电话new_data.reshape(837, -1)
就可以完成。这是一个简短的例子:
arr = np.arange(8*6).reshape(8,6)
maskpiece = np.array([True, False]*3)
mask = np.broadcast_to(maskpiece, (8,6))
print('the original array\n%s\n' % arr)
print('the flat masked array\n%s\n' % arr[mask])
print('the masked array reshaped into 2D\n%s\n' % arr[mask].reshape(8, -1))
输出:
the original 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 40 41]
[42 43 44 45 46 47]]
the flat masked array
[ 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46]
the masked array reshaped into 2D
[[ 0 2 4]
[ 6 8 10]
[12 14 16]
[18 20 22]
[24 26 28]
[30 32 34]
[36 38 40]
[42 44 46]]
实现目标的 'correct' 方法是不将蒙版扩展为二维。而是使用 [:, mask]
和 1D 掩码进行索引。这向 numpy 表明您希望轴 0 不变并且 mask
沿轴 1 应用。
a = np.arange(12).reshape(3, 4)
b = np.array((1,0,1,0),'?')
a
# array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11]])
b
# array([ True, False, True, False])
a[:, b]
# array([[ 0, 2],
# [ 4, 6],
# [ 8, 10]])
如果您的 mask
已经是二维的,numpy 将不会检查其所有行是否相同,因为那样效率很低。但显然你可以在这种情况下使用 [:, mask[0]]
。
如果您的 mask
是二维的,并且恰好每行中的 True
数量相同,那么要么使用@tel 的答案。或者创建索引数组:
B = b^b[:3, None]
B
# array([[False, True, False, True],
# [ True, False, True, False],
# [False, True, False, True]])
J = np.where(B)[1].reshape(len(B), -1)
现在要么
np.take_along_axis(a, J, 1)
# array([[ 1, 3],
# [ 4, 6],
# [ 9, 11]])
或
I = np.arange(len(J))[:, None]
IJ = I, J
a[IJ]
# #array([[ 1, 3],
# [ 4, 6],
# [ 9, 11]])
我创建了一个名为 mask
的 2D 蒙版,其形状与数组 data
相同,我想将其应用于数组。但是,当我这样做时,数据会失去它的形状并变成一维的。
我认为,由于轴 0 的每个级别都是相同的(显示为使用循环理解创建 mask
),因此输出将产生形状为 (837, 10)
我想知道是否有任何 numpy 技巧可用于在不使用 reshape 的情况下实现此目标?
>>> data.shape
(837, 44)
>>> m = altitudes < 50000
>>> m.shape
(44,)
>>> np.sum(m) # calculates my expected dimension for axis 1
10
>>> mask = [m for i in range(data.shape[0])]
>>> mask.shape
(837, 44)
>>> new_data = data[mask]
>>> new_data.shape
(8370,) # same as 837 * 10 (dimension wanted)
如果这不能实现,为什么会这样?
相信你想做的事,打电话new_data.reshape(837, -1)
就可以完成。这是一个简短的例子:
arr = np.arange(8*6).reshape(8,6)
maskpiece = np.array([True, False]*3)
mask = np.broadcast_to(maskpiece, (8,6))
print('the original array\n%s\n' % arr)
print('the flat masked array\n%s\n' % arr[mask])
print('the masked array reshaped into 2D\n%s\n' % arr[mask].reshape(8, -1))
输出:
the original 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 40 41]
[42 43 44 45 46 47]]
the flat masked array
[ 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46]
the masked array reshaped into 2D
[[ 0 2 4]
[ 6 8 10]
[12 14 16]
[18 20 22]
[24 26 28]
[30 32 34]
[36 38 40]
[42 44 46]]
实现目标的 'correct' 方法是不将蒙版扩展为二维。而是使用 [:, mask]
和 1D 掩码进行索引。这向 numpy 表明您希望轴 0 不变并且 mask
沿轴 1 应用。
a = np.arange(12).reshape(3, 4)
b = np.array((1,0,1,0),'?')
a
# array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11]])
b
# array([ True, False, True, False])
a[:, b]
# array([[ 0, 2],
# [ 4, 6],
# [ 8, 10]])
如果您的 mask
已经是二维的,numpy 将不会检查其所有行是否相同,因为那样效率很低。但显然你可以在这种情况下使用 [:, mask[0]]
。
如果您的 mask
是二维的,并且恰好每行中的 True
数量相同,那么要么使用@tel 的答案。或者创建索引数组:
B = b^b[:3, None]
B
# array([[False, True, False, True],
# [ True, False, True, False],
# [False, True, False, True]])
J = np.where(B)[1].reshape(len(B), -1)
现在要么
np.take_along_axis(a, J, 1)
# array([[ 1, 3],
# [ 4, 6],
# [ 9, 11]])
或
I = np.arange(len(J))[:, None]
IJ = I, J
a[IJ]
# #array([[ 1, 3],
# [ 4, 6],
# [ 9, 11]])