pandas qcut 如何决定 bin 边缘

数据挖掘 Python 熊猫
2022-02-16 22:39:42

我有熊猫数据框,我想对连续值进行分类。

a['abc'].describe() # a name of pandas dataframe, abc--column name
count    250000.000000
mean         43.412040
std          26.075295
min           0.000000
25%          25.000000
50%          38.000000
75%          53.000000
max         218.000000
Name: abc, dtype: float64

在将熊猫qcut用于 4 组时,如何在其中一个箱中分配负值?

a["abc_bin"] = pd.qcut(a["abc"],4,labels=None,)
print(a["abc_bin"].value_counts())

(25.0, 38.0]      73448
(-0.001, 25.0]    62818
(53.0, 218.0]     61605
(38.0, 53.0]      52129
Name: abc_bin, dtype: int64

bin 宽度是如何确定的?特别是,如何有一个负值作为 bin 边缘?

1个回答

为什么一个 bin 包含负值?

这是因为生成的间隔在左侧是开放的,所以 pandas 扩展了左边缘以包含最小值。根据您的describe输出,最小值为 0,因此左边缘略微为负:

  • (0, 25.0]包括0
  • (-0.001, 25.0]包括 0

这没有记录在 中qcut,但类似的行为在 中进行了解释cut

bins: ... 的范围x在每一侧扩展 0.1%,以包括 的最小值和最大值x


垃圾箱是如何确定的?

qcut调整边缘,使每个 bin 包含相同数量的元素,而cut仅在边缘处严格划分。

  • 因此,我们可以通过指定一个 bin 列表cut来避免负边缘,因为数据在这些边缘处被精确分割:

    a = pd.DataFrame({'abc': np.random.random(size=10000)})
    pd.cut(a['abc'], [0, 0.25, 0.5, 0.75, 1]).value_counts()
    
    # (0.25, 0.5]    2637
    # (0.0, 0.25]    2478
    # (0.75, 1.0]    2454
    # (0.5, 0.75]    2431
    # Name: abc, dtype: int64
    
  • 但是对于qcut,这种解决方法没有任何效果,因为qcut总是调整边缘以强制 bin 数量相等:

    pd.qcut(a['abc'], [0, 0.25, 0.5, 0.75, 1]).value_counts()
    
    # (-0.000818, 0.253]    2500
    # (0.253, 0.489]        2500
    # (0.489, 0.745]        2500
    # (0.745, 1.0]          2500
    # Name: abc, dtype: int64