python - 如何将公交车进/出站记录汇总到行程中以提供唯一ID,并删除时间差小的重复记录?
问题描述
我每天有一条公交线路的数据集,其中有 32 辆公交车和两辆公交车route_direction(0,1)
,在第一个方向有 18 个车站,每个车站有一个从 1 到 18 的序列,另一个方向有 15 个带有 seq(1-15) 的车站并记录时间进入/退出每个车站。每条记录包含 bus_id、route_direction、station_seq、in_time、out_time、station_id。
在此处输入图像描述
route_id route_direction bus_id station_seq schdeule_date in_time out_time
0 59 1 1349508393 2 2021-01-01 05:04:31 05:04:58
1 59 1 1349508393 2 2021-01-01 05:04:27 05:04:58
2 59 1 1349508393 2 2021-01-01 05:04:31 05:06:31
3 59 1 1349508393 2 2021-01-01 05:04:27 05:06:31
4 59 1 1349508393 1 2021-01-01 05:00:35 05:00:56
首先,我尝试对某个列进行分组,以便为每次旅行提供索引:
grouped = df.groupby(['bus_id', 'route_direction'])
我在这张图片中得到类似的东西 在此处输入图片描述:
index route_id route_direction bus_id station_seq schdeule_date in_time out_time
654 59 0 1349508329 1 2021-01-01 NaN 06:34:10
663 59 0 1349508329 2 2021-01-01 06:33:34 06:34:04
664 59 0 1349508329 2 2021-01-01 06:33:33 06:34:04
677 59 0 1349508329 2 2021-01-01 06:33:34 06:35:34
678 59 0 1349508329 2 2021-01-01 06:33:33 06:35:34
... ... ... ... ... ... ... ...
12133 59 0 1349508329 12 2021-01-01 NaN NaN
正如您所看到的,在几乎相同的日期和时间,同一个车站也有相同的 bus_id 进入出口的重复项:我尝试过删除重复项,但运气不好:
df = df.drop_duplicates(subset=['bus_id', 'route_direction', 'station_seq', 'station_id', 'in_time'], keep='first').reset_index(drop=True)
在 in_time 或 out_time 中也有一些 NaN 值,所以如果我 dropna ,那么我可能会错过公交线路沿线车站之一的记录。
在一次旅行中对每条巴士记录进行分组以赋予其 ID 有什么帮助,在这种情况下如何删除重复的记录(进入时间略有不同)?任何帮助将不胜感激。
解决方案
- 带有 'bus_id' 和 'in_time' 的 sort_values
- groupby 'bus_id',对于每个 bus_id,计算每个记录与它的前一个记录的时间差异
- 如果 time-diff 小于 60s,则标记为 0,否则标记为 1,以便设置某些组忽略 time-diff < 60s
- 在标签上使用
cumsum
,创建组标签 - groupby grouptag,对于每个 grouptag 保持 min(in_time) 和 max(out_time)
# convert the in_time to dateTime first, then sorted the values
df['in_time_t'] = pd.to_datetime(df['schdeule_date'] + ' ' + df['in_time'])
df.sort_values(['bus_id', 'in_time_t'], inplace=True)
# calculate the time difference for every bus_id
df['t_diff'] = df.groupby('bus_id')['in_time_t'].diff()
# set group_tag
cond = df['t_diff'].dt.seconds < 60
df['tag'] = np.where(cond, 0, 1).cumsum()
# for every grouptag keep min(in_time) and max(out_time)
df_result = df.groupby(['route_id', 'route_direction', 'bus_id', 'station_seq', 'schdeule_date',
'tag']).agg({'in_time':'min', 'out_time':'max'}).reset_index()
df
route_id route_direction bus_id station_seq schdeule_date in_time out_time
0 59 1 1349508393 2 2021-01-01 05:04:31 05:04:58
1 59 1 1349508393 2 2021-01-01 05:04:27 05:04:58
2 59 1 1349508393 2 2021-01-01 05:04:31 05:06:31
3 59 1 1349508393 2 2021-01-01 05:04:27 05:06:31
4 59 1 1349508393 1 2021-01-01 05:00:35 05:00:56
654 59 0 1349508329 1 2021-01-01 NaN 06:34:10
663 59 0 1349508329 2 2021-01-01 06:33:34 06:34:04
664 59 0 1349508329 2 2021-01-01 06:33:33 06:34:04
677 59 0 1349508329 2 2021-01-01 06:33:34 06:35:34
678 59 0 1349508329 2 2021-01-01 06:33:33 06:35:34
12133 59 0 1349508329 12 2021-01-01 NaN NaN
df_result
route_id route_direction bus_id station_seq schdeule_date tag in_time out_time
0 59 0 1349508329 1 2021-01-01 2 NaN 06:34:10
1 59 0 1349508329 2 2021-01-01 1 06:33:33 06:35:34
2 59 0 1349508329 12 2021-01-01 3 NaN NaN
3 59 1 1349508393 1 2021-01-01 4 05:00:35 05:00:56
4 59 1 1349508393 2 2021-01-01 5 05:04:27 05:06:31
df with tag
| | route_id | route_direction | bus_id | station_seq | schdeule_date | in_time | out_time | in_time_t | t_diff | tag |
|------:|-----------:|------------------:|-----------:|--------------:|:----------------|:----------|:-----------|:--------------------|:----------------|------:|
| 664 | 59 | 0 | 1349508329 | 2 | 2021-01-01 | 06:33:33 | 06:34:04 | 2021-01-01 06:33:33 | NaT | 1 |
| 678 | 59 | 0 | 1349508329 | 2 | 2021-01-01 | 06:33:33 | 06:35:34 | 2021-01-01 06:33:33 | 0 days 00:00:00 | 1 |
| 663 | 59 | 0 | 1349508329 | 2 | 2021-01-01 | 06:33:34 | 06:34:04 | 2021-01-01 06:33:34 | 0 days 00:00:01 | 1 |
| 677 | 59 | 0 | 1349508329 | 2 | 2021-01-01 | 06:33:34 | 06:35:34 | 2021-01-01 06:33:34 | 0 days 00:00:00 | 1 |
| 654 | 59 | 0 | 1349508329 | 1 | 2021-01-01 | nan | 06:34:10 | NaT | NaT | 2 |
| 12133 | 59 | 0 | 1349508329 | 12 | 2021-01-01 | nan | nan | NaT | NaT | 3 |
| 4 | 59 | 1 | 1349508393 | 1 | 2021-01-01 | 05:00:35 | 05:00:56 | 2021-01-01 05:00:35 | NaT | 4 |
| 1 | 59 | 1 | 1349508393 | 2 | 2021-01-01 | 05:04:27 | 05:04:58 | 2021-01-01 05:04:27 | 0 days 00:03:52 | 5 |
| 3 | 59 | 1 | 1349508393 | 2 | 2021-01-01 | 05:04:27 | 05:06:31 | 2021-01-01 05:04:27 | 0 days 00:00:00 | 5 |
| 0 | 59 | 1 | 1349508393 | 2 | 2021-01-01 | 05:04:31 | 05:04:58 | 2021-01-01 05:04:31 | 0 days 00:00:04 | 5 |
| 2 | 59 | 1 | 1349508393 | 2 | 2021-01-01 | 05:04:31 | 05:06:31 | 2021-01-01 05:04:31 | 0 days 00:00:00 | 5 |
推荐阅读
- java - Java:将数组/元素列表拆分为相等元素的子列表
- javascript - Lambda函数:尽管在函数内部将对象推送到它,但数组返回空
- r - 在 API GET 请求中,我应该在哪里插入我的 API 密钥?
- github - 我不小心删除了 github 存储库中的文件,但我仍然在本地保存它们
- emacs - 尽管“加载路径”列表正确,但 Flycheck 报告“无法打开加载文件”
- sql - 如何在单个查询中加入 3 个表
- jquery - jquery切换搜索栏在点击时没有关闭,它会是什么?
- php - 如何更改现有的永久链接(PHP、HTML、CSS)
- python - 张量流重塑使用
- java - 处理 TreeSet 中的重复项