【问题标题】:Numpy array losing dimensions when applying mask of same shape应用相同形状的掩码时 Numpy 数组丢失尺寸
【发布时间】:2019-05-18 10:56:12
【问题描述】:

我创建了一个适当命名为 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)

如果这不能实现,为什么会这样?

【问题讨论】:

  • 我凭直觉就预料到了同样的事情——我觉得奇怪的是它不能那样工作!

标签: python arrays numpy masking numpy-ndarray


【解决方案1】:

我相信您可以通过致电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]]

【讨论】:

  • 是的,这对很多人都有帮助!我不认为 -1 的行为类似于通配符值。
【解决方案2】:

实现目标的“正确”方法是不要将蒙版扩展到 2D。而是使用带有 1D 掩码的 [:, mask] 进行索引。这向 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 是 2D 并且恰好在每行中具有相同数量的 Trues,那么请使用 @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]])

【讨论】:

  • 完美!我没有意识到您可以在各个轴上应用蒙版。不过有道理。干杯@Paul-Panzer
  • 我不明白关于@tel 解决方案危险的评论。请问你能扩展('scuse pun)吗? arr.reshape(dim0,-1) 安全吗?
猜你喜欢
  • 2020-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-26
  • 1970-01-01
相关资源
最近更新 更多