Python – применить функцию для заполнения N/A в группах Group by

У меня есть набор данных с отсутствующими значениями в 2 столбцах, и я хотел бы заполнить его значениями в предыдущих строках в последнюю предыдущую дату. Итак, есть Weight и Height должны быть заполнены значениями из другой строки на основе последней даты для предопределенного Category и со ссылкой на WorkerID (предопределено в предыдущих заполненных строках), например:

Пример данных:

Ind  Date       WorkerID  Category   Weight   Height   Kind_eat
1    31/12/17    E145-46     cat      2.35      0.6       1  
2    01/09/18    M147-50     cat      4.78      0.8       2
3    27/05/18    K178-56     dog      7.03      0.75      3
4    09/02/18    T106-20     mouse    NaN       NaN       1
5    18/03/19    M147-50     cat      NaN       NaN       2
6    25/03/19    K178-56     dog      NaN       NaN       3
7    04/01/17    T106-20     mouse    0.75      0.15      4
8    01/04/19    T156-10     dog      6.99      0.13      4

Таким образом, столбцы NaN из Weight и Height должны быть заполнены на основе столбцов Weight, Height со ссылкой на значения, отличные от NaN, на последнюю доступную дату, которая предшествует фактическому значению в Date.

Например,

5    18/03/19    M147-50     cat      NaN       NaN       2

должны быть заполнены Weight и Height из line2:

5    18/03/19    M147-50     cat      4.78      0.8       2

Я пытался сделать это методом group-by и fillna для group, но ничего не заполняет.

df.groupby(['Date','WorkerID'], as_index = False).apply(lambda group: group.ffill())

также я пытался использовать: df.groupby(['Date','WorkedID']).ffill().reindex(df.columns, axis=1)

Фактический результат: - нет правильного заполнения для NaN

Ind  Date       WorkerID  Category   Weight   Height   Kind_eat
1    31/12/17    E145-46     cat      2.35      0.6       1  
2    01/09/18    M147-50     cat      4.78      0.8       2
3    27/05/18    K178-56     dog      7.03      0.75      3
4    09/02/18    T106-20     mouse    NaN       NaN       1
5    18/03/19    M147-50     cat      NaN       NaN       2
6    25/03/19    K178-56     dog      NaN       NaN       3
7    04/01/17    T106-20     mouse    0.75      0.15      4
8    01/04/19    T156-10     dog      6.99      0.13      4

Ожидаемый результат должен быть:

Ind  Date       WorkerID  Category   Weight   Height   Kind_eat
1    31/12/17    E145-46     cat      2.35      0.6       1  
2    01/09/18    M147-50     cat      4.78      0.8       2
3    27/05/18    K178-56     dog      7.03      0.75      3
4    09/02/18    T106-20     mouse    0.75      0.15      1
5    18/03/19    M147-50     cat      4.78      0.8       2
6    25/03/19    K178-56     dog      7.03      0.75      3
7    04/01/17    T106-20     mouse    0.75      0.15      4
8    01/04/19    T156-10     dog      6.99      0.13      4

Буду признателен за любую идею. Спасибо)

Я думаю, что ваше line2, описанное как 5 18/03/19 M147-50 cat 4.78 0.8 2, должно быть 2 01/09/18 M147-50 cat 4.78 0.8 2, я прав?

Szymon Maszke 09.04.2019 23:55

@SzymonMaszke, нет, дата должна быть сохранена как в строке 5: 18/03/19, только NaN из столбцов Weight и Height должны быть заменены из строки 2.

Cindy 09.04.2019 23:58

Да, я это и имел в виду, хотя это выглядит немного запутанно, спасибо за разъяснение

Szymon Maszke 09.04.2019 23:58

@SzymonMaszke, поэтому у меня нет новой идеи о том, как это можно исправить.

Cindy 10.04.2019 00:00

@Cindy, не могли бы вы попробовать: df.sort_values('Date').fillna(method='ffill').sort_values('I‌​nd')

Vasilis D 10.04.2019 00:06

@VasilisD, спасибо за идею. Он заполнил NaN значения для mouse категории из 3-й строки вместо 7-й. Итак, WorkerID и Category следует сохранить.

Cindy 10.04.2019 00:28
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
6
128
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, вам нужно сначала преобразовать Date в datetime.

df['Date'] = pd.to_datetime(df['Date'])

И используйте sort_values рядом с Date и groupby с ['WorkerID', 'Category'], а затем ffill.

df = df.sort_values('Date').groupby(['WorkerID', 'Category']).ffill().sort_index()

df
    WorkerID Category       Date  Weight  Height  Kind_eat
Ind                                                       
1    E145-46      cat 2017-12-31    2.35    0.60         1
2    M147-50      cat 2018-01-09    4.78    0.80         2
3    K178-56      dog 2018-05-27    7.03    0.75         3
4    T106-20    mouse 2018-09-02    0.75    0.15         1
5    M147-50      cat 2019-03-18    4.78    0.80         2
6    K178-56      dog 2019-03-25    7.03    0.75         3
7    T106-20    mouse 2017-04-01    0.75    0.15         4
8    T156-10      dog 2019-01-04    6.99    0.13         4

Другие вопросы по теме