2017-09-15 110 views
1

一个GROUPBY操作我有这样的示例表的结果:情节大熊猫

ID Date  Days Volume/Day 
0 111 2016-01-01 20 50 
1 111 2016-02-01 25 40 
2 111 2016-03-01 31 35 
3 111 2016-04-01 30 30 
4 111 2016-05-01 31 25 
5 111 2016-06-01 30 20 
6 111 2016-07-01 31 20 
7 111 2016-08-01 31 15 
8 111 2016-09-01 29 15 
9 111 2016-10-01 31 10 
10 111 2016-11-01 29 5 
11 111 2016-12-01 27 0 
0 112 2016-01-01 31 55 
1 112 2016-02-01 26 45 
2 112 2016-03-01 31 40 
3 112 2016-04-01 30 35 
4 112 2016-04-01 31 30 
5 112 2016-05-01 30 25 
6 112 2016-06-01 31 25 
7 112 2016-07-01 31 20 
8 112 2016-08-01 30 20 
9 112 2016-09-01 31 15 
10 112 2016-11-01 29 10 
11 112 2016-12-01 31 0 

我试图让我的表格最后的表像这样通过ID和日期分组后下方。

ID Date  CumDays Volume/Day 
0 111 2016-01-01 20  50 
1 111 2016-02-01 45  40 
2 111 2016-03-01 76  35 
3 111 2016-04-01 106  30 
4 111 2016-05-01 137  25 
5 111 2016-06-01 167  20 
6 111 2016-07-01 198  20 
7 111 2016-08-01 229  15 
8 111 2016-09-01 258  15 
9 111 2016-10-01 289  10 
10 111 2016-11-01 318  5 
11 111 2016-12-01 345  0 
0 112 2016-01-01 31  55 
1 112 2016-02-01 57  45 
2 112 2016-03-01 88  40 
3 112 2016-04-01 118  35 
4 112 2016-05-01 149  30 
5 112 2016-06-01 179  25 
6 112 2016-07-01 210  25 
7 112 2016-08-01 241  20 
8 112 2016-09-01 271  20 
9 112 2016-10-01 302  15 
10 112 2016-11-01 331  10 
11 112 2016-12-01 362  0 

接着,我希望能够以提取音量/每ID天,所有的CumDays值和每个ID和日期的所有容积/日的值的第一个值。因此,我可以将它们用于进一步计算并绘制Volume/Day vs CumDays。 ID为111的例子,Volume/Day的第一个值将只有50,ID:112,它将只有55. ID:111的所有CumDays值将是20,45 ...和ID:112,它会是31,57 ...对于所有批量/天--- ID:111,将在50,40 ...和ID:112将55,45 ...

我的解决办法:

def get_time_rate(grp_df): 
    t = grp_df['Days'].cumsum() 
    r = grp_df['Volume/Day'] 
    return t,r 

vals = df.groupby(['ID','Date']).apply(get_time_rate) 
vals 

这样做,累计计算根本不起作用。它返回原始的Days值。这不允许我进一步提取Volume/Day的第一个值,所有CumDays值和我需要的所有Volume/Day值。任何意见或帮助如何去解决它将不胜感激。谢谢

+0

你为什么要张贴HTML吗?这是你如何接收你的数据? – piRSquared

+0

@piRSquared,no。这是我组织它,所以它可以在S.O.上看到。有没有其他更好的方法来显示S.O的表格,除了用html形式表示它或拍摄它的照片? – dlvr

+0

我们所看到的只是原始HTML,除非我们点击运行代码片段。请粘贴数据文本并突出显示该文本,然后单击与{{}}相似的按钮。这将使每行缩进四个空格。反过来以便利的方式呈现您的餐桌,以便我们帮助您 – piRSquared

回答

2

获取groupby对象。

g = df.groupby('ID') 

计算列与transform

df['CumDays'] = g.Days.transform('cumsum') 
df['First Volume/Day'] = g['Volume/Day'].transform('first') 
df 

    ID  Date Days Volume/Day CumDays First Volume/Day 
0 111 2016-01-01 20   50  20    50 
1 111 2016-02-01 25   40  45    50 
2 111 2016-03-01 31   35  76    50 
3 111 2016-04-01 30   30  106    50 
4 111 2016-05-01 31   25  137    50 
5 111 2016-06-01 30   20  167    50 
6 111 2016-07-01 31   20  198    50 
7 111 2016-08-01 31   15  229    50 
8 111 2016-09-01 29   15  258    50 
9 111 2016-10-01 31   10  289    50 
10 111 2016-11-01 29   5  318    50 
11 111 2016-12-01 27   0  345    50 
0 112 2016-01-01 31   55  31    55 
1 112 2016-01-02 26   45  57    55 
2 112 2016-01-03 31   40  88    55 
3 112 2016-01-04 30   35  118    55 
4 112 2016-01-05 31   30  149    55 
5 112 2016-01-06 30   25  179    55 
6 112 2016-01-07 31   25  210    55 
7 112 2016-01-08 31   20  241    55 
8 112 2016-01-09 30   20  271    55 
9 112 2016-01-10 31   15  302    55 
10 112 2016-01-11 29   10  331    55 
11 112 2016-01-12 31   0  362    55 

如果你想组合图,您可以通过ID分组后在各组迭代。要绘制,首先设置索引并致电plot

fig, ax = plt.subplots(figsize=(8,6)) 
for i, g in df2.groupby('ID'): 
    g.plot(x='CumDays', y='Volume/Day', ax=ax, label=str(i)) 

plt.show() 

enter image description here

+0

@COLDSPEED的悬挂,感谢您的及时响应。代码工作,选择第一个值和所有的值。但是,情节是否可以通过身份证分开,而不是像现在一样加入到一起。所以每个ID都有它自己的情节。在这种情况下,2个地块。那可能吗?谢谢 – dlvr

+0

@dlvr使用单独的行编辑解决方案。 –

+0

@COLDSPEED,我的意思是,单独的图表。一个图表为111,第二个图表为112.这可能吗?谢谢 – dlvr