#python #arrays #numpy
Вопрос:
Допустим, у меня есть массив данных numpy длиной N и массив битовых масок длиной N.
data = [1,2,3,4,5,6,7,8,9,0]
mask = [0,1,0,1,0,1,0,1,0,1]
Существует ли безцикловый способ создания нового массива на основе данных, такой, чтобы он принимал все записи данных тогда и только тогда, когда маски[i] != 0? Вот так:
func(data, mask) = [2,4,6,8,0]
Или, что эквивалентно, в циклической нотации:
ans = []
for idx in range(mask):
if mask[idx]:
ans.append(data[idx])
ans = numpy.array(ans)
Спасибо!
Комментарии:
1. Ваш вопрос еще проще, чем связанный дубликат, поскольку вы работаете только в одном измерении. необходимый код… подождите его…
data[mask != 0]
. И да, такого рода упрощение является одним из основных преимуществ Numpy. Конечно, вам нужно начинать с массивов Numpy, а не с простых списков Python.2. Вы должны проверить: numpy doc с решением . В вашем случае просто сделайте:
np.ma.array(data, mask=mask).data
(измените список на массивы раньше).3. @Memristor когда я пытаюсь
np.ma.array(data, mask=mask).data
, я просто получаю исходный массив. На самом деле не совсем ясно, как ссылку, которую вы разместили, можно использовать для получения результатов, которые хочет получить ОП.4. Да, похоже
.data
, это дает вам исходный массив..tolist()
дает вам замаскированный список, но не удаляет замаскированные значения. Они всегда заполненыfill_value
(либоNone
или пользовательским значением).5. @MarkM извините, вы должны получить результат
x = np.ma.array(...)
, а затемx[~x.mask].data
он удаляет элементы с маской 0; Другой способ заключается в использованииwhere
:np.where([1, 0, 1, 0, 1], [1, 2, 3, 4, 5], 0)
это не удаляет их, а заменяет 0.
Ответ №1:
Вы можете фильтровать массивы numpy с помощью массива логических значений. Вы начинаете с массива целых чисел, которые вы не можете использовать напрямую, но вы, конечно, можете интерпретировать единицы и нули как логические значения, а затем использовать их непосредственно в качестве маски:
import numpy as np
data = np.array([1,2,3,4,5,6,7,8,9,0])
mask = np.array([0,1,0,1,0,1,0,1,0,1])
data[mask.astype(bool)]
# array([2, 4, 6, 8, 0])