Заменить значения в массиве, используя маску и другой массив - PullRequest
0 голосов
/ 01 сентября 2018

У меня есть 1D "from" -array (назовите его " frm " ), содержащий значения со связанным массивом логических масок: " mask" (той же формы, что и от ). Затем у меня есть третий массив «replace»: " repl " , также 1D, но короче по длине, чем два других.

С их помощью я хотел бы создать новый массив ( " до " ), который содержит значения frm за исключением , где mask == True , в этом случае должно быть по порядку значения от repl . (Обратите внимание, что количество True элементов в mask равно длине repl ).

Я искал "умный" тупой способ реализации этого? Я посмотрел на такие методы, как np.where , np.take , np.select , np.choose , но ни один из них не подходит счет "?

«Обрезка по коду», вот что у меня есть до сих пор. Это работает нормально, но не кажется "Numpythonic"? (или даже Pythonic в этом отношении)

frm  = [1, 2, 3, 4, 5]
mask = [False, True, False, True, True]
repl = [200, 400, 500]
i = 0; to = []
for f,m in zip(frm,mask):
    if m:
        to.append(repl[i])
        i += 1
    else:
        to.append(f)
print(to)

Выход: [1, 200, 3, 400, 500]

( Справочная информация : причина, по которой мне нужно это сделать, заключается в том, что я создаю подклассы класса Pandas pd.Dataframe и мне нужен "установщик" для столбцов / индексов. Как pd.Index не может быть "индексирован по частям". Мне нужно сначала скопировать массив индекса / столбца, заменить некоторые элементы в копии на основе маски, а затем установить setter , чтобы установить Совершенно новое значение. Дайте мне знать, если кто-нибудь узнает более элегантное решение для этого).

1 Ответ

0 голосов
/ 01 сентября 2018

numpy решение:

Это довольно просто, как это:

# convert frm to a numpy array:
frm = np.array(frm)
# create a copy of frm so you don't modify original array:
to = frm.copy()

# mask to, and insert your replacement values:
to[mask] = repl

Затем to возвращает:

>>> to
array([  1, 200,   3, 400, 500])

pandas решение:

если ваш фрейм данных выглядит так:

>>> df
   column
0       1
1       2
2       3
3       4
4       5

Тогда вы можете использовать loc:

df.loc[mask,'column'] = repl

Тогда ваш фрейм данных выглядит так:

>>> df
   column
0       1
1     200
2       3
3     400
4     500
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...