Размеры кускового массива теряются при применении маски одинаковой формы - PullRequest
0 голосов
/ 18 декабря 2018

Я создал 2D-маску с соответствующим именем mask, которая будет иметь ту же форму, что и массив data, массив, к которому я хочу применить ее.Однако, когда я делаю это, данные теряют свою форму и становятся 1D.

Я думал, что, поскольку каждый уровень для оси 0 идентичен (показано с созданием mask с использованием понимания цикла), что вывод будет производить выводс формой (837, 10)

Мне интересно, есть ли какие-нибудь хитрые уловки, которые можно использовать для достижения этой цели без использования изменения формы?

>>> 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)

Если это невозможно, зачем этобыть?

ура

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

«Правильный» способ достижения вашей цели - не расширять маску до 2D.Вместо этого индексируйте с [:, 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 уже 2D, 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]])
0 голосов
/ 18 декабря 2018

Я верю, что вы можете сделать, позвонив по номеру 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]]
...