Pandas python barplot由子组

时间:2014-07-22 01:05:55

标签: python matplotlib pandas

好的,我有一个数据框对象的索引如下:

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') 

这会生成2个单独的指标条形图。理想情况下,我会将这两个合并和堆叠(现在堆叠=真不做任何事情)。任何帮助将不胜感激。

这会给我理想的结果,但我不认为重新组织以适应这是实现目标的最佳方式,因为我有很多指标和许多修订。

index,   metric1(rev87654), metric1(rev92365)
exp1,    0.018987,          0.003008 
exp2,   -0.070901,         -0.065196
exp3,    0.150140,         -0.174096

这是我的目标。 (手工制作)

http://i.stack.imgur.com/5GRqB.png

2 个答案:

答案 0 :(得分:0)

从这个matplotlib库示例开始: http://matplotlib.org/examples/api/barchart_demo.html

他们通过为每个集合调用一次来获得多个绘图。

您可以使用索引操作在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')

从内到外工作:

  1. 获取' SL'的所有独特价值在其中一个cols(你的情况下为rev)
  2. 获取所有行的布尔向量,其中' SL'等于第一个(或第n个)唯一值
  3. 索引轮胎的布尔向量(这将仅拉出向量为True的行
  4. 访问SA的值或您的案例中的指标。 (只采用了'[0:13]'值,因为我在一个庞大的数据集上测试了这个值)
  5. 条形图那些值
  6. 如果你的实验在框架中按顺序排列(如图所示)那就是那个。否则,您可能需要运行一些排序以正确的顺序获取Y值。 .sort(column name)应该照顾好这一点。在我的代码中,我会在...[0]].SA...

    之间滑动它

    一般来说,这种操作可以真正帮助你解决大框架问题。 .between很有用。您可以随时添加,乘以布尔向量以构造更复杂的逻辑。

答案 1 :(得分:0)

我不确定如何在不完全完成您最后指定的重组的情况下自动获取所需的图表。 user3823992的答案为您提供了更详细的图表控制,但如果您希望它们更自动,这里是一些临时重组,应该使用类似的索引,但也可以连接回一个将为您完成绘图的DataFrame。

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')