我有一个数据框,我想将其按一列进行分组(即分组为子范围),然后对每个分组的第二列取平均值:
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
这种分箱方式存在 2 个问题:
(n-1)
n
precision=0
cut
x
precision=x
第二点会导致问题,例如,当我尝试绘制时df,它破坏了 x 轴的外观:
df
import matplotlib.pyplot as plt plt.plot([str(i) for i in df.Age], df.Score, 'o-')
precision=0尽管我放置了标记以暗示我只想要整数作为 bin 限制,而不是浮点数,但为什么还是会发生这种情况?我该如何修复它?
我通过int手动将 bin 值转换为 s 来暂时解决这个问题:
int
_, 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
但这感觉像是黑客行为,我认为应该有一个“正确”的解决方案,而不是黑客行为。虽然它解决了第二个问题,但我不确定这是否解决了第一个问题。
关于你在问题中提到的两个问题,它们都是由你的代码中的一行引起的,即
labels = ['{}-{}'.format(i + 1, j) for i, j in zip(bins[:-1], bins[1:])]
由此产生的空白i+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])
labels[0] = '{}-{}'.format(bins[0], bins[1])