Python 加速数据转换
我有一个给定的(由第三方提供,因此是不可更改的)输入数据,其结构如下:数据是一个4元组列表,每个4元组表示一次出击。每架次出击的第一个要素是从总共20个可能的类别(不重复)中选择1至5个类别的清单;第二个因素是参与人数;第三个是datetime对象,指示出击的开始;最后一个和第四个元素是datetime对象,指示出击结束 现在我必须将这些数据转换成以下格式:对于每一类别,我需要计算(a)该类别的出动次数,(b)花费的总时间,(c)每次出动的平均时间,(d)总“工时”,即每次出动的持续时间之和乘以同一出动的参与者人数,和(e)每架次的平均“工时” 我第一次天真的尝试如下:Python 加速数据转换,python,optimization,transformation,Python,Optimization,Transformation,我有一个给定的(由第三方提供,因此是不可更改的)输入数据,其结构如下:数据是一个4元组列表,每个4元组表示一次出击。每架次出击的第一个要素是从总共20个可能的类别(不重复)中选择1至5个类别的清单;第二个因素是参与人数;第三个是datetime对象,指示出击的开始;最后一个和第四个元素是datetime对象,指示出击结束 现在我必须将这些数据转换成以下格式:对于每一类别,我需要计算(a)该类别的出动次数,(b)花费的总时间,(c)每次出动的平均时间,(d)总“工时”,即每次出动的持续时间之和乘以
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)
我将用以下内容对其进行分析:
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而不是简单的听写或列表理解
我想利用这个模块,但我不确定如何从中获得最佳效果。因此:
a)转换函数以何种方式进行时间优化(加速)?
b)在这项工作中,itertools
能以何种方式帮助我?
我提前感谢你的回答
--
参考:在我的盒子上(AMD Phenom II Quad,4 GB RAM,4 GB交换),在linux上使用Python 3.3.1(默认值,2013年4月17日,22:30:32)[GCC 4.7.3]
分析器弹出:1000 2.027 0.002 2.042 0.002 trans.py:6(transform)
。从pyhton3移动到pypy不是一个选项
编辑:
示例数据(使用ISO表示)或使用第二个代码段创建(显然不是真实的)数据:
2013-08-02:
不幸的是,分析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
您可能会使用:
我不知道它是否更快。如果你尝试一下,请报告结果
还有,我的肚皮舞也没那么棒。因此,如果有人知道如何改进它,请告诉我。您是否发现这部分代码是一个瓶颈?不幸的是,它确实是一个瓶颈。我们需要经常在总数据的不同子集上运行此转换,这会阻止缓存。此外,我一直对如何优化代码以及如何从我不经常使用的模块中获取全部资源感兴趣。如果您在输入数据中查找模式,确实有:某些类别往往有一定数量的参与者。某些类别倾向于与某些其他类别组合在一起。某些类别与其他类别相互排斥。另一方面,时间和持续时间完全独立于参与者和类别。这里没有任何可以优化的主要内容。将该函数实现为C扩展(试试Cython)。谢谢。我现在坐在另一台机器旁。一旦我再次坐在参考框前,我会在我的硬件上描述你的解决方案,并告诉你结果。再次感谢你的想法。不幸的是,numpy的速度更慢了。看看我对我的问题所做的编辑。不过,谢谢你的意见。