【问题标题】:Find the column name of the highest weighted average查找最高加权平均值的列名
【发布时间】:2022-10-04 22:09:04
【问题描述】:

我有一个看起来像这样的DF。在投资者栏中,1 表示已投资,0 表示没有。如果有超过 1 个投资人投资了一个项目,我们可以假设他们平分投资(例如:投资人 A 和 B 各投资了 50000 到项目“某物”)。我想计算每个投资者投入的总金额,并找出谁投资最多。

Project Invested Amount Investor A Investor B Investor C
Something 100000 1 1 0
Another 5000000 0 0 1
Last 25000000 1 1 1

现在我正在考虑按每个有 1 的投资者进行过滤,然后除以所有投资者列的总和。这是我尝试过的,但我仍然缺少一些东西:

Investor_A = df[df['Investor A'] == 1]
test = Investor_A['Invested Amount'] / (df.iloc[:,3:5].sum())

预期输出:

投资者 A 将总共投入 100000/2 + 25000000/3 = 8383333.33333。投资者 B 将总共投入 100000/2 + 25000000/3 = 8383333.33333。投资者 C 将总共投入 5000000 + 25000000/3 = 13333333.3333 -->投资者 C投入了最多的钱。

【问题讨论】:

    标签: python pandas dataframe data-analysis


    【解决方案1】:

    在 Investor 列上调用 filter(),然后将 Invested Amount 列除以 Investor 列的逐行总和。然后再次乘以投资人列,得到每个投资人对每个项目的总份额。然后调用sum() 会找到每个投资者的总投资,idxmax() 会获取投资者的姓名。

    investors = df.filter(like='Investor')
    avg_invested_amount = df['Invested Amount'] / investors.sum(1)
    investment_shares = investors.mul(avg_invested_amount, axis=0)
    investment_per_investor = investment_shares.sum()
    investment_per_investor.idxmax()
    #'Investor C'
    

    仅供参考,这段代码可以写成 2 行(但可读性要差得多):

    investors = df.filter(like='Investor')
    investors.mul(investors.sum(1).rdiv(df['Invested Amount']), axis=0).sum().idxmax()
    

    注: mul()(和add()sub()div())允许axis 参数,您可以使用该参数使索引与矢量化操作匹配(这对于* 是不可能的)。

    【讨论】:

    • 谢谢,所以我们需要使用 mul() 和 div() 而不是使用 * 和 /。有什么特别的原因吗?
    【解决方案2】:

    @NewEnglandcottontail 的方式直截了当……另一种方式可能是这样;

    import pandas as pd 
    
    df = pd.DataFrame({"Project":["Project1","Project2","Project3"],
                       "Invested Amount":[100000,5000000,25000000],
                       "Investor A":[1,0,1],
                       "Investor B":[1,0,1],
                       "Investor C":[0,1,1]})
    
    df1 = df.copy()
    col_lst = [col for col in df1.columns if "Investor" in col]
    df1[col_lst] = df1.apply(lambda x: x[col_lst] * x["Invested Amount"]/sum(x[col_lst]),axis=1)
    
    lst = df1[col_lst].sum().to_list()
    print("Investor who invested maximum ammount:",col_lst[lst.index(max(lst))])
    

    输出;

    Investor who invested maximum ammount: Investor C
    

    【讨论】:

    • 你知道,apply(..., axis=1) 确实是 for 循环的语法糖,而且通常比列表理解要慢,因为它有 pandas 开销。你应该avoid it wherever possible
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-03
    • 2021-05-27
    • 2020-08-10
    相关资源
    最近更新 更多