【问题标题】:New cumulative value col derived from existing col in a Pandas dataframe从 Pandas 数据框中的现有列派生的新累积值列
【发布时间】:2013-12-27 04:32:08
【问题描述】:

我是 python 和 pandas 的新手,我想知道是否有一种“pythonic”方式来完成以下任务:我有一个如下所示的数据框:

L1  L2  L3
X   1   50
X   2   100
Z   1   15
X   3   200
Z   2   10
Y   1   1
Z   3   20
Y   2   10
Y   3   100

我正在尝试对行进行排序并创建一个附加列,以升序显示从 L3 派生的累积值。我需要的输出如下:

L1  L2  L3  New
X   3   200 0.40000
X   2   100 0.60000
X   1   200 1.00000
Y   3   100 0.90090
Y   2   10  0.99099
Y   1   1   1.00000
Z   3   20  0.44444
Z   1   15  0.77778
Z   2   10  1.00000

“新”下第 1 行的值 (0.4000) 表示 200/500(L1 的所有 L3 值的总和)。第二个值 (0.6000) 就是 300/500,依此类推。为 X、Y 和 Z 的每个值重复“循环”。

有人可以帮忙吗?谢谢。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    您可以使用以下代码行:

    df.groupby("L1", as_index=False).apply(lambda x : pd.expanding_sum(x.sort("L3", ascending=False)["L3"])/x["L3"].sum())
    

    一些解释:

    • df.groupby("L1", as_index=False) 确实按列 L1 对数据帧进行分组,因此对每个值(X、Y 和 Z)进行以下计算
    • .apply() 将该函数应用于每个组:
      • pd.expanding_sum(x.sort("L3", ascending=False)["L3"]) 取“L3”列的累积总和,但首先按“L3”中的值排序
      • .../x["L3"].sum() 然后将其除以该组中所有“L3”值的总和。

    这给出了:

    In [9]: df["new"] = df.groupby("L1", as_index=False).apply(lambda x : pd.expanding_sum(x.sort("L3", ascending=False)["L3"])/x["L3"].sum())
    
    In [10]: df
    Out[10]: 
      L1  L2   L3       new
    0  X   1  200  0.800000
    1  X   2  100  1.000000
    2  Z   1   15  0.777778
    3  X   3  200  0.400000
    4  Z   2   10  1.000000
    5  Y   1    1  1.000000
    6  Z   3   20  0.444444
    7  Y   2   10  0.990991
    8  Y   3  100  0.900901
    

    或排序:

    In [16]: df.sort(["L1", "L3"], ascending=[True, False])
    Out[16]: 
      L1  L2   L3       new
    0  X   1  200  0.800000
    3  X   3  200  0.400000
    1  X   2  100  1.000000
    8  Y   3  100  0.900901
    7  Y   2   10  0.990991
    5  Y   1    1  1.000000
    6  Z   3   20  0.444444
    2  Z   1   15  0.777778
    4  Z   2   10  1.000000
    

    【讨论】:

    • 很好的答案!我正要问一个类似的问题。谢谢
    【解决方案2】:

    正如this 帖子中所述,该解决方案仅适用于 0.13 版的 Pandas。对于当前版本(0.12),解决方法如下:

    In [20]: new_column = df.groupby('L1', as_index=False).apply(lambda x : pd.expanding_sum(x.sort('L3', ascending=False)['L3'])/x['L3'].sum())
    In [21]: df["new"] = new_column.reset_index(level=0, drop=True)
    

    【讨论】:

    • 在我的回答中,有人提到了另一种方法,它仍然有点干净
    猜你喜欢
    • 1970-01-01
    • 2021-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-08
    • 2017-05-15
    • 2020-07-18
    相关资源
    最近更新 更多