按选定DataFrame列的值的百分位进行分组

6 投票
3 回答
9784 浏览
提问于 2025-04-18 12:39

假设我有一个 DataFrame,里面的列只包含真实的数值。

>> df        
          col1   col2      col3  
0     0.907609     82  4.207991 
1     3.743659   1523  6.488842 
2     2.358696    324  5.092592  
3     0.006793      0  0.000000  
4    19.319746  11969  7.405685 

我想根据某一列(比如 col1)的四分位数(或者我自己指定的其他百分位数)来对数据进行分组,然后对这些组进行一些操作。理想情况下,我想做的事情是:

df.groupy( quartiles_of_col1 ).mean()  # not working, how to code quartiles_of_col1?

输出应该显示每个列在对应于 col1 的四个组中的平均值。这样做可以通过 groupby 命令实现吗?最简单的方法是什么呢?

3 个回答

0

Pandas有一个自带的解决方案,叫做pandas.qcut,可以用来处理这个问题:

http://pandas.pydata.org/pandas-docs/stable/generated/pandas.qcut.html

0

我希望这个能解决你的问题。虽然看起来不太好,但我希望它能对你有用。

    import pandas as pd
    import random 
    import numpy as np
    ## create a mock df as example. with column A, B, C and D
    df = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD'))

    ## select dataframe based on the quantile of column A, using the quantile method.
    df[df['A'] < df['A'].quantile(0.3)].mean()

这段代码会输出:

A   -1.157615
B    0.205529
C   -0.108263
D    0.346752
dtype: float64
12

我现在没有电脑来测试这个,不过我觉得你可以这样做:df.groupby(pd.cut(df.col0, np.percentile(df.col0, [0, 25, 75, 90, 100]), include_lowest=True)).mean()。150分钟后我会更新。

一些解释:

In [42]:
#use np.percentile to get the bin edges of any percentile you want 
np.percentile(df.col0, [0, 25, 75, 90, 100])
Out[42]:
[0.0067930000000000004,
 0.907609,
 3.7436589999999996,
 13.089311200000001,
 19.319745999999999]
In [43]:
#Need to use include_lowest=True
print df.groupby(pd.cut(df.col0, np.percentile(df.col0, [0, 25, 75, 90, 100]), include_lowest=True)).mean()
                       col0     col1      col2
col0                                          
[0.00679, 0.908]   0.457201     41.0  2.103996
(0.908, 3.744]     3.051177    923.5  5.790717
(3.744, 13.0893]        NaN      NaN       NaN
(13.0893, 19.32]  19.319746  11969.0  7.405685
In [44]:
#Or the smallest values will be skiped
print df.groupby(pd.cut(df.col0, np.percentile(df.col0, [0, 25, 75, 90, 100]))).mean()
                       col0     col1      col2
col0                                          
(0.00679, 0.908]   0.907609     82.0  4.207991
(0.908, 3.744]     3.051177    923.5  5.790717
(3.744, 13.0893]        NaN      NaN       NaN
(13.0893, 19.32]  19.319746  11969.0  7.405685

撰写回答