2015-08-30 3 views
2

Предположит, что у нас есть test набора данных:Уплотненной IfElse альтернативы панд

value group 
123 1 
120 1 
NA 1 
130 1 
23 2 
22 2 
24 2 
NA 2 

Теперь мы хотим, чтобы заменить недостающие значения с group -wise средних значений. В R мы можем сделать это, используя вложенный вызов ifelse.

first.med <- median(test[test$group == 1, ]$value, na.rm = T) 
second.med <- median(test[test$group == 2, ]$value, na.rm = T) 

test$value <- ifelse(is.na(test$value) & test$group == 1, first.med 
        ifelse(is.na(test$value) & test$group == 2, second.med, 
          test$value)) 

я хотя о применении numpy.where функции или метода pandas.DataFrame.Set.map как демонстрировалось here, но оба метода не поддерживает вложенность. Я могу подумать о понимании списка, но я хочу знать, есть ли альтернатива в области NumPy/pandas. Заранее спасибо.

+1

почему вы должны сделать вложенные if-то еще заявления? например, в r это, как правило, плохая практика, и вы можете просто делать это с помощью (test, ave (value, group, FUN = function (x) {x [is.na (x)] <- медиана (x, na .rm = TRUE); x})) ', который будет работать для n групп – rawr

+0

Вам нужно узнать о [groupby /"Split-Apply-Combine"](http://pandas.pydata.org/pandas-docs/stable /groupby.html). Это очень сильная парадигма. Также намного более чистый код. Ответ на @ chrisb – smci

+0

@rawr Я просто привык к 'ifelse'. Ваш фрагмент выглядит намного лучше. –

ответ

3

В этом случае, вы можете использовать groupby для заполнения групповой медианы:

In [16]: df.groupby('group')['value'].apply(lambda x: x.fillna(x.median())) 
Out[16]: 
0 123 
1 120 
2 123 
3 130 
4  23 
5  22 
6  24 
7  23 
dtype: float64 

Хотя в целом, оба из этих методов может быть вложены только штрафом. Например, вы могли бы сделать:

In [23]: medians = df.groupby('group')['value'].median() 

In [24]: np.where(pd.isnull(df['value']), 
      np.where(df['group'] == 1, medians.loc[1], medians.loc[2]),  
      df['value']) 
Out[24]: array([ 123., 120., 123., 130., 23., 22., 24., 23.]) 
1
df = pd.DataFrame({'value' : [123,120,np.nan ,130,23 ,22 ,24 ,np.nan] , 'group' : [1 , 1 ,1 , 1 , 2 , 2 , 2 , 2] }) 

def replace_with_median(df): 
    df['value'][pd.isnull(df['value'])] = df['value'].median() 
    return df 

df.groupby('group').apply(replace_with_median) 
+0

Я не понимаю, как это известно группе. –

+0

'df.groupby ('group'). Apply (replace_with_median)' здесь он сгруппирован по столбцу группы –

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