我正在使用Python修改纽约市的地铁十字转门数据,将其变成每个车站入口/出口的可视化。
到目前为止,我有一个基于开始(03-24-15
)和结束(03-27-15
)日期的入口/出口计数列表:
{
'endTime': '03-25-14T21:40:30',
'entriesDuringPeriod': 158,
'exitsDuringPeriod': 597,
'startTime': '03-25-14T17:03:23'
},
{
'endTime': '03-26-14T01:00:00',
'entriesDuringPeriod': 29,
'exitsDuringPeriod': 235,
'startTime': '03-25-14T21:00:00'
},
我遇到的问题是不同的时间段不是标准化的,有时是重叠的。我希望能够通过并创建另一个列表,将这些数字标准化为一小时的增量。
我对Python时间处理不是很熟悉,我想知道是否有人可以提供一些有关如何开始接受字符串,将它们转换为日期对象以及根据时间划分值的信息。
如果重要的话,最终的可视化将使用d3.js进行可视化。
答案 0 :(得分:1)
将字符串放入datetime对象并不算太糟糕:
from datetime import datetime
from time import time, mktime, strptime
def get_datetime( instr ):
return datetime.fromtimestamp(mktime(strptime(instr, '%m-%d-%yT%H:%M:%S')))
# eg: get_datetime( '03-25-14T21:20:30' ) => datetime.datetime(2014, 3, 25, 21, 20, 30)
对数据进行分箱/归一化在很大程度上取决于您希望如何处理重叠持续时间......例如。你想假设人们到了吗?以线性方式退出,如果时间戳是一个半小时,66%将进入整个小时,33%进入另一个部分小时?
编辑:根据OP的评论,这里有完整的功能代码:
from datetime import timedelta
from collections import defaultdict
def add_datum( dd, v ):
end_dt = get_datetime(v['endTime'])
start_dt = get_datetime(v['startTime'])
total_duration = end_dt - start_dt
hour_start = datetime( year = start_dt.year,
month = start_dt.month,
day = start_dt.day,
hour = start_dt.hour )
hour_end = hour_start + timedelta( hours = 1 )
while hour_start < end_dt:
dt = min([hour_end, end_dt]) - max([ hour_start, start_dt ])
fraction = 1.0 * dt.total_seconds() / total_duration.total_seconds()
dd[ hour_start ]['hour'] = hour_start
dd[ hour_start ]['entries'] += v['entriesDuringPeriod'] * fraction
dd[ hour_start ]['exits'] += v['exitsDuringPeriod'] * fraction # exits
hour_start = hour_end
hour_end = hour_end + timedelta( hours = 1 )
return dd
dd = defaultdict(lambda: {'entries':0,'exits':0})
all_data = [{ 'endTime': '03-25-14T21:40:30',
'entriesDuringPeriod': 158,
'exitsDuringPeriod': 597,
'startTime': '03-25-14T17:03:23' },
{ 'endTime': '03-26-14T01:00:00',
'entriesDuringPeriod': 29,
'exitsDuringPeriod': 235,
'startTime': '03-25-14T21:00:00' }]
[ add_datum( dd, i ) for i in all_data ]
res = dd.values()
res.sort( key = lambda i: i['hour'] )
print res
# [{'entries': 32.28038732182594,
# 'exits': 121.97083057677271,
# 'hour': datetime.datetime(2014, 3, 25, 17, 0)},
# {'entries': 34.209418415829674,
# 'exits': 129.25963793829314,
# 'hour': datetime.datetime(2014, 3, 25, 18, 0)},
# {'entries': 34.209418415829674,
# 'exits': 129.25963793829314,
# 'hour': datetime.datetime(2014, 3, 25, 19, 0)},
# {'entries': 34.209418415829674,
# 'exits': 129.25963793829314,
# 'hour': datetime.datetime(2014, 3, 25, 20, 0)},
# {'entries': 30.34135743068503,
# 'exits': 146.00025560834786,
# 'hour': datetime.datetime(2014, 3, 25, 21, 0)},
# {'entries': 7.25,
# 'exits': 58.75,
# 'hour': datetime.datetime(2014, 3, 25, 22, 0)},
# {'entries': 7.25,
# 'exits': 58.75,
# 'hour': datetime.datetime(2014, 3, 25, 23, 0)},
# {'entries': 7.25,
# 'exits': 58.75,
# 'hour': datetime.datetime(2014, 3, 26, 0, 0)}]
答案 1 :(得分:1)
解析给定时间戳的方法是:
import datetime
datetime.datetime.strptime("03-25-14T21:08:12", "%m-%d-%yT%H:%M:%S")
这将为您提供一个datetime
对象,该对象可与其他datetime
对象进行比较。
datetime
library本身包含创建任意datetime
对象的所有函数,然后可用于排序/分级目的。
鉴于数据中的时间段不均匀且包含重叠,可能有一些方法可行。如果您可以对输入和退出进行线性平均,则可以计算每个时间段并计算平均每小时输入和退出的次数,然后,给定一小时,您可以遍历所有数据点,查找多少数据点与该小时重叠(即15分钟或整个小时),并将数据点的每小时平均条目/出口应用重叠百分比修改为累加器。
就伪代码而言:
assume we have an hour to data accumulation bag called htdab
for given hour in time series
for data point in all data points
if data point's start <= given hour <= data point's end
calculate percentage of overlap on top of given hour
add data point's entries per hour * percentage of overlap to our htdab's entry for given hour
add data point's exits per hour * percentage of overlap to our htdab's entry for given hour