Как пересылать значения заполнения и возвращать значения заполнения, если запись в столбце равна нулю (в виде плавающей точки) во фрейме данных pandas?

#python #pandas #dataframe #pandas-groupby #fillna

Вопрос:

У меня есть фрейм данных, в котором вес каждого клиента не очень хорошо сохраняется, что приводит к:

ИДЕНТИФИКАТОР КЛИЕНТА ДАТА ВСТРЕЧИ ВЕС_КГ
16081 2018-12-17 70.0
16081 2019-03-19 0.0
16081 2019-04-18 0.0
16081 2019-06-07 0.0
20011 2020-02-27 0.0
20011 2020-03-27 0.0
20011 2020-04-27 57.0
20011 2020-06-07 0.0
20011 2020-07-07 60.0
20020 2020-01-01 0.0

Таблица отсортирована по CLIENT_ID и DATE_ENCOUNTER . Как я могу заменить значения для каждого CLIENT_ID места WEIGHT_KG = 0.0 , сначала заполнив записи вперед, а затем заполнив их обратно? (В зависимости от записей для каждой CLIENT_ID из них это приведет к кадру данных, показанному ниже:

ИДЕНТИФИКАТОР КЛИЕНТА ДАТА ВСТРЕЧИ ВЕС_КГ
16081 2018-12-17 70.0
16081 2019-03-19 70.0
16081 2019-04-18 70.0
16081 2019-06-07 70.0
20011 2020-02-27 57.0
20011 2020-03-27 57.0
20011 2020-04-27 57.0
20011 2020-06-07 57.0
20011 2020-07-07 60.0
20020 2020-01-01 0.0

Вот код для создания df:

 df = pd.DataFrame({"CLIENT_ID": [16081, 16081, 16081, 16081, 20011, 20011, 20011, 20011, 20011,20020],
                   "ENCOUNTER_DATE": ['2018-12-17', '2019-03-19', '2019-04-18', '2019-06-07', '2020-02-27', '2020-03-27', '2020-04-27', '2020-06-07', '2020-07-07','2020-01-01'],
                   "WEIGHT_KG": [70, 0, 0, 0, 0, 0, 57, 0, 60,0]})
 

Ответ №1:

Идея заключается в замене 0 на отсутствующие значения, а затем для групп, использующих forward и backfilling отсутствующих значений, последняя замена NaN на 0 :

 df['WEIGHT_KG'] = (df['WEIGHT_KG'].replace(0, np.nan)
                                  .groupby(df['CLIENT_ID'])
                                  .transform(lambda x: x.ffill().bfill())
                                  .fillna(0))
 

Или:

 df['WEIGHT_KG'] = (df['WEIGHT_KG'].where(df['WEIGHT_KG'].ne(0))
                                  .groupby(df['CLIENT_ID'])
                                  .transform(lambda x: x.ffill().bfill())
                                  .fillna(0))
print (df)
   CLIENT_ID ENCOUNTER_DATE  WEIGHT_KG
0      16081     2018-12-17       70.0
1      16081     2019-03-19       70.0
2      16081     2019-04-18       70.0
3      16081     2019-06-07       70.0
4      20011     2020-02-27       57.0
5      20011     2020-03-27       57.0
6      20011     2020-04-27       57.0
7      20011     2020-06-07       57.0
8      20011     2020-07-07       60.0
9      20020     2020-01-01        0.0