我正在尝试添加一列数据,该数据是根据多索引数据帧的最左端索引从现有列中计算得出的。
在这种情况下,我有一列统计信息,最左边的索引是玩家,下一个级别的索引是季节。我想添加一列,该列是基于每个玩家最大状态的百分比的相对状态数。
因此,对于下面的数据框,我想添加一列为rStats(相对统计),其中第一个条目为= 5/7,第二个条目为= 6/7,第三个条目为= 6/7 = 7/7,然后到达新玩家后,它将使用他们的最大值,因此条目4将为= 3/5,依此类推。
Stats
Stephen Curry 2010 5
2011 6
2012 7
Chris Paul 2010 3
2011 4
2012 5
我已经创建了一系列最大统计信息(df.groupby('Player')['Stats']。max()),并尝试创建一个for循环,该循环基于条目应用正确的数学运算在df中,但无法使其正常工作。
下面是复制数据框简化版本的代码,如上所示:
import pandas as pd
players = ['Stephen Curry','Stephen Curry','Stephen Curry','Chris Paul','Chris Paul','Chris Paul']
years = [2010, 2011, 2012, 2010, 2011, 2012]
stats = [5, 6, 7, 3, 4, 5]
df = pd.DataFrame(index=[players,years],columns=['Stats'],data=stats)
答案 0 :(得分:3)
比groupby.apply
更快的方法是在GroupBy.max
上组合.div
和level=0
匹配索引
df.div(df.groupby(level=0).max(), level=0)
或者您只能在系列本身上这样做
df.Stats.div(df.Stats.groupby(level=0).max(), level=0)
Stats
Stephen Curry 2010 0.714286
2011 0.857143
2012 1.000000
Chris Paul 2010 0.600000
2011 0.800000
2012 1.000000
Timings
df = pd.concat([df]*1000)
%timeit df.div(df.groupby(level=0).max(), level=0)
100 loops, best of 3: 3.02 ms per loop
%timeit df.groupby(level=0).apply(lambda x: x/x.max())
1 loop, best of 3: 8.88 s per loop
答案 1 :(得分:2)
df['rstats']=df.groupby(level=0)['Stats'].apply(lambda x: x/x.max())
或更佳 @Quang Hoang建议的内容:
df['rstats']=df['Stats']/df.groupby(level=0)['Stats'].transform('max')
Stats rstats
Stephen Curry 2010 5 0.714286
2011 6 0.857143
2012 7 1.000000
Chris Paul 2010 3 0.600000
2011 4 0.800000
2012 5 1.000000