我知道有人问过 this similar question;但是,如果可能的话,我正在寻找进一步的澄清以更好地理解 .groupby。 Data used
我想要完全相同的结果,但使用 .groupby():
df.pivot(columns='survived').age.plot.hist()
所以我尝试:
df.groupby('age')['survived'].count().plot.hist()
x 轴看起来不对。有什么方法可以使用纯 .groupby() 方法获得与 .pivot() 相同的结果吗?谢谢。
答案 0 :(得分:1)
我赞成这个问题,因为 pivot
和 groupby
之间存在非常细微的区别。我认为您正在寻找与此类似的内容:
df.groupby('age').size().plot.bar(width=1)
plt.show()
但是,我不认为通过分组获得相同结果的合理方法是因为 hist()
需要原始形式的观察,而 groupby
被设计为跟随一个函数,该函数将转换数据(例如 count
、min
、mean
等)。
要看到这一点,请注意通过按 age
分组然后使用 count
,您不再拥有年龄的原始数组。例如,对 40 岁的人进行了 13 次观察。原始数据看起来像 (40, 40, ... , 40, 40)
,而分组计数看起来像:
age count
40 13
这不是直方图的数据应该是什么样子。另一个关键区别是直方图中的 bin。如您所见,第一个图计算了年龄在 0 到 10 岁之间的人的所有观察值。通过按年龄分组,您将在这个 bin 内有 11 个 bin:一个用于 0 岁的人,一个用于 1 岁的人,一个用于人2岁等
总而言之,groupby
需要一个可以转换原始数据的函数,但是为了绘制直方图,您需要原始状态的数据。因此,pivot
是此类任务的首选解决方案,因为它还按 survived
拆分数据,但不对数据应用任何函数。
答案 1 :(得分:1)
扩展 Quang 的评论,您可能希望对年龄进行分组,而不是按每个年龄分组(这就是 df.groupby('age')
所做的)。
一种方法是cut
age
箱:
df['age group'] = pd.cut(df.age, bins=range(0, 100, 10), right=False)
然后 groupby
这些 bin 并制作 survived.value_counts()
的条形图:
(df.groupby('age group').survived.value_counts()
.unstack().plot.bar(width=1, stacked=True))
我注意到在您发布的链接中,所有直方图看起来都有些不同。我认为这是由于每种方法的分类方式略有不同。切割自己的 bin 的优势之一是您可以清楚地看到确切的 bin 边界: