Pandas Python 按子组绘制条形图
好的,我有一个数据框对象,它的索引是这样的:
index, rev, metric1 (more metrics.....)
exp1, 92365, 0.018987
exp2, 92365, -0.070901
exp3, 92365, 0.150140
exp1, 87654, 0.003008
exp2, 87654, -0.065196
exp3, 87654, -0.174096
对于这些指标,我想创建单独的堆叠条形图,比较它们的收入。
这是我尝试过的:
df = df[['rev', 'metric1']]
df = df.groupby("rev")
df.plot(kind = 'bar')
这样做的结果是两个单独的条形图。理想情况下,我希望这两个图合并成一个堆叠的图(现在设置堆叠为true没有任何效果)。如果能帮忙解决这个问题,我会非常感激。
这将给我理想的结果,不过我觉得为了达到这个目标而重新组织数据并不是最好的方法,因为我有很多指标和很多修订。
index, metric1(rev87654), metric1(rev92365)
exp1, 0.018987, 0.003008
exp2, -0.070901, -0.065196
exp3, 0.150140, -0.174096
这是我的目标。(手动制作的)
2 个回答
0
接下来是关于这个 matplotlib 示例的内容:
在这个示例中,他们通过对每一组数据调用一次 bar 函数来绘制多个柱状图。
你可以通过以下方式在 pandas 中访问这些值:
fig, ax = subplots(figsize=(16.2,10),dpi=300)
Y = Tire2[Tire2.SL==Tire2.SL.unique()[0]].SA.values[0:13]
X = linspace(0,size(Y),size(Y))
ax.bar(X,Y,width=.4)
Y = Tire2[Tire2.SL==Tire2.SL.unique()[2]].SA.values[0:13]
X = linspace(0,size(Y),size(Y))+.5
ax.bar(X,Y,width=.4,color='r')
从内到外来理解:
- 先获取某一列(在你的情况下是 rev 列)中所有独特的 'SL' 值。
- 得到一个布尔向量,表示所有 'SL' 等于第一个(或第 n 个)独特值的行。
- 用这个布尔向量来索引 Tire 数据,这样就只会提取出布尔向量为
True
的那些行。 - 访问
SA
的值,或者在你的情况下的某个指标。(我只取了 `[0:13]` 的值,因为我在一个很大的数据集上测试这个) - 把这些值绘制成柱状图。
如果你的实验数据在框架中是有序的(就像展示的那样),那就没问题。否则,你可能需要稍微排序一下,以确保 Y 值的顺序正确。使用 .sort(列名)
就可以解决这个问题。在我的代码中,我会把它放在 ...[0]]
和 .SA...
之间。
总的来说,这种操作在处理大数据框时非常有帮助。.between
方法也很实用。而且你可以随时对布尔向量进行加法、乘法等操作,以构建更复杂的逻辑。
0
我不太确定如何能自动生成你想要的图,而不需要按照你最后提到的那样进行具体的重新组织。用户user3823992的回答可以让你对图表有更详细的控制,但如果你想要更自动化的方式,这里有一些临时的重新组织方法,可以使用类似的索引,同时也把结果合并回一个数据框,这样就能为你生成图表了。
import numpy as np
import pandas as pd
exp = ['exp1','exp2','exp3']*2
rev = [1,1,1,2,2,2]
met1 = np.linspace(-0.5,1,6)
met2 = np.linspace(1.0,5.0,6)
met3 = np.linspace(-1,1,6)
df = pd.DataFrame({'rev':rev, 'met1':met1, 'met2':met2, 'met3':met3}, index=exp)
for met in df.columns:
if met != 'rev':
merged = df[df['rev'] == df.rev.unique()[0]][met]
merged.name = merged.name+'rev'+str(df.rev.unique()[0])
for rev in df.rev.unique()[1:]:
tmp = df[df['rev'] == rev][met]
tmp.name = tmp.name+'rev'+str(rev)
merged = pd.concat([merged, tmp], axis=1)
merged.plot(kind='bar')
这样应该能给你生成三个图,每个图对应我虚构的一个指标。
编辑:或者类似这样的方式也可能有效
df['exp'] = df.index
pt = pd.pivot_table(df, values='met1', rows=['exp'], cols=['rev'])
pt.plot(kind='bar')