plt.hist()vs np.histogram() - 出乎意料的结果

KOB*_*KOB 6 python numpy matplotlib histogram binning

以下几行

a1, b1, _ = plt.hist(df['y'], bins='auto')
a2, b2 = np.histogram(df['y'], bins='auto')

print(a1 == a2)
print(b1 == b2)
Run Code Online (Sandbox Code Playgroud)

等同于的所有值a1等于那些a2与同为b1b2

然后我pyplot单独创建一个绘图(使用bins=auto 应该使用相同的np.histogram()函数):

plt.hist(df['y'], bins='auto')
plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

然后我尝试实现相同的直方图,但通过调用np.histogram()自己,并将结果传递给plt.hist(),但我得到一个空白的直方图:

a2, b2 = np.histogram(df['y'], bins='auto')
plt.hist(a2, bins=b2)
plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

根据我的理解,plt.hist(df['y'], bins='auto')我正在创建的这两个图应该完全相同 - 为什么我的使用方法不是Numpy

编辑

接下来来自@ MSeifert的回答,我相信

counts, bins = np.histogram(df['y'], bins='auto')
Run Code Online (Sandbox Code Playgroud)

bins是每个bin的起始值的列表,并且counts是每个bin 中相应的值的数量.如上面的直方图所示,这应该产生近乎完美的正态分布,但是,如果调用print(counts, bins) 结果counts显示第一个和最后一个分箱具有相当大的~11,000个数.为什么这不会反映在直方图中 - 为什么两条尾部都没有两个大的尖峰?

编辑2

这只是一个分辨率问题,我的情节看起来太小了,两端的尖峰都无法正确渲染.放大允许它们显示.

MSe*_*ert 8

您假设plt.hist可以区分包含计数值的数组和包含要计数的的数组.

然而,这不是发生的事情,当您将计数传递给plt.hist它时,它将计算它们并将它们放在提供的箱中.这可能导致空的直方图,但也会导致奇怪的直方图.

因此,尽管plt.histnumpy.histogram这两个工作一样,你不能只是通过从获得的数据numpy.histogramplt.hist,因为这将算值(你期望不算什么)的计数:

import numpy as np
import matplotlib.pyplot as plt

%matplotlib notebook

f, ax = plt.subplots(1)
arr = np.random.normal(10, 3, size=1000)
cnts, bins = np.histogram(arr, bins='auto')
ax.hist(cnts, bins=bins)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

但是,您可以使用bar绘图来对通过numpy.histogram以下方式获得的直方图进行虚拟化:

f, (ax1, ax2) = plt.subplots(2)
cnts, bins = np.histogram(arr, bins='auto')
ax1.bar(bins[:-1] + np.diff(bins) / 2, cnts, np.diff(bins))
ax2.hist(arr, bins='auto')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述