我有一个数据集(测试),其中包含几个包含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
但是,正如您所看到的,项目的不同持续时间使运行项目的视图变得重要。 所以我想要有四个酒吧[2000年,2001年,2002年,2003年,2004年]。 2001年的律师资格应该是A型(la,li,lu)的4倍,3倍和B型(le)的1倍。在这种情况下,案件不属于酒吧,因为它始于2002年。
那个(短/优雅)的解决方案是什么? 我错过了哪些关键字,我无法找到这样的解决方案?
答案 0 :(得分:1)
您可以使用range
和join
创建新系列到原始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)
对于新的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