Функция агрегирования групп Pandas для определенных столбцов, отображение всех столбцов в результатах

#python #pandas #dataframe #pandas-groupby

#python #pandas #фрейм данных #pandas-groupby

Вопрос:

Я хотел бы иметь группу и сумму на основе идентификатора, но отображать все столбцы в результате.

Пример кода

 import pandas as pd
import numpy as np

mre = [
    ["2018-1", "Sold", 109000.0, "Appartement", 73.0, 4.0],
    ["2018-1", "Sold", 109000.0, "Appartement", "NaN", 0.0],
    ["2018-2", "Sold", 239300.0, "House", 163.0, 4.0],
    ["2018-2", "Sold", 239300.0, "House", 51.0, 2.0],
    ["2018-2", "Sold", 239300.0, "House", 51.0, 2.0]
]

df = pd.DataFrame(mre)

# Rename columns
df.columns = ["_idMutation", "typeOfSearch",
              "price", "typeOfBuilding", "surface", "nbRoom"]

df["surface"] = df["surface"].astype(float)

print(df)
  

Базовый фрейм данных

   _idMutation typeOfSearch     price typeOfBuilding  surface  nbRoom
0      2018-1         Sold  109000.0    Appartement     73.0     4.0
1      2018-1         Sold  109000.0    Appartement      NaN     0.0
2      2018-2         Sold  239300.0          House    163.0     4.0
3      2018-2         Sold  239300.0          House     51.0     2.0
4      2018-2         Sold  239300.0          House     51.0     2.0
  

Ожидаемые результаты

groupby Основан на _idMutation , он суммирует surface и суммирует nbRoom , но не влияет на другие строки. Я хотел бы отобразить все столбцы, удалив дубликаты _idMutation и показав результаты groupby

   _idMutation typeOfSearch     price typeOfBuilding surface  nbRoom
0      2018-1         Sold  109000.0    Appartement    73.0     4.0
1      2018-2         Sold  239300.0          House   265.0     8.0
  

Текущий код

Следующее решение дает ожидаемый результат. У меня 14,6 миллионов строк, и решение, которое я придумал, не выглядит оптимизированным.

 # Groupby on _idMutation amp; sum ["surface", "nbRoom"]
gb_df = df[["surface", "nbRoom"]].groupby(df["_idMutation"]).sum()

# Delete duplicates _idMutation
df.drop_duplicates(subset=["_idMutation"], inplace=True)

# Set _idMutation as df index
df.set_index("_idMutation", inplace=True)

# Concat df with gb_df
df = pd.concat(
    [df[["typeOfSearch", "price", "typeOfBuilding"]], gb_df], axis=1)
  

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

1. Сумма nbRoom для 2018-2 неверна, вы можете отредактировать?

2. Да, извините за это 🙂

Ответ №1:

Мы можем использовать GroupBy.agg и установить желаемый метод агрегирования для каждого столбца с помощью dict. В этом случае нам нужно только first и sum :

 dfg = df.groupby("_idMutation", as_index=False).agg({
    "typeOfSearch": "first",
    "price": "first",
    "typeOfBuilding": "first",
    "surface": "sum",
    "nbRoom": "sum"
})
  
   _idMutation typeOfSearch     price typeOfBuilding  surface  nbRoom
0      2018-1         Sold  109000.0    Appartement     73.0     4.0
1      2018-2         Sold  239300.0          House    265.0     8.0