2014-02-06 7 views
36

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

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

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

Если скопировать канал в новый фрейм данных это просто:

df2 = df.my_channel 

df2[df2 > 20000] = 0 

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

Спасибо заранее.

Бен

+0

Найдено, что я думаю, что вы искали [здесь] (http://stackoverflow.com/q/37841525/2662901). – feetwet

ответ

49

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

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

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

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

+7

Ответ lmiguelvargasf должен быть помечен как правильный, учитывая недавние изменения в пандах. – ramhiser

+1

Можете ли вы использовать 'iloc 'с такой маской? Кажется, это не работает для меня (хотя 'loc' отлично работает).Если 'iloc' не работает в этом случае, возможно, стоит уточнить, что' loc' должен заменить 'ix' для решения этой проблемы, а в других ситуациях может быть заменен на' iloc'? – LangeHaare

+2

@ LangeHaare, я просто попробовал то, что вы сказали, и вы правы, это не работает для 'iloc'. Я обновлю свой ответ, чтобы решить эту проблему. Большое вам спасибо за то, что сообщили мне. – lmiguelvargasf

56

Попробуйте

df.ix[df.my_channel > 20000, 'my_channel'] = 0 
+6

Спасибо. Я тоже нашел свое решение: df.my_channel [df.my_channel> 20000] = 0 – BMichell

+1

@BMichell Я думаю, что ваше решение может начать давать вам предупреждения в 0,13, не было возможности попробовать еще – lowtech

+0

Ошибка выхода: /opt/anaconda3/envs/python35/lib/python3.5/site-packages/ipykernel_launcher.py:1: SettingWithCopy Предупреждение: Значение, которое нужно установить на копии фрагмента из DataFrame См. предостережения в документация: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy «« Точка входа для запуска ядра IPython. –

0

Я лично, как с помощью функции 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)

+0

Мне нравится np.where тоже только "." необходимо удалить из инструкции. так и должно быть. df ['my_channel'] = np.where (df.my_channel> 20000, 0, df.my_channel) –

Смежные вопросы