【问题标题】:Convert data to the quantile bin将数据转换为分位数 bin
【发布时间】:2013-01-13 07:29:55
【问题描述】:

我有一个带有数字列的数据框。对于每一列,我想计算分位数信息并将每一行分配给其中一个。我尝试使用qcut() method 返回一个垃圾箱列表,但最终单独计算垃圾箱。我认为可能存在但我找不到像df.to_quintile(num of quantiles) 这样的方法。这是我想出的,但我想知道是否有更简洁/熊猫的方式来做到这一点。

import pandas as pd

#create a dataframe
df = pd.DataFrame(randn(10, 4), columns=['A', 'B', 'C', 'D'])

def quintile(df, column):
    """
    calculate quintiles and assign each sample/column to a quintile 
    """
    #calculate the quintiles using pandas .quantile() here
    quintiles = [df[column].quantile(value) for value in [0.0,0.2,0.4,0.6,0.8]]
    quintiles.reverse() #reversing makes the next loop simpler

    #function to check membership in quintile to be used with pandas apply
    def check_quintile(x, quintiles=quintiles):
        for num,level in enumerate(quintiles):
            #print number, level, level[1]
            if  x >= level:
                print x, num
                return num+1

    df[column] = df[column].apply(check_quintile)

quintile(df,'A')

谢谢, 扎克cp

编辑:在看到 DSM 回答后,可以更简单地编写函数(如下)。伙计,那太甜了。

def quantile(column, quantile=5):
    q = qcut(column, quantile)
    return len(q.levels)- q.labels
df.apply(quantile)
#or
df['A'].apply(quantile)

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    我认为使用 qcut 返回的 Categorical 对象中存储的 labels 可以使这更简单。例如:

    >>> import pandas as pd
    >>> import numpy as np
    >>> np.random.seed(1001)
    >>> df = pd.DataFrame(np.random.randn(10, 2), columns=['A', 'B'])
    >>> df
              A         B
    0 -1.086446 -0.896065
    1 -0.306299 -1.339934
    2 -1.206586 -0.641727
    3  1.307946  1.845460
    4  0.829115 -0.023299
    5 -0.208564 -0.916620
    6 -1.074743 -0.086143
    7  1.175839 -1.635092
    8  1.228194  1.076386
    9  0.394773 -0.387701
    >>> q = pd.qcut(df["A"], 5)
    >>> q
    Categorical: A
    array([[-1.207, -1.0771], (-1.0771, -0.248], [-1.207, -1.0771],
           (1.186, 1.308], (0.569, 1.186], (-0.248, 0.569], (-1.0771, -0.248],
           (0.569, 1.186], (1.186, 1.308], (-0.248, 0.569]], dtype=object)
    Levels (5): Index([[-1.207, -1.0771], (-1.0771, -0.248],
                       (-0.248, 0.569], (0.569, 1.186], (1.186, 1.308]], dtype=object)
    >>> q.labels
    array([0, 1, 0, 4, 3, 2, 1, 3, 4, 2])
    

    或匹配您的代码:

    >>> len(q.levels) - q.labels
    array([5, 4, 5, 1, 2, 3, 4, 2, 1, 3])
    >>> quintile(df, "A")
    >>> np.array(df["A"])
    array([5, 4, 5, 1, 2, 3, 4, 2, 1, 3])
    

    【讨论】:

    • 感谢帝斯曼。我没有意识到 qcut() 输出有标签。这正是我所需要的!
    • 感谢@DSM,我不知道 qcut/cut 有标签属性(不幸的是,它没有在 IPython 自动完成中显示)。到目前为止,我认为我必须调用 labels=False 来调用函数来获取标签。但这样更好。
    猜你喜欢
    • 1970-01-01
    • 2017-11-20
    • 1970-01-01
    • 1970-01-01
    • 2021-03-16
    • 2020-05-16
    • 2019-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多