Замените значения NaN на средства других Cols на основе условия

#python #pandas #dataframe

#питон #pandas #фрейм данных

Вопрос:

У меня есть следующий фрейм данных Pandas

   Col1 Col2  Col3
0    A    c   1.0
1    A    c   3.0
2    B    c   5.0
3    A    d   6.0
4    A    c   NaN
 

Я пишу следующую функцию:

 replace_missing_with_conditional_mean(df, condition_cols, cols)
 

Я хочу заменить отсутствующие значения, присутствующие в столбцах, метками в списке cols .

Значение, подлежащее замене, вычисляется как среднее из не пропущенных значений соответствующей группы. Группы формируются на основе значений в столбцах с метками в списке condition_cols .

Когда replace_missing_with_conditional_mean(df, condition_cols=['Col1','Col2'], cols=['Col3']) применяется к вышеуказанному фрейму данных с аргументами, он должен выдавать:

  Col1 Col2  Col3
0    A    c   1.0
1    A    c   3.0
2    B    c   5.0
3    A    d   6.0
4    A    c   2.0
 

это связано с тем, что запись в строке 4 принадлежит к группе A c , которая имеет среднее значение (1 3)/2 = 2.

Я пробовал использовать df.fillna(df.groupby(condition_cols).transform('mean')) , но это выдает мне ошибку

 TypeError: Transform function invalid for data types
 

Комментарии:

1. О чем df.groupby(condition_cols)['Col3'].transform('mean') ?

2. @DaniMesejo это решило проблему с ошибкой типа, но по какой-то причине она не заполняет значения NaN.

3. Для чего вы ожидаете нескольких столбцов cols=['Col3'] ?

4. @DaniMesejo Функция должна работать для любого количества значений столбцов. Например, если cols = ['Col3','Col4'] функция должна просмотреть conditional_cols и увидеть, что значение NaN в Col3 имеет A c группировку, тогда она должна искать строки с одинаковыми группировками и принимать для них среднее значение в Col3. То же самое должно произойти для Col4, но для Col4 должно быть вычислено среднее значение.

Ответ №1:

Вы могли бы реализовать функцию следующим образом:

 def replace_missing_with_conditional_mean(df, condition_cols, cols):
    s = df.groupby(condition_cols)[cols].transform('mean')
    return df.fillna(s.to_dict('series'))


res = replace_missing_with_conditional_mean(df, ['Col1', 'Col2'], ['Col3'])
print(res)
 

Выходной сигнал

   Col1 Col2  Col3
0    A    c   1.0
1    A    c   3.0
2    B    c   5.0
3    A    d   6.0
4    A    c   2.0
 

Комментарии:

1. Вам не нужно конвертировать s в словарь, fillna так как он также работает с рядами и фреймами данных