Функции Grouper() и agg() при сжатии создают несколько копий

#python #pandas #dataframe #data-science #data-processing

Вопрос:

У меня есть образец фрейма данных, как показано ниже.

 import pandas as pd import numpy as np  NaN = np.nan data = {'ID':['A', 'A', 'A', 'B','B','B'], 'Date':['2021-09-20 04:34:57', '2021-09-20 04:37:25', '2021-09-20 04:38:26', '2021-09-01   00:12:29','2021-09-01 11:20:58','2021-09-02 09:20:58'], 'Name':['xx','xx',NaN,'yy',NaN,NaN], 'Height':[174,174,NaN,160,NaN,NaN], 'Weight':[74,NaN,NaN,58,NaN,NaN], 'Gender':[NaN,'Male',NaN,NaN,'Female',NaN], 'Interests':[NaN,NaN,'Hiking,Sports',NaN,NaN,'Singing']}  df1 = pd.DataFrame(data) df1   

Я хочу объединить данные, представленные на одну и ту же дату, в одну строку. Столбец «Дата» имеет формат метки времени. Я написал для этого код. Вот мой примерный код:

пробовать:

 df1['Date'] = pd.to_datetime(df1['Date'])  df_out = (df1.groupby(['ID', pd.Grouper(key='Date', freq='D')])  .agg(lambda x: ''.join(x.dropna().astype(str)))  .reset_index()  ).replace('', np.nan)  

Это дает результат, в котором при наличии нескольких записей с одинаковым значением конечный результат содержит несколько записей в одной строке, как показано ниже.

Полученный вывод введите описание изображения здесь, однако, я не хочу, чтобы значения повторялись, если есть несколько записей. Конечный результат должен выглядеть так, как показано на рисунке ниже.

Требуемая Производительность введите описание изображения здесь

В первом столбце не должно быть » xx «и 174.0 вместо «xxxx» и «174.0 174.0».

Мы будем очень признательны за любую помощь. Спасибо.

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

1. агрегирование с str.join , похоже, не подходит здесь для многих столбцов. Если вы ожидаете, что информация будет статичной, просто различающейся по отсутствию, то вам следует использовать first такие столбцы, как имя, возраст, вес, пол. Но если есть проблемы с качеством данных, вы можете решить их, например, с помощью модального значения. Тогда 'Interests' это была бы единственная колонка, которую вы ','.join

Ответ №1:

В вашем случае замените agg join на first

 df_out = (df1.groupby(['ID', pd.Grouper(key='Date', freq='D')])  .first()  .reset_index()  ).replace('', np.nan) df_out Out[113]:   ID Date Name Height Weight Gender Interests 0 A 2021-09-20 xx 174.0 74.0 Male Hiking,Sports 1 B 2021-09-01 yy 160.0 58.0 Female None 2 B 2021-09-02 None NaN NaN None Singing  

Ответ №2:

Поскольку вы пытаетесь сохранить только первое доступное значение для каждого столбца для каждой даты, вы можете сделать:

 gt;gt;gt; df1.groupby(["ID", pd.Grouper(key='Date', freq='D')]).agg("first").reset_index()   ID Date Name Height Weight Gender Interests 0 A 2021-09-20 xx 174.0 74.0 Male Hiking,Sports 1 B 2021-09-01 yy 160.0 58.0 Female None 2 B 2021-09-02 None NaN NaN None Singing