小能豆

在 pandas 数据框中使用 cut 进行分箱时,为什么分箱没有正确完成?

py

我有一个数据框,我想将其按一列进行分组(即分组为子范围),然后对每个分组的第二列取平均值:

import pandas as pd
import numpy as np

data = pd.DataFrame(columns=['Score', 'Age'])
data.Score = [1, 1, 1, 1, 0, 1, 2, 1, 0, 1, 1, 0, 2, 1, 1, 2, 1, 0, 1, 1, -1, 1, 0, 1, 1, 0, 1, 0, -2, 1]
data.Age = [29, 59, 44, 52, 60, 53, 45, 47, 57, 54, 35, 32, 48, 31, 49, 43, 67, 32, 31, 42, 37, 45, 52, 59, 56, 57, 48, 45, 56, 31]

_, bins = np.histogram(data.Age, 10)
labels = ['{}-{}'.format(i + 1, j) for i, j in zip(bins[:-1], bins[1:])]
labels[0] = '{}-{}'.format(bins[0], bins[1])
binned = pd.cut(data.Age, bins=bins, labels=labels, include_lowest=True, precision=0)
df = data.groupby(binned)['Score'].mean().reset_index()
df

3.png

这种分箱方式存在 2 个问题:

  1. 第个箱的上限(n-1)和第个箱的下限之间存在 1 的间隙n(这意味着分箱不连续,并且位于此间隙中的数据点将被跳过)。
  2. 最后几个 bin 限制在小数点后有很多数字。我precision=0在 中使用了标志cut,但似乎没用——无论x我在 中使用什么precision=x,它仍然会产生最后几个 bin 在小数点后有很多数字的 bin。

第二点会导致问题,例如,当我尝试绘制时df,它破坏了 x 轴的外观:

import matplotlib.pyplot as plt
plt.plot([str(i) for i in df.Age], df.Score, 'o-')

1.png

precision=0尽管我放置了标记以暗示我只想要整数作为 bin 限制,而不是浮点数,但为什么还是会发生这种情况?我该如何修复它?


我通过int手动将 bin 值转换为 s 来暂时解决这个问题:

_, bins = np.histogram(data.Age, 10)
for i in range(len(bins)): # my fix
    bins[i] = int(bins[i])
labels = ['{}-{}'.format(i + 1, j) for i, j in zip(bins[:-1], bins[1:])]
labels[0] = '{}-{}'.format(bins[0], bins[1])
binned = pd.cut(data.Age, bins=bins, labels=labels, include_lowest=True, precision=0)
df = data.groupby(binned)['Score'].mean().reset_index()
df

2.png

但这感觉像是黑客行为,我认为应该有一个“正确”的解决方案,而不是黑客行为。虽然它解决了第二个问题,但我不确定这是否解决了第一个问题。


阅读 16

收藏
2024-12-30

共1个答案

小能豆

关于你在问题中提到的两个问题,它们都是由你的代码中的一行引起的,即

labels = ['{}-{}'.format(i + 1, j) for i, j in zip(bins[:-1], bins[1:])]

由此产生的空白i+1,以及同一行中计算机近似得到的数字。

因此,将其修改为

labels = [f'{i:.1f}-{j:.1f}' for i, j in zip(bins[:-1], bins[1:])]

其中我们将其近似为一位数字。

并且不需要labels[0] = '{}-{}'.format(bins[0], bins[1])

2024-12-30