我是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的每个值重复'循环'。
有人可以帮忙吗?谢谢。
答案 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)