在pandas(Python)中按id分组的数据帧中减去连续的行

时间:2016-06-10 11:11:20

标签: python pandas data-manipulation data-cleansing data-science

我有以下数据框:

.when("/alcohol", {
  redirectTo: "/alcohol/list"
});

我需要在day列中每两个连续时间减去它们是否具有相同的id,直到到达该id的最后一行然后开始减去day列中的时间这一次为新id,类似于输出中的后续行的东西是预期的:

id        day           total_amount
 1       2015-07-09         1000
 1       2015-10-22          100
 1       2015-11-12          200
 1       2015-11-27         2392
 1       2015-12-16          123
 7       2015-07-09          200
 7       2015-07-09         1000
 7       2015-08-27       100018
 7       2015-11-25         1000
 8       2015-08-27         1000
 8       2015-12-07        10000
 8       2016-01-18          796
 8       2016-03-31        10000
15       2015-09-10         1500
15       2015-09-30         1000

1 个答案:

答案 0 :(得分:3)

您可以使用DataFrameGroupBy.diff

df['dif'] = df.groupby('id')['day'].diff(-1) * (-1)
print (df)
    id        day  total_amount      dif
0    1 2015-07-09          1000 105 days
1    1 2015-10-22           100  21 days
2    1 2015-11-12           200  15 days
3    1 2015-11-27          2392  19 days
4    1 2015-12-16           123      NaT
5    7 2015-07-09           200   0 days
6    7 2015-07-09          1000  49 days
7    7 2015-08-27        100018  90 days
8    7 2015-11-25          1000      NaT
9    8 2015-08-27          1000 102 days
10   8 2015-12-07         10000  42 days
11   8 2016-01-18           796  73 days
12   8 2016-03-31         10000      NaT
13  15 2015-09-10          1500  20 days
14  15 2015-09-30          1000      NaT

apply shift的另一种解决方案:

df['diff'] = df.groupby('id')['day'].apply(lambda x: x.shift(-1) - x)
print (df)
    id        day  total_amount     diff
0    1 2015-07-09          1000 105 days
1    1 2015-10-22           100  21 days
2    1 2015-11-12           200  15 days
3    1 2015-11-27          2392  19 days
4    1 2015-12-16           123      NaT
5    7 2015-07-09           200   0 days
6    7 2015-07-09          1000  49 days
7    7 2015-08-27        100018  90 days
8    7 2015-11-25          1000      NaT
9    8 2015-08-27          1000 102 days
10   8 2015-12-07         10000  42 days
11   8 2016-01-18           796  73 days
12   8 2016-03-31         10000      NaT
13  15 2015-09-10          1500  20 days
14  15 2015-09-30          1000      NaT

通过评论编辑:

如果您需要将hours与[{1}}区别开来,请将int转换为timedelta

hour
df['diff'] = df.groupby('id')['day'].diff(-1) * (-1) / np.timedelta64(1, 'h')
print (df)
    id        day  total_amount    diff
0    1 2015-07-09          1000  2520.0
1    1 2015-10-22           100   504.0
2    1 2015-11-12           200   360.0
3    1 2015-11-27          2392   456.0
4    1 2015-12-16           123     NaN
5    7 2015-07-09           200     0.0
6    7 2015-07-09          1000  1176.0
7    7 2015-08-27        100018  2160.0
8    7 2015-11-25          1000     NaN
9    8 2015-08-27          1000  2448.0
10   8 2015-12-07         10000  1008.0
11   8 2016-01-18           796  1752.0
12   8 2016-03-31         10000     NaN
13  15 2015-09-10          1500   480.0
14  15 2015-09-30          1000     NaN