2013-05-22 3 views
3

У меня есть кадр данных pandas, и я хочу создать новый столбец, который вычисляется по-разному для разных групп строк. Вот краткий пример:Присвоить выбор в pandas

import pandas as pd 

data = {'foo': list('aaade'), 'bar': range(5)} 
df = pd.DataFrame(data) 

dataframe выглядит следующим образом:

 bar foo 
0 0 a 
1 1 a 
2 2 a 
3 3 d 
4 4 e 

Теперь я добавляю новую колонку и попытаться присвоить некоторые значения для выбранных строк:

df['xyz'] = 0 
df.loc[(df['foo'] == 'a'), 'xyz'] = df.loc[(df['foo'] == 'a')].apply(lambda x: x['bar'] * 2, axis=1) 

Блок данных не изменился. То, что я бы ожидать, это dataframe выглядеть следующим образом:

 bar foo xyz 
0 0 a 0 
1 1 a 2 
2 2 a 4 
3 3 d 0 
4 4 e 0 

В моей реальной проблеме, колонка «хуг» также computated для других строк, но используя другую функцию. На самом деле, я также использую разные столбцы для вычисления. So мои вопросы:

  1. Почему назначение в приведенном выше примере не работает?
  2. Обязательно ли делать df.loc[(df['foo'] == 'a') дважды (как я это делаю сейчас)?

ответ

3

Вы меняете копию df (булевская маска DataFrame является копией, см. docs).
Другой способ достижения желаемого результата заключается в следующем:

In [11]: df.apply(lambda row: (row['bar']*2 if row['foo'] == 'a' else row['xyz']), axis=1) 
Out[11]: 
0 0 
1 2 
2 4 
3 0 
4 0 
dtype: int64 

In [12]: df['xyz'] = df.apply(lambda row: (row['bar']*2 if row['foo'] == 'a' else row['xyz']), axis=1) 

In [13]: df 
Out[13]: 
    bar foo xyz 
0 0 a 0 
1 1 a 2 
2 2 a 4 
3 3 d 0 
4 4 e 0 

Возможно аккуратнее способ это просто:

In [21]: 2 * (df1.bar) * (df1.foo == 'a') 
Out[21]: 
0 0 
1 2 
2 4 
3 0 
4 0 
dtype: int64 
+0

Да, Джефф, писать что-то больше к документации на моем списке дел. :) –

+0

и я даже не прокомментировал :) – Jeff

+0

благодарит за ваш быстрый ответ. Это делает именно то, что я хочу. Можно ли связать эти, если еще звонки? – uuazed

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