【发布时间】:2019-02-25 14:31:12
【问题描述】:
给定以下数据库:
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
说明: 这些是铁路车厢,每节车厢由 num 标识(即 A、B、C) 这些可以是收费的,也可以是空的(空栏) 列 dir 指示我们是否已选择或退出该特定汽车。可能有很多其他状态(如本例中的 PASS),但我们只对 IN 和 OUT 状态感兴趣 车站栏是事件发生的地方 时间列是事件发生的时间。
我必须对每个 IN 和 OUT 对之间的数据进行分组(或显示它们中的每一个的轨迹)并显示活动发生的地点和时间困难在于这不是“正常”分组,而是一种基于时间序列的分层结构(在同一天,可以多次装载和清空汽车)。
我不知道 pandas 是否是该练习的最佳结构,但数据库中有数亿条记录,性能至关重要。 (我们正在根据特定时间范围预先选择数据)
如何达到预期效果?
【问题讨论】:
-
根据数据的大小和可用的计算资源,您可能需要研究并行线扫描算法。
-
另外,这是批处理环境还是流环境?因为将其作为流式处理问题可能会在概念上更容易。
-
好吧,我们可能会认为这是一个批处理过程,但如果响应时间是可以接受的(对于这个和十几个其他处理来说不到一分钟,但是那个处理的数据最多)那么整个过程将在线(这是最好的),用户点击“生成”,然后他将获得所需的列表
-
关于规模,我每天可能有大约 100 000 个事件(IN、OUT、PASS 等)。该报告总是生成每月数据(因此每月大约有 300 万条记录),并且我们必须在数据库中将数据保存数年。
-
如果您每月仅“按需”生成一次报告,那么对于 pandas 而言,这可能是一个太大的数据集。 (请记住,pandas 的计算模型完全在内存中)但是除非您的数据比您在此处说明的要多得多,否则像 dask dask.pydata.org/en/latest/ 这样的东西肯定能够处理它。 (dask 强烈模拟 pandas 界面,因此学习曲线应该非常小)
标签: python pandas pandas-groupby