Подтвердить что ты не робот

Условное замещение Pandas

Я, наверное, делаю что-то очень глупое, но я в тупике.

У меня есть датафрейм, и я хочу заменить значения в определенном столбце, которые превышают значение на ноль. Я думал, что это был способ достижения этого:

df[df.my_channel > 20000].my_channel = 0

Если я скопирую канал в новый фрейм данных, это будет просто:

df2 = df.my_channel 

df2[df2 > 20000] = 0

это именно то, что я хочу, но, похоже, не работает с каналом как частью исходного кадра данных.

4b9b3361

Ответ 1

.ix индексатор работает нормально для версий панд до 0.20.0, но, поскольку pandas 0.20.0, индексатор .ix устарел, поэтому вам следует избегать его использования. Вместо этого вы можете использовать индексаторы .loc или iloc. Вы можете решить эту проблему:

mask = df.my_channel > 20000
column_name = 'my_channel'
df.loc[mask, column_name] = 0

Или в одну строку

df.loc[df.my_channel > 20000, 'my_channel'] = 0

mask помогает вам выбрать строки, в которых df.my_channel > 20000 имеет значение True, а df.loc[mask, column_name] = 0 устанавливает значение 0 для выбранных строк, где mask содержится в столбце, имя которого равно column_name.

Обновление: в этом случае вы должны использовать loc потому что если вы используете iloc, вы получите NotImplementedError сообщающую, что логическое индексирование на основе iLocation для целочисленного типа недоступно.

Ответ 2

Пытаться

df.loc[df.my_channel > 20000, 'my_channel'] = 0

Примечание. Начиная с версии 0.20.0, ix устарела в пользу loc/iloc.

Ответ 3

Функция np.where работает следующим образом:

df['X'] = np.where(df['Y']>=50, 'yes', 'no')

В вашем случае вы хотели бы:

import numpy as np
df['my_channel'] = np.where(df.my_channel > 20000, 0, df.my_channel)

Ответ 4

Причина, по которой исходный фрейм данных не обновляется, заключается в том, что цепная индексация может привести к изменению копии, а не к просмотру вашего фрейма данных. Документы дают этот совет:

При установке значений в объекте pandas необходимо соблюдать осторожность, чтобы избежать так называемой цепной индексации.

У вас есть несколько альтернатив: -

loc + логическое индексирование

loc может использоваться для установки значений и поддерживает логические маски:

df.loc[df['my_channel'] > 20000, 'my_channel'] = 0

mask + логическое индексирование

Вы можете назначить для вашей серии:

df['my_channel'] = df['my_channel'].mask(df['my_channel'] > 20000, 0)

Или вы можете обновить свою серию на месте:

df['my_channel'].mask(df['my_channel'] > 20000, 0, inplace=True)

np.where + логическое индексирование

Вы можете использовать NumPy, назначив свою оригинальную серию, когда ваше условие не выполнено; однако первые два решения более чистые, поскольку они явно изменяют только указанные значения.

df['my_channel'] = np.where(df['my_channel'] > 20000, 0, df['my_channel'])

Ответ 5

Попробуй это:

df.my_channel = df.my_channel.where(df.my_channel <= 20000, other= 0)

или же

df.my_channel = df.my_channel.mask(df.my_channel > 20000, other= 0)

Ответ 6

Я бы использовал lambda функцию в Series DataFrame следующим образом:

f = lambda x: 0 if x>100 else 1
df['my_column'] = df['my_column'].map(f)

Я не утверждаю, что это эффективный способ, но он прекрасно работает.