Pandas 根据条件从一个位置跳到另一个位置的计数

Pandas 根据条件从一个位置跳到另一个位置的计数,pandas,python-3.5,pandas-groupby,Pandas,Python 3.5,Pandas Groupby,我有以下数据帧 id start finish location 0 1 2015-12-14 16:44:00 2015-12-15 18:00:00 A 1 1 2015-12-15 18:00:00 2015-12-16 13:00:00 B 2 1 2015-12-16 13:00:00 2015-12-16 20:00:00 C 3 2 2015-12-10 13:15:00 2015-12-12 13:45:00 B 4 2 2

我有以下数据帧

    id  start   finish  location
0   1   2015-12-14 16:44:00 2015-12-15 18:00:00 A
1   1   2015-12-15 18:00:00 2015-12-16 13:00:00 B
2   1   2015-12-16 13:00:00 2015-12-16 20:00:00 C
3   2   2015-12-10 13:15:00 2015-12-12 13:45:00 B
4   2   2015-12-12 13:45:00 2015-12-12 19:45:00 A
5   3   2015-12-15 07:45:00 2015-12-15 18:45:00 A
6   3   2015-12-15 18:45:00 2015-12-18 07:15:00 D
7   3   2015-12-18 07:15:00 2015-12-19 10:45:00 C
8   3   2015-12-19 10:45:00 2015-12-20 09:00:00 H
9   4   2015-12-09 10:45:00 2015-12-13 12:20:00 E
10  4   2015-12-13 12:20:00 2015-12-13 18:20:00 A
11  4   2015-12-13 18:20:00 2015-12-13 23:40:00 A
12  4   2015-12-13 23:40:00 2015-12-16 08:00:00 B
13  5   2015-12-07 08:00:00 2015-12-13 12:25:00 H
我想计算每个“id”中从一个位置到另一个位置的跳跃。对于这些跳转计数,首先我想将完成列的日期和时间与同一id的下一行的开始列的日期和时间进行比较。如果匹配,我想将计数设为1或0。我想得到的是:

    id  start   count
0   1   2015-12-14 16:44:00 1
1   1   2015-12-15 18:00:00 1
2   1   2015-12-16 13:00:00 0
3   2   2015-12-10 13:15:00 1
4   2   2015-12-12 13:45:00 0
5   3   2015-12-15 07:45:00 1
6   3   2015-12-15 18:45:00 1
7   3   2015-12-18 07:15:00 1
8   3   2015-12-19 10:45:00 0
9   4   2015-12-09 10:45:00 1
10  4   2015-12-13 12:20:00 1
11  4   2015-12-13 18:20:00 1
12  4   2015-12-13 23:40:00 0
13  5   2015-12-07 08:00:00 0
date    count_sum
2015-12-07  0
2015-12-09  1
2015-12-10  1
2015-12-12  0
2015-12-13  2
2015-12-14  1
2015-12-15  3
2015-12-16  0
2015-12-18  1
2015-12-19  0
一旦我有了这些,我想根据日期对计数求和,得到如下结果:

    id  start   count
0   1   2015-12-14 16:44:00 1
1   1   2015-12-15 18:00:00 1
2   1   2015-12-16 13:00:00 0
3   2   2015-12-10 13:15:00 1
4   2   2015-12-12 13:45:00 0
5   3   2015-12-15 07:45:00 1
6   3   2015-12-15 18:45:00 1
7   3   2015-12-18 07:15:00 1
8   3   2015-12-19 10:45:00 0
9   4   2015-12-09 10:45:00 1
10  4   2015-12-13 12:20:00 1
11  4   2015-12-13 18:20:00 1
12  4   2015-12-13 23:40:00 0
13  5   2015-12-07 08:00:00 0
date    count_sum
2015-12-07  0
2015-12-09  1
2015-12-10  1
2015-12-12  0
2015-12-13  2
2015-12-14  1
2015-12-15  3
2015-12-16  0
2015-12-18  1
2015-12-19  0

对我来说,最后一部分很容易做到,根据日期执行groupby(),并使用.sum()汇总该日期的所有计数。但是如何得到第一部分,我们计算实际的跳跃还不清楚。任何帮助都将不胜感激

您的数据似乎已经按
'start'
排序,因此您可以使用
pandas.Series.shift()检查完成时间是否与下一行的开始时间相同

我建议不要调用列
“count”
,因为这是pandas的内置函数,所以不能使用
Series.colu name
表示法

#df['start'] = pd.to_datetime(df.start)
#df['finish'] = pd.to_datetime(df.finish)
df['count'] = (df.groupby('id').apply(lambda x: x.finish == x.start.shift(-1))
                 .astype('int').reset_index(level=0, drop=True))
输出:

    id               start              finish location  count
0    1 2015-12-14 16:44:00 2015-12-15 18:00:00        A      1
1    1 2015-12-15 18:00:00 2015-12-16 13:00:00        B      1
2    1 2015-12-16 13:00:00 2015-12-16 20:00:00        C      0
3    2 2015-12-10 13:15:00 2015-12-12 13:45:00        B      1
4    2 2015-12-12 13:45:00 2015-12-12 19:45:00        A      0
5    3 2015-12-15 07:45:00 2015-12-15 18:45:00        A      1
6    3 2015-12-15 18:45:00 2015-12-18 07:15:00        D      1
7    3 2015-12-18 07:15:00 2015-12-19 10:45:00        C      1
8    3 2015-12-19 10:45:00 2015-12-20 09:00:00        H      0
9    4 2015-12-09 10:45:00 2015-12-13 12:20:00        E      1
10   4 2015-12-13 12:20:00 2015-12-13 18:20:00        A      1
11   4 2015-12-13 18:20:00 2015-12-13 23:40:00        A      1
12   4 2015-12-13 23:40:00 2015-12-16 08:00:00        B      0
13   5 2015-12-07 08:00:00 2015-12-13 12:25:00        H      0
为了完整起见:

df.groupby(df.start.dt.date)['count'].sum()
start
2015-12-07    0
2015-12-09    1
2015-12-10    1
2015-12-12    0
2015-12-13    2
2015-12-14    1
2015-12-15    3
2015-12-16    0
2015-12-18    1
2015-12-19    0

哇,太好了!我想你要么想确保
df
是按
['id',start']
排序的,要么在groupby之后使用
.sort\u index
,这样就不会弄乱行顺序了?你好,非常感谢。结果很完美。是的,数据帧已经根据id和start进行了排序。谢谢你的建议。我不知道使用列名“count”会有问题。从现在起,我将避免使用“count”作为列名。虽然您的代码工作得很好,但我不明白为什么代码中的lambda函数在满足条件时返回1,否则返回0。您能否解释一下如何在计数列中得到1和0?提前感谢。@HT121,如果finish值等于下一行的start值(移位完成与下一行的比较),lambda函数将返回
True
False
。然后得到
1
0
,因为我使用了
.astype('int')
,它将
True
转换为
1
False
转换为
0