从Pandas数据框中的现有col派生的新累积值col

时间:2013-12-21 22:59:49

标签: python pandas

我是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

“New”下的第1行(0.4000)中的值表示200/500(L1的al L3值之和)。第二个值(0.6000)仅为300/500,依此类推。对于X,Y和Z的每个值重复'循环'。

有人可以帮忙吗?谢谢。

2 个答案:

答案 0 :(得分:3)

您可以使用以下代码行完成此操作:

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

答案 1 :(得分:1)

正如this帖子中所述,该解决方案仅适用于Pandas版本0.13。对于当前版本(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)