熊猫:绘制正在运行的项目

时间:2017-12-14 12:38:34

标签: python pandas bar-chart

我有一个数据集(测试),其中包含几个包含theyer Typ,theier Beginning和theier End的项目的信息:

$students = \App\Student::whereDoesntHave('academics')
->orWhereHas('academics',function($q) use ($academic){
  $q->where('id',$academic->id)->count();
},'=',0)->get();

我想绘制每年按类型堆放的正在运行的项目。

我能够生成一个Projekt的开始或结束的图表,这样做:

ID   Name  Type  Start   End
1    la    A     2000    2003
2    le    B     2001    2002
3    li    A     2001    2004
4    lo    B     2002    2003
5    lu    A     2001    2002

Stacked Strat new

但是,正如您所看到的,项目的不同持续时间使运行项目的视图变得重要。 所以我想要有四个酒吧[2000年,2001年,2002年,2003年,2004年]。 2001年的律师资格应该是A型(la,li,lu)的4倍,3倍和B型(le)的1倍。在这种情况下,案件不属于酒吧,因为它始于2002年。

那个(短/优雅)的解决方案是什么? 我错过了哪些关键字,我无法找到这样的解决方案?

1 个答案:

答案 0 :(得分:1)

您可以使用rangejoin创建新系列到原始df

s = (df.apply(lambda x: pd.Series(range(x['Start'], x['End'] + 1)), 1)
      .stack()
      .rename('year')
      .reset_index(level=1, drop=True)
      .astype(int))
df = df.join(s)
print (df)

   ID Name Type  Start   End  year
0   1   la    A   2000  2003  2000
0   1   la    A   2000  2003  2001
0   1   la    A   2000  2003  2002
0   1   la    A   2000  2003  2003
1   2   le    B   2001  2002  2001
1   2   le    B   2001  2002  2002
2   3   li    A   2001  2004  2001
2   3   li    A   2001  2004  2002
2   3   li    A   2001  2004  2003
2   3   li    A   2001  2004  2004
3   4   lo    B   2002  2003  2002
3   4   lo    B   2002  2003  2003
4   5   lu    A   2001  2002  2001
4   5   lu    A   2001  2002  2002

df.groupby(['year','Type']).size().unstack(fill_value=0)
  .plot(kind='bar', legend=False, stacked=True)

graph

对于新的DataFrame,也可以使用列表理解:

d = [(x['Type'], y) for i, x in df.T.items() for y in range(x['Start'], x['End'] + 1)]
print (d)
[('A', 2000), ('A', 2001), ('A', 2002), ('A', 2003), ('B', 2001), 
 ('B', 2002), ('A', 2001), ('A', 2002), ('A', 2003), ('A', 2004), 
 ('B', 2002), ('B', 2003), ('A', 2001), ('A', 2002)]

与循环版本相同:

d = []
for i, x in df.T.items():
    a = range(x['Start'], x['End'] + 1)
    for y in a:
        d.append((x['Type'], y))

然后DataFrame contructor:

df = pd.DataFrame(d, columns=['Type','year'])
print (df)
   Type  year
0     A  2000
1     A  2001
2     A  2002
3     A  2003
4     B  2001
5     B  2002
6     A  2001
7     A  2002
8     A  2003
9     A  2004
10    B  2002
11    B  2003
12    A  2001
13    A  2002