我在数据框中有一个数字列,需要根据该列的值对其进行分类。例如,
id value
1 2.0
2 3.0
3 4.5
4 5.5
我需要一个新的分类变量
group
基于该行之前的行的分位数值。因此,对于id=2
,它将在分位数计算中考虑第1行和第2行。然后进行分类,如下所示:if value > quantile(90%) category = 'Very High'
if value > quantile(75%) & value <= quantile(90%) & category = 'High'
if value > quantile(25%) & value <= quantile(75%) & category = 'Normal'
if value <= quantile(25%) category = 'Low'
我该如何计算这样的分位数并进行比较?
最佳答案
也许我不太明白这个问题,但是由于你的级数总是在增加,最后一个值的分位数总是1。所以产量应该一直“很高”。
这不是超级有效的,因为我正在为每个迭代创建一个系列,但它确实做到了。您可以使用scipy中的某些内容更改apply函数来计算百分位数,这将加快进程
这都是因为DataFrame.expanding()
没有rank()
方法。如果那是可能的话,那将是非常直接的。
def ranking(x):
return pd.Series(x).rank(pct=True).values[-1]
ranked = sx.expanding().apply(lambda x: ranking(x))
pd.cut(ranked, (0, 0.25, 0.75, 0.90, 1), labels=['low', 'Normal', 'High', 'Very High'])
Out[97]:
0 Very High
1 Very High
2 Very High
3 Very High
dtype: category
Categories (4, object): [low < Normal < High < Very High]
具有scipy依赖性的更快的解决方案:
from scipy.stats import rankdata
ranked = sx.expanding().agg(lambda x: rankdata(x)[-1]/len(x))
In[108]: import timeit
In[109]: %timeit sx.expanding().agg(lambda x: rankdata(x)[-1]/len(x))
1000 loops, best of 3: 611 us per loop
In[110]: %timeit sx.expanding().apply(lambda x: ranking(x))
1000 loops, best of 3: 1.15 ms per loop
关于python - Pandas :如何基于扩展的分位数创建类别?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40305449/