2015-11-30 5 views
1

Знаю, что метод fillna() может использоваться для заполнения NaN в полном кадре данных.Заполните NaN средним значением для группы для каждого столбца

df.fillna(df.mean()) # fill with mean of column. 

Как ограничить средний расчет группой (и столбцом), где находится NaN.

Exemple:

import pandas as pd 
import numpy as np 

df = pd.DataFrame({ 
    'a': pd.Series([1,1,1,2,2,2]), 
    'b': pd.Series([1,2,np.NaN,1,np.NaN,4]) 
}) 

print df 

Входной

a b 
0 1 1 
1 1 2 
2 1 NaN 
3 2 1 
4 2 NaN 
5 2 4 

Выход (после того, как GroupBy ('а') & заменить NaN от средней группы)

a b 
0 1 1.0 
1 1 2.0 
2 1 1.5 
3 2 1.0 
4 2 2.5 
5 2 4.0 
+0

Извините, вы спрашиваете конкретно для вывода здесь? – EdChum

+0

Этот результат является всего лишь примером, но, скажем, у вас много NaNs в разных других столбцах b, c, d и т. Д. –

+0

В будущем было бы полезно публиковать ваши полные требования по своему усмотрению, и это влияет на ответы – EdChum

ответ

4

IIUC, то вы можете вызвать fillna с результатом groupby на «а» и transform на «B»:

In [44]: 
df['b'] = df['b'].fillna(df.groupby('a')['b'].transform('mean')) 
df 

Out[44]: 
    a b 
0 1 1.0 
1 1 2.0 
2 1 1.5 
3 2 1.0 
4 2 2.5 
5 2 4.0 

Если у вас есть несколько NaN значения, то я думаю, что должно работать:

In [47]: 
df.fillna(df.groupby('a').transform('mean')) 

Out[47]: 
    a b 
0 1 1.0 
1 1 2.0 
2 1 1.5 
3 2 1.0 
4 2 2.5 
5 2 4.0 

EDIT

In [49]: 
df = pd.DataFrame({ 
    'a': pd.Series([1,1,1,2,2,2]), 
    'b': pd.Series([1,2,np.NaN,1,np.NaN,4]), 
    'c': pd.Series([1,np.NaN,np.NaN,1,np.NaN,4]), 
    'd': pd.Series([np.NaN,np.NaN,np.NaN,1,np.NaN,4]) 
}) 
df 

Out[49]: 
    a b c d 
0 1 1 1 NaN 
1 1 2 NaN NaN 
2 1 NaN NaN NaN 
3 2 1 1 1 
4 2 NaN NaN NaN 
5 2 4 4 4 

In [50]: 
df.fillna(df.groupby('a').transform('mean')) 

Out[50]: 
    a b c d 
0 1 1.0 1.0 NaN 
1 1 2.0 1.0 NaN 
2 1 1.5 1.0 NaN 
3 2 1.0 1.0 1.0 
4 2 2.5 2.5 2.5 
5 2 4.0 4.0 4.0 

Вы получаете Л.Л. NaN для «d», так как все значения NaN для группы 1 для d

+0

Ответ на ваше редактирование - это то, что я ищу. Спасибо. –

0

Вычислим сначала группа означает, игнорируя отсутствующие значения:

group_means = df.groupby('a')['b'].agg(lambda v: np.nanmean(v)) 

Далее мы используем groupby снова, на этот раз Извлечение соответствующие значения:

df_new = df.groupby('a').apply(lambda t: t.fillna(group_means.loc[t['a'].iloc[0]])) 
Смежные вопросы