Python:如何在Pandas中创建加权分位数?

Python:如何在Pandas中创建加权分位数?,python,pandas,Python,Pandas,我了解如何使用Pandas创建简单的分位数。但是在四处搜索之后,我没有看到任何创建加权分位数的东西。具体地说,我希望创建一个变量,该变量将感兴趣的变量的值(从最小到最大)分类,以便每个分类包含相等的权重。到目前为止,这就是我所拥有的: def wtdQuantile(dataframe, var, weight = None, n = 10): if weight == None: return pd.qcut(dataframe[var], n, labels = Fa

我了解如何使用Pandas创建简单的分位数。但是在四处搜索之后,我没有看到任何创建加权分位数的东西。具体地说,我希望创建一个变量,该变量将感兴趣的变量的值(从最小到最大)分类,以便每个分类包含相等的权重。到目前为止,这就是我所拥有的:

def wtdQuantile(dataframe, var, weight = None, n = 10):
    if weight == None:
        return pd.qcut(dataframe[var], n, labels = False)
    else:
        dataframe.sort_values(var, ascending = True, inplace = True)
        cum_sum = dataframe[weight].cumsum()
        cutoff = max(cum_sum)/n
        quantile = cum_sum/cutoff
        quantile[-1:] -= 1
        return quantile.map(int)
有没有一个更简单的方法,或者是用我错过的熊猫预制的东西

编辑:根据要求,我提供了一些示例数据。在下面,我尝试使用“Weight”作为权重来存储“Var”变量。使用
pd.qcut
,我们在每个箱子中得到相同数量的观察结果。相反,我希望每个箱子的重量相等,或者在这种情况下,尽可能接近相等

Weight  Var  pd.qcut(n=5)  Desired_Rslt
   10     1            0              0
   14     2            0              0
   18     3            1              0
   15     4            1              1
   30     5            2              1
   12     6            2              2
   20     7            3              2
   25     8            3              3
   29     9            4              3
   45    10            4              4

我不认为这是Pandas内置的,但这里有一个函数,它可以在几行代码中实现您想要的功能:

import numpy as np
import pandas as pd
from pandas._libs.lib import is_integer

def weighted_qcut(values, weights, q, **kwargs):
    'Return weighted quantile cuts from a given series, values.'
    if is_integer(q):
        quantiles = np.linspace(0, 1, q + 1)
    else:
        quantiles = q
    order = weights.iloc[values.argsort()].cumsum()
    bins = pd.cut(order / order.iloc[-1], quantiles, **kwargs)
    return bins.sort_index()
我们可以通过以下方式对您的数据进行测试:

data = pd.DataFrame({
    'var': range(1, 11),
    'weight': [10, 14, 18, 15, 30, 12, 20, 25, 29, 45]
})

data['qcut'] = pd.qcut(data['var'], 5, labels=False)
data['weighted_qcut'] = weighted_qcut(data['var'], data['weight'], 5, labels=False)
print(data)
输出与上面的期望结果相匹配:

   var  weight  qcut  weighted_qcut
0    1      10     0              0
1    2      14     0              0
2    3      18     1              0
3    4      15     1              1
4    5      30     2              1
5    6      12     2              2
6    7      20     3              2
7    8      25     3              3
8    9      29     4              3
9   10      45     4              4

您能否提供一些示例数据、输入和输出,以说明您想要什么?请在询问熊猫相关问题时始终提供示例数据。对于大量分位数,这有时会跳过箱子。我在大量数据集上有20个存储箱,有时0.75缺失,有时0.30缺失,等等。我不完全理解这段代码是如何工作的,你猜它为什么会跳过存储箱吗?