我有一个给定的(由第三方提供,因此是不可更改的)输入数据,其结构如下:数据是一个4元组的列表,每个4元组表示一次出击。每次出击的第一个元素是从总共20个可能的类别(不重复)中选择的长度为1到5的类别列表;第二个元素是参与人数;第三个元素是指示出击开始的日期时间对象;最后一个和第四个元素是一个datetime对象,指示出动的结束。你知道吗
现在我必须将这些数据转换成以下格式:对于每一类,我需要计算(a)这一类的出动次数,(b)花费的总时间,(c)每次出动花费的平均时间,(d)总“工时”,即每次出动的持续时间乘以同一出动的参与人数之和,(e)每架次的平均“工时”。你知道吗
我第一次天真的尝试是:
def transform (data):
t = defaultdict (lambda: (0, 0, 0) )
for row in data:
delta = row [3] - row [2]
hours = delta.days * 24 + delta.seconds / 3600
manHours = row [1] * hours
for cat in row [0]:
t [cat] = (t [cat] [0] + 1, t [cat] [1] + hours, t [cat] [2] + manHours)
return {k: (v [0], v [1], v [1] / v [0], v [2], v [2] / v [0] ) for k, v in t.items () }
我用下面的文字来描述它:
cats = [_ for _ in range (20) ]
for test in range (1000):
data = [ (random.sample (cats, random.randint (1, 5) ), random.randint (2, 40), datetime.datetime (2013, 1, 1, 8), datetime.datetime (2013, 1, 1, 9) ) for _ in range (1000) ]
transform (data)
使用-m cProfile
。你知道吗
我读过很多关于stackoverflow的文章,其中提到了itertools在执行迭代、分组、计数等方面令人难以置信的优势,以至于用户更喜欢使用itertools而不是简单的dict或list理解。你知道吗
我想利用这个模块,但我不知道如何从中得到最好的。因此:
a)用哪种方法可以对转换函数进行时间优化(加速)?
b)在这项工作中,itertools
可以用哪种方式帮助我?
我提前感谢你的回答。你知道吗
---
参考:在我的盒子(AMD Phenom II Quad,4gbram,4gbswap)上,使用Python 3.3.1 (default, Apr 17 2013, 22:30:32) [GCC 4.7.3] on linux
探查器输出:1000 2.027 0.002 2.042 0.002 trans.py:6(transform)
。从pyhton3移动到pypy不是一个选项。你知道吗
编辑: 示例数据(使用ISO表示)或使用第二个代码段创建(显然不是真实的)数据:
[([6, 4, 15], 3, '2013-07-31T17:23:00', '2013-07-31T18:40:00'), ([9, 18, 5], 15, '2013-07-08T17:49:00', '2013-07-08T18:57:00'), ([7, 14, 17, 12, 0], 18, '2013-07-20T08:16:00', '2013-07-20T09:06:00'), ([6, 1], 32, '2013-07-31T07:14:00', '2013-07-31T09:01:00'), ([17, 7], 7, '2013-07-05T06:59:00', '2013-07-05T07:52:00')]
2013年8月2日: 不幸的是,分析pillmuncher的想法会导致使用numpy比不使用numpy慢360%:
1000 1.828 0.002 1.842 0.002 prof.py:8(transform) #original function
1000 0.159 0.000 8.457 0.008 prof.py:43(transform3) #numpy function
您可以使用numpy:
我不知道是不是更快了。如果你试一下,请报告结果。你知道吗
而且,我的肚皮也不是很好。如果有人知道如何改进,请告诉我。你知道吗
相关问题 更多 >
编程相关推荐