合并groupby中的加权平均值

问题描述 投票:0回答:1

我有一只熊猫

DataFrame
:

import pandas as pd
df = pd.DataFrame({
    "commodity":["Potatos","Potatos","Apples","Apples","Apples"], 
    "amount":[1,2,3,4,None], 
    "price":[4,5,6,7,8], 
    "attr1":[None,1,None,"foo","bar"],
})

(实际上,我有无数不同类型的列,例如

attr1
)。

我需要通过

commodity
总结框架,保持 first 非空
attr1
(和 last 非空
attr2
)。

这是我现在的做法:

df["cost"] = df.amount * df.price
def first(se):
    "Get the first non-None element of the Series"
    assert isinstance(se, pd.Series)
    se = se.dropna()
    if se.empty:
        return None
    return se.iloc[0]
summary = df.groupby("commodity").agg({"amount":sum, "cost":sum, "attr1":first})
df.drop(columns=["cost"], inplace=True)
summary["price"] = summary.cost / summary.amount
summary.drop(columns=["cost"], inplace=True)
columns = list(df.columns)
columns.remove("commodity")
summary = summary[columns]
summary

            amount  price       attr1
commodity           
Apples      7.0     6.571429    foo
Potatos     3.0     4.666667    1

这实现了我想要的功能,但是功能

first
似乎昂贵得难以忍受(正如预期)。

我想知道这是否可以更有效地完成。

python pandas dataframe group-by aggregate
1个回答
0
投票

也许你可以使用

.notna()
+
.idxmax()
:

x = df.groupby("commodity").agg(
    {"amount": "sum", "attr1": lambda s: s.loc[s.notna().idxmax()]}
)
print(x)

打印:

           amount attr1
commodity              
Apples        7.0   foo
Potatos       3.0     1

或者:

Series.first_valid_index()

x = df.groupby("commodity").agg(
    {"amount": "sum", "attr1": lambda s: s.loc[s.first_valid_index()]}
)
print(x)
© www.soinside.com 2019 - 2024. All rights reserved.