我知道可以使用Pandas绘制直方图:
df4 = pd.DataFrame({'a': np.random.randn(1000) + 1})
df4['a'].hist()
但是我该如何从这样的图中获取直方图计数?
我知道可以通过以下方法实现(来自Pandas系列的直方图值)
count,division = np.histogram(df4['a'])
在使用df.hist()
之后获取计数值感觉非常冗余。是否可以直接从pandas中获取频率值?
我知道可以使用Pandas绘制直方图:
df4 = pd.DataFrame({'a': np.random.randn(1000) + 1})
df4['a'].hist()
但是我该如何从这样的图中获取直方图计数?
我知道可以通过以下方法实现(来自Pandas系列的直方图值)
count,division = np.histogram(df4['a'])
在使用df.hist()
之后获取计数值感觉非常冗余。是否可以直接从pandas中获取频率值?
简短回答如下:
pd.cut(df4['a'], 10).value_counts().sort_index()
根据文档的描述:
所以看一下bins: integer, default 10 Number of histogram bins to be used
pd.cut(df4['a'], 10).value_counts()
,你会发现这些值与np.histogram
的相同。
这是在pandas中计算直方图的另一种方法。它更加复杂,但我认为更好,因为你可以避免使用pd.cut
返回的奇怪字符串型的区间,这会破坏任何绘图。同时,使用.pipe()
也能让你获得风格上的加分:
(df['a']
.pipe(lambda s: pd.Series(np.histogram(s, range=(0, 100), bins=20)))
.pipe(lambda s: pd.Series(s[0], index=s[1][:-1]))
)
然后你可以在末尾添加更多的内容,例如:
.pipe(lambda s: s/s.sum())
这将给你一个分布。
理想情况下,pd.hist
中会有一个明智的 density
,可以为您完成此操作。 Pandas
确实有一个 density=False
关键字,但它是荒谬的。我已经阅读了无数次的解释,比如 this one,但我从来没有理解过它,也不知道谁会真正使用它。当您在直方图上看到分数时,99.9%的时间您会认为是“分布”,而不是 density=True
实际计算的 np.sum(pdf * np.diff(bins))
。这让你想哭。
count, division = df4['a'].hist()
这样的事情会很棒。这样可以更方便,而且不需要额外的代码。 - ZK Zhao