【问题标题】:Replace column values based on percentiles in python根据python中的百分位数替换列值
【发布时间】:2018-04-21 14:12:19
【问题描述】:

我已经对一个数据框进行了分组,并且我希望按组替换某些列中的值(如果它们或小于某个百分位数)。 因此,组内大于 0.95 个百分位的所有值都应替换为 0.95 个百分位,所有小于 0.05 个百分位的值应替换为 0.05 个百分位。
数据框可能如下所示(示例取自 another question): 两组:“一”和“二”

    A           B           C
0   0.719391    0.091693    one
1   0.951499    0.83716     one
2   0.975212    0.224855    one
3   0.80762     0.031284    one
4   0.63319     0.342889    one
5   0.075102    0.899291    one
6   0.502843    0.773424    one
7   0.032285    0.242476    one
8   0.794938    0.607745    one
9   0.620387    0.574222    one
10  0.446639    0.549749    two
11  0.664324    0.134041    two
12  0.622217    0.505057    two
13  0.670338    0.99087     two
14  0.281431    0.016245    two
15  0.675756    0.185967    two
16  0.145147    0.045686    two
17  0.404413    0.191482    two
18  0.94913     0.943509    two
19  0.164642    0.157013    two

这个数据框的结果应该是:

A               B           C
0   0.719391    0.091693    one
1   0.951499    0.83716     one
2   0.96454115  0.224855    one
3   0.80762     0.05846805  one
4   0.63319     0.342889    one
5   0.075102    0.87133205  one
6   0.502843    0.773424    one
7   0.05155265  0.242476    one
8   0.794938    0.607745    one
9   0.620387    0.574222    one
10  0.446639    0.549749    two
11  0.664324    0.134041    two
12  0.622217    0.505057    two
13  0.670338    0.96955755  two
14  0.281431    0.02949345  two
15  0.675756    0.185967    two
16  0.15391975  0.045686    two
17  0.404413    0.191482    two
18  0.8261117   0.943509    two
19  0.164642    0.157013    two

请注意,对于 A 列,第 2、7、16 和 18 行已被替换;并且对于 B 列,第 3、5、13 和 14 行已被替换。

有谁知道如何以有效的方式为大型数据框执行此操作?

谢谢

【问题讨论】:

    标签: python pandas grouping percentile


    【解决方案1】:

    为了使其更快,您可以通过这种方法来完成,尽管如果您有很多列,这将涉及更多的编码行。我的数据集包含 200 万行,这是一种非常快速的方法(

    A_05 = df['A'].quantile(0.05)
    A_95 = df['A'].quantile(0.95)
    df['A'].clip(A_05, A_95, inplace=True) 
    

    【讨论】:

      【解决方案2】:

      你可以使用groupby + quantile + clip:

      g = df.groupby('C').transform(lambda x: x.clip(*x.quantile([0.05, 0.95])))
      g['C'] = df['C']
      
                 A         B    C
      0   0.719391  0.091693  one
      1   0.951499  0.837160  one
      2   0.964541  0.224855  one
      3   0.807620  0.058468  one
      4   0.633190  0.342889  one
      5   0.075102  0.871332  one
      6   0.502843  0.773424  one
      7   0.051553  0.242476  one
      8   0.794938  0.607745  one
      9   0.620387  0.574222  one
      10  0.446639  0.549749  two
      11  0.664324  0.134041  two
      12  0.622217  0.505057  two
      13  0.670338  0.969558  two
      14  0.281431  0.029493  two
      15  0.675756  0.185967  two
      16  0.153920  0.045686  two
      17  0.404413  0.191482  two
      18  0.826112  0.943509  two
      19  0.164642  0.157013  two
      

      健全性检查

      np.allclose(e[['A', 'B']].values, g[['A', 'B']].values)
      True
      

      这里,e 是您问题的输出。

      【讨论】:

      • LOL,还是用pandas的剪辑更好~ ;-)
      • 我必须说它花费的时间比我预期的要多得多:我的 df 有超过 400 万行,并且自从我开始运行以来已经超过 20 分钟。如果我只选择一列进行转换会更快吗?如果是,那么最有效的方法是什么?谢谢
      • @JamieLee 不能说...也许是绝对规模​​... groupby 操作通常很慢。还有一个叫dask的替代方案,用于快速处理大熊猫数据帧,如果你有兴趣,可以研究一下。
      • 我的运行给了我错误“长度不匹配:预期轴有..”。可以解决这个问题吗?
      • @JamieLee 你能用产生此错误的数据副本打开一个新 Q 吗?
      【解决方案3】:
      df.groupby('C')['A','B'].transform(lambda x : np.clip(x,x.quantile(0.05),x.quantile(0.95)))
      Out[1599]: 
                 A         B
      0   0.719391  0.091693
      1   0.951499  0.837160
      2   0.964541  0.224855
      3   0.807620  0.058468
      4   0.633190  0.342889
      5   0.075102  0.871332
      6   0.502843  0.773424
      7   0.051553  0.242476
      8   0.794938  0.607745
      9   0.620387  0.574222
      10  0.446639  0.549749
      11  0.664324  0.134041
      12  0.622217  0.505057
      13  0.670338  0.969558
      14  0.281431  0.029493
      15  0.675756  0.185967
      16  0.153920  0.045686
      17  0.404413  0.191482
      18  0.826112  0.943509
      19  0.164642  0.157013
      

      【讨论】:

        猜你喜欢
        • 2017-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-08
        • 2022-07-21
        • 2020-10-02
        • 1970-01-01
        相关资源
        最近更新 更多