75

我想通过让 Y 轴显示每列在整个数据集大小中的百分比而不是绝对值来比较两个直方图。那可能吗?我正在使用熊猫和 matplotlib。谢谢

4

6 回答 6

90

( density=Truefor ) 返回一个等于 1 的直方图normed=True。如果您希望直方图的总和为 1,您可以使用 Numpy 的 histogram() 并自己对结果进行归一化。matplotlib < 2.2.0np.sum(pdf * np.diff(bins))

x = np.random.randn(30)

fig, ax = plt.subplots(1,2, figsize=(10,4))

ax[0].hist(x, density=True, color='grey')

hist, bins = np.histogram(x)
ax[1].bar(bins[:-1], hist.astype(np.float32) / hist.sum(), width=(bins[1]-bins[0]), color='grey')

ax[0].set_title('normed=True')
ax[1].set_title('hist = hist / hist.sum()')

在此处输入图像描述

顺便说一句:左图的第一个 bin 出现奇怪的绘图故障。

于 2013-07-26T09:01:44.683 回答
27

Pandas 绘图可以接受来自相应 matplotlib 函数的任何额外关键字参数。因此,从这里其他人的评论来看,这是一个完整的做法:

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(100,2), columns=list('AB'))

df.hist(density=1)

此外,对于直接比较,这也可能是一个好方法:

df.plot(kind='hist', density=1, bins=20, stacked=False, alpha=.5)
于 2015-09-23T20:02:57.183 回答
20

看起来@CarstenKönig找到了正确的方法

df.hist(bins=20, weights=np.ones_like(df[df.columns[0]]) * 100. / len(df))
于 2016-01-13T01:34:43.230 回答
17

我知道这个答案是 6 年后的事,但对于任何使用密度 = True(normed = True 的替代品)的人来说,这并不是你想做的。它将对整个分布进行归一化,使箱的面积为 1。因此,如果您有更多宽度 < 1 的箱,则可以预期高度 > 1(y 轴)。如果要将直方图绑定到 [0;1],则必须自己计算。

于 2019-11-20T04:09:57.767 回答
10

您可以使用np.ones_like()简化权重:

df["ColumnName"].plot.hist(weights = np.ones_like(df.index) / len(df.index))
  • np.ones_like() 可以使用 df.index 结构
  • len(df.index) 对于大型 DataFrame 更快
于 2017-05-13T08:45:03.960 回答
2

我认为这是一个老问题,但它在某些搜索中显示在顶部,所以我认为从 2021 年开始,seaborn 将是一种简单的方法。

你可以这样做:

import seaborn as sns
sns.histplot(df,stat="probability")
于 2021-06-30T14:25:39.237 回答