【问题标题】:Groupby dataframe with custom quantiles and add quantile labels to a new column具有自定义分位数的 Groupby 数据框并将分位数标签添加到新列
【发布时间】:2020-10-09 13:28:14
【问题描述】:
import pandas as pd
import numpy as np

a = list("ABC") * 4
value = np.random.randint(-5, 5, 12)
df = pd.DataFrame({"A": a, "value": value})
print(df)

    A  value
0   A     -5
1   B      1
2   C      0
3   A      0
4   B     -4
5   C     -1
6   A      2
7   B      4
8   C     -5
9   A      0
10  B      1
11  C     -1

我的目标是创建第三列,其中包含基于自定义分位数范围的分位数标签。这些范围是基于第一列在 GroupBy 对象上计算的。我的用例是计算每个组的底部 10% 和顶部 10% 值(即十分位数),然后在新列中相应地标记它们:'bottom_decile'、'mid_deciles'、'top_decile'

期望的结果:

    A  value              C
0   A     -5  bottom_decile
1   B      1    mid_deciles
2   C      0     top_decile
3   A      0    mid_deciles
4   B     -4  bottom_decile
5   C     -1    mid_deciles
6   A      2     top_decile
7   B      4     top_decile
8   C     -5  bottom_decile
9   A      0    mid_deciles
10  B      1    mid_deciles
11  C     -1    mid_deciles

这是我的尝试:

df['C'] = df.groupby(['A'])['value'].transform(lambda x: pd.qcut(x, [0, 0.1, 0.9, 1], labels=['bottom_decile', 'mid_deciles', 'top_decile']))

但是,结果引发了错误:

ValueError: Bin edges must be unique: array([-5. , -3.8,  2. ,  2. ]).
You can drop duplicate edges by setting the 'duplicates' kwarg

【问题讨论】:

  • 所以按照您的错误提示删除重复的边缘。
  • 我的实际数据集有数百万行。丢弃边缘如何影响最终的数据帧?
  • 阅读this answer
  • 这些值应该正确分配给相应的 bin,但 bin 的大小可以不同(什么对你来说并不重要)。

标签: python pandas dataframe


【解决方案1】:

您可以删除重复的边缘:

df['C'] = df.groupby('A')['value'].transform(pd.qcut,
                                   q=[0, 0.1, 0.9, 1],
                                   labels=['bottom_decile', 'mid_deciles', 'top_decile'],
                                   duplicates='drop')

print(df.head())

输出:

   A  value              C
0  A     -5  bottom_decile
1  B      1    mid_deciles
2  C      0     top_decile
3  A      0    mid_deciles
4  B     -4  bottom_decile

【讨论】:

    【解决方案2】:

    我是初学者,但我正在尝试练习,所以这是我的解决方案:

    import pandas as pd
    import numpy as np
    
    a = list("ABC") * 4
    value = np.random.randint(-5, 5, 12)
    df = pd.DataFrame({"A": a, "value": value})
    print(df)
    
     A  value
    0   A      4
    1   B     -2
    2   C      1
    3   A     -3
    4   B     -3
    5   C      1
    6   A     -2
    7   B      1
    8   C      4
    9   A     -2
    10  B      0
    11  C     -1
    

    然后我写了这个函数:

    def func(x):
       return pd.DataFrame(pd.qcut(x, [0.0, 0.1, 0.9, 1], labels=['bottom_decile', 'mid_deciles', 'top_decile']))
    

    然后我就这样做了:

    df['C'] = func(df.groupby(['A'])['value'].head(len(df.index)))
    

    那么最后的输出:

    df.head()
    A   value   C
    0   A   4   top_decile
    1   B   -2  mid_deciles
    2   C   1   mid_deciles
    3   A   -3  bottom_decile
    4   B   -3  bottom_decile
    

    或者你可以像 ValueError 所说的那样删除重复项

    我希望它运作良好!

    【讨论】:

    • 您的解决方案计算整个数据帧的分位数,而不是每个组。
    • 每组怎么样,能给我举个例子更好理解吗?
    猜你喜欢
    • 2021-12-06
    • 2017-07-15
    • 2013-10-29
    • 2016-08-17
    • 2012-10-08
    • 1970-01-01
    • 1970-01-01
    • 2018-04-01
    • 2022-01-26
    相关资源
    最近更新 更多