【问题标题】:Applying dependent mathematical operation to column in multi-indexed dataframe based on far left index基于最左索引将相关数学运算应用于多索引数据帧中的列
【发布时间】:2019-10-11 03:10:33
【问题描述】:

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

对于这个例子,我有一列统计数据,我最左边的索引是球员,下一个级别的索引是赛季。我想根据每个玩家最大统计数据的百分比添加一个相对统计数据列。

所以对于下面的数据框,我想添加一列是 rStats(相对统计),其中第一个条目是 =5/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)

【问题讨论】:

  • 如果您准确地展示您尝试过的内容和结果,这将会得到改进。

标签: python pandas dataframe


【解决方案1】:

groupby.apply 更快的方法是在level=0 上组合GroupBy.max.div 匹配索引

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

【讨论】:

    【解决方案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
    

    【讨论】:

    • transform('max') 和除法会更快:df['Stats']/df.groupby(level=0).Stats.transform('max')
    • 谢谢!但我意识到这不适用于具有多列的完整 df...如果我需要指定“统计”列,因为其他列是字符串,我需要如何编辑此实现?
    • 我很乐意提供帮助!
    猜你喜欢
    • 1970-01-01
    • 2014-04-17
    • 1970-01-01
    • 2021-09-29
    • 2018-05-11
    • 2018-06-12
    • 2016-06-27
    • 2020-03-01
    • 1970-01-01
    相关资源
    最近更新 更多