给出以下数据库:
import pandas as pd
from time import strptime
data = {'num': ['B', 'A', 'B', 'A', 'B', 'A', 'B', 'C', 'B', 'A', 'C', 'B'],
'dir': ['IN', 'IN', 'PASS', 'PASS', 'PASS', 'PASS', 'OUT', 'IN', 'IN', 'OUT', 'OUT', 'OUT'],
'empty': [True, False, True, False, True, False, True, False, False, False, False, False],
'station': [100, 1, 20, 20, 14, 14, 5, 65, 89, 8, 66, 11],
'time': [strptime('20180115 00:25', '%Y%m%d %H:%M'),
strptime('20180115 00:30', '%Y%m%d %H:%M'),
strptime('20180115 01:10', '%Y%m%d %H:%M'),
strptime('20180115 01:10', '%Y%m%d %H:%M'),
strptime('20180115 02:10', '%Y%m%d %H:%M'),
strptime('20180115 02:10', '%Y%m%d %H:%M'),
strptime('20180115 03:33', '%Y%m%d %H:%M'),
strptime('20180115 03:33', '%Y%m%d %H:%M'),
strptime('20180115 03:34', '%Y%m%d %H:%M'),
strptime('20180115 04:10', '%Y%m%d %H:%M'),
strptime('20180115 04:11', '%Y%m%d %H:%M'),
strptime('20180115 10:10', '%Y%m%d %H:%M')]}
df = pd.DataFrame.from_dict(data)
我必须生成以下预期结果的列表:
num empty station_from station_to time_from time_to
0 B True 100 5 20180115 00:25 20180115 03:33
1 A False 1 8 20180115 00:30 20180115 04:10
2 C False 65 66 20180115 03:33 20180115 04:11
3 B False 89 11 20180115 03:34 20180115 10:10
说明: 那些是用数字标识每辆车(即A,B,C)的铁路车 那些可以收费或为空(列为空) dir列指示我们是否已选择或退出该特定汽车。可能还有很多其他状态(例如本例中的PASS),但我们仅对IN和OUT状态感兴趣 站列是事件发生的地方 时间栏是事件发生的时间。
我必须将每个IN和OUT对之间的数据分组(或显示每个对的轨迹),并显示活动发生的时间和地点。困难在于,这不是“正常”分组,而是一种基于时间序列的分层时间序列(同一天,一辆汽车可以装载和清空几次)。
我不知道熊猫是否是该练习的最佳结构,但数据库中有数亿条记录,性能至关重要。 (我们正在根据特定的时间范围预先选择数据)
如何达到预期效果?
答案 0 :(得分:1)
1)用'IN'过滤所有行
2)为每个“ IN”找到匹配的 num 和 empty
的第一个下一个“ OUT”result = df[df.dir=='IN'][['num','empty','station','time']].rename({'station':'station_from','time':'time_from'},axis='columns')
result[['station_to','time_to']] = result.apply(lambda r: df[(df.index>r.name) & (df.num==r.num) & (df.empty==r.empty) & (df.dir=='OUT')][['station','time']].iloc[0,:], axis=1)
print(result)
num empty station_from time_from station_to \
0 B True 100 (2018, 1, 15, 0, 25, 0, 0, 15, -1) 5
1 A False 1 (2018, 1, 15, 0, 30, 0, 0, 15, -1) 8
7 C False 65 (2018, 1, 15, 3, 33, 0, 0, 15, -1) 66
8 B False 89 (2018, 1, 15, 3, 34, 0, 0, 15, -1) 11
time_to
0 (2018, 1, 15, 3, 33, 0, 0, 15, -1)
1 (2018, 1, 15, 4, 10, 0, 0, 15, -1)
7 (2018, 1, 15, 4, 11, 0, 0, 15, -1)
8 (2018, 1, 15, 10, 10, 0, 0, 15, -1)