根据最左端索引

时间:2019-10-10 18:50:04

标签: python pandas dataframe

我正在尝试添加一列数据,该数据是根据多索引数据帧的最左端索引从现有列中计算得出的。

在这种情况下,我有一列统计信息,最左边的索引是玩家,下一个级别的索引是季节。我想添加一列,该列是基于每个玩家最大状态的百分比的相对状态数。

因此,对于下面的数据框,我想添加一列为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)

2 个答案:

答案 0 :(得分:3)

groupby.apply更快的方法是在GroupBy.max上组合.divlevel=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)

使用groupby.apply

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