在pandas

时间:2017-09-15 01:33:07

标签: python pandas matplotlib dataframe group-by

我有这个样本表:

    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的Volume / Day的第一个值,所有CumDays值以及每个ID和Date的所有Volume / Day值。所以我可以用它们进行进一步的计算并绘制Volume / Day和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值。这并没有让我进一步提取卷/日的第一个值,所有CumDays值以及我需要的所有Volume / Day值。任何有关如何去做的建议或帮助将不胜感激。感谢

1 个答案:

答案 0 :(得分:3)

获取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