【问题标题】:Plot average on subplots (pandas)在子图上绘制平均值(熊猫)
【发布时间】:2016-08-24 07:20:30
【问题描述】:

我已经设法从 groupby 中绘制子图。我有两列“A”和“B”,我想在子图上绘制它们(“B”中的每个值 1 个)及其各自的平均值。 我通过计数、删除重复项然后总结来准备我的数据(如果有更优雅的方法,请告诉我!)。

df = pd.DataFrame([[1, 'cat1'], [1, 'cat1'], [4, 'cat2'], [3, 'cat1'], [5, 'cat1'],[1, 'cat2']], columns=['A', 'B'])
df = df[['A','B']]
df['count'] = df.groupby(['A','B'])['A'].transform('count')
df = df.drop_duplicates(['A','B'])
df = df.groupby(['A','B']).sum()

然后我将它拆开并用子图绘制它:

plot = df.unstack().plot(kind='bar',subplots=True, sharex=True, sharey=True, layout = (3,3), legend=False)
plt.show(block=True)

我想为每个类别添加平均值,但我不知道: 1. 如何计算平均值。如果我在未堆叠的 groupby 上计算它,我会得到计数的平均值,而不是值“A”。 2. 一旦我得到平均值,我不知道如何将它绘制在同一个子图上。

欢迎任何帮助:)

--

按照 Nickil Maveli 的回答进行编辑: 我想要实现的是在 A 上绘制分组值的条形图,并在 B 上绘制一条带有平均值的垂直线。所以使用 Nickil Maveli 的图表,这将是:

根据我在 stackexchange 上的发现,我认为我应该使用 plt.axvline(mean, color='r', linestyle='--')。但是,我不知道如何调用每个情节的平均值不同。

【问题讨论】:

  • 您可以添加数据样本吗?请查看How to make good reproducible pandas examples
  • df = df_plot_zoom_cs.drop_duplicates(['A','B']) 行完全覆盖了df,在此之前的一切都不再重要。这表明您没有验证您发布的代码是否有效。请参阅stackoverflow.com/help/mcve 获取有关如何发布问题的指导。
  • @piRSquared - 我认为这只是错字,原始数据农场被称为 df_plot_zoom_cs 并且 OP 忘记更改它。
  • @jezrael 我应该更好;-)
  • 哎呀,是的,会改变的!

标签: python pandas matplotlib plot


【解决方案1】:

IIUC,您可以在平均值和计数上使用agg 来预先计算平均值和计数。

df_1 = df.groupby(['A', 'B'])['A'].agg({'counts': 'count'}).reset_index()
df_2 = df.groupby('B')['A'].agg({'average': 'mean'}).reset_index()

在 B 列之后是 DF.merge,因为它是两个 groupby 操作中的公共列。然后,可以删除 A 列和 B 列之间的重复条目。

df = df_1.merge(df_2, on='B').drop_duplicates(['A', 'B'])
df.drop('average', axis=1, inplace=True)
df = df.groupby(['A','B']).sum()

修改第二个数据框,让 A 列取平均值。

df_2['A'] = df_2['average']
df_2 = df_2.groupby(['A','B']).sum()

使用布局和定位多个轴。

fig, ax = plt.subplots(2, 2, figsize=(8, 8))

target1 = [ax[0][0], ax[0][1]]
target2 = [ax[1][0], ax[1][1]]

按分组计数。

df.unstack().plot(kind='bar', subplots=True, rot=0, xlim=(0,5), ax=target1,
                            ylim=(0,3), layout=(2,2), legend=False)

平均分组图。

df_2.unstack().plot(kind='bar', width=0.005, subplots=True, rot=0, xlim=(0,5), ax=target2,
                    ylim=(0,3), layout=(2,2), legend=False, color='k')

调整子图之间的间距。

plt.subplots_adjust(wspace=0.5, hspace=0.5)
plt.show()

【讨论】:

  • 谢谢,差不多了 :) 你帮我看看为什么我不清楚:我想计算 'A' 和 'B' 上的 'mean',如下所示:df[' count'] = df.groupby(['A','B'])['A'].transform('count') df['mean'] = df.groupby(['A', 'B'] )['B'].transform('mean') 两个虚拟数据的均值都是 2.5,所以我想在两个子图上绘制一条 2.5 的垂直线。
  • @MikeAtomat:请查看我的编辑回复,看看这是否确实是您想要的。
  • 谢谢!我编辑了我的问题以放一张图片。我试图在同一张图上画一条线:)
  • 我已经为您提供了您所需要的。我想你可以从这里开始 :-)
  • 哇,太好了,谢谢!我设法将它们放在同一个图表上(使用相同的目标),但现在两组图表(绘制在同一个子图上)对 x 轴使用不同的开始和结束值。它们在代码的绘图行中具有相同的 xlim 和 ylim。我还必须设置df_2['B'] = maxcount,否则它们太小了:) 我尝试使用ax[0][0].set_xlim(xmin=0, xmax=14)。我的 A 值在 7 到 21 之间,平均在 11 到 13 之间;现在他们正在密谋,但不是在正确的地方。有什么线索吗? :)
猜你喜欢
  • 2017-11-28
  • 2015-09-11
  • 1970-01-01
  • 2018-04-19
  • 2017-01-28
  • 2023-02-17
  • 2018-09-20
  • 2022-01-23
相关资源
最近更新 更多