#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