2017-02-14 1 views
2

Можно ли мутировать DataFrame inplace с заявлением groupby?Преобразование на месте панды с группой

import pandas as pd 
dt = pd.DataFrame({ 
        "LETTER": ["a", "b", "c", "a", "b"], 
        "VALUE" : [10 , 12 , 13, 0, 15] 
        }) 
def __add_new_col(dt_): 
    dt_['NEW_COL'] = dt_['VALUE'] - dt_['VALUE'].mean() 
    return dt_ 
pass 


dt.groupby("LETTER").apply(__add_new_col) 
    LETTER VALUE NEW_COL 
0  a  10  5.0 
1  b  12  -1.5 
2  c  13  0.0 
3  a  0  -5.0 
4  b  15  1.5 


dt 
    LETTER VALUE 
0  a  10 
1  b  12 
2  c  13 
3  a  0 
4  b  15 

В R data.table можно с помощью оператора, например, :=dt[, col := ... , by ='LETTER']

+1

Почему не 'ДФ [ 'NEWCOL'] = dt.groupby ('Письмо') [ 'VALUE '] .apply (lambda x: x - x.mean()) '? – Zero

+0

@JohnGalt Есть ли гарантия заказа? –

+0

Да, вы тоже можете это проверить. – Zero

ответ

1

Я думаю, что вы можете использовать transform, которые возвращают Series одинаковую длину и тот же индекс, как df с вычитанием:

print (dt.groupby("LETTER")['VALUE'].transform('mean')) 
0  5.0 
1 13.5 
2 13.0 
3  5.0 
4 13.5 
Name: VALUE, dtype: float64 

dt['NEW_COL'] = dt['VALUE'] - dt.groupby("LETTER")['VALUE'].transform('mean') 
print (dt) 
    LETTER VALUE NEW_COL 
0  a  10  5.0 
1  b  12  -1.5 
2  c  13  0.0 
3  a  0  -5.0 
4  b  15  1.5 
1

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

df['NEW_COL'] = df['VALUE'] - df['LETTER'].map(dt.groupby("LETTER")['VALUE'].mean()).values 

Это будет касаться любой возможной проблемы с заказом, которую я бы не стал бы гарантировать, даже если она будет проверена. Лучше перестраховаться, чем жаль :)

Кроме того, я использую .values ​​ аксессора после карты, потому что я не уверен, что индекс «отображенной» серии будет таким же серии «VALUE», который когда-нибудь будет результатом NaN.

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