全部,
我将使用以下python代码计算一些特征值。但是,由于输入尺寸太大,因此非常耗时。请帮我优化代码。
leaving_volume=len([x for x in pickup_ids if x not in dropoff_ids])
arriving_volume=len([x for x in dropoff_ids if x not in pickup_ids])
transition_volume=len([x for x in dropoff_ids if x in pickup_ids])
union_ids=list(set(pickup_ids + dropoff_ids))
busstop_ids=[x for x in union_ids if self.geoitems[x].fare>0]
busstop_density=np.sum([Util.Geodist(self.geoitems[x].orilat, self.geoitems[x].orilng, self.geoitems[x].destlat, self.geoitems[x].destlng)/(1000*self.geoitems[x].fare) for x in busstop_ids])/len(busstop_ids) if len(busstop_ids) > 0 else 0
busstop_ids=[x for x in union_ids if self.geoitems[x].balance>0]
smartcard_balance=np.sum([self.geoitems[x].balance for x in busstop_ids])/len(busstop_ids) if len(busstop_ids) > 0 else 0
嗨,全部,
这是我的修订版。我在GPS跟踪数据上运行此代码。它更快。
intersect_ids=set(pickup_ids).intersection( set(dropoff_ids) )
union_ids=list(set(pickup_ids + dropoff_ids))
leaving_ids=set(pickup_ids)-intersect_ids
leaving_volume=len(leaving_ids)
arriving_ids=set(dropoff_ids)-intersect_ids
arriving_volume=len(arriving_ids)
transition_volume=len(intersect_ids)
busstop_density=np.mean([Util.Geodist(self.geoitems[x].orilat, self.geoitems[x].orilng, self.geoitems[x].destlat, self.geoitems[x].destlng)/(1000*self.geoitems[x].fare) for x in union_ids if self.geoitems[x].fare>0])
if not busstop_density > 0:
busstop_density = 0
smartcard_balance=np.mean([self.geoitems[x].balance for x in union_ids if self.geoitems[x].balance>0])
if not smartcard_balance > 0:
smartcard_balance = 0
非常感谢你的帮助。
答案 0 :(得分:3)
我注意到的一些事情,就像一些Python效率琐事:
if x not in dropoff_ids
使用in
运算符检查成员资格在set
上比list
更有效。但是,使用for
到list
进行迭代可能比set
更有效。因此,如果您希望前两行尽可能高效,那么您应该预先拥有两种类型的数据结构。
list(set(pickup_ids + dropoff_ids))
在合并数据之前创建集合效率更高,而不是创建长list
并从中构建set
。幸运的是,您现在可能已经拥有set
版本(请参阅第一条评论)!
最重要的是,你需要问自己一个问题:
通过构建额外的数据结构来节省构建它们所花费的时间吗?
下一个:
np.sum([...])
我接受过Python的训练,想到构建一个list
然后应用一个理论上只需要一个生成器作为code smell的函数。我不确定这是否适用于numpy,因为根据我的记忆,从生成器中提取数据并将其置于一个numpy结构中并不是完全直截了当。
看起来这只是代码的一小部分。如果您真的关心效率,我建议使用numpy数组而不是列表,并尝试尽可能多地使用numpy的内置数据结构和函数。对于C语言中的原始数据运算,它们可能比内置的Python函数更加优化。
如果你真的,真的关注效率,那么你应该在C中直接进行这种数据分析。特别是如果你没有比你更多的代码在这里介绍它可能很容易翻译。
答案 1 :(得分:0)
我只能支持机器yerning在这篇文章中所写的内容。如果您正在考虑切换到numpy,那么如果您的变量pickup_ids和dropoff_ids是numpy数组(也许它们已经是其他的:
dropoff_ids = np.array( dropoff_ids, dtype='i' )
pickup_ids = np.array( pickup_ids, dtype='i' )
然后你可以使用函数np.in1d(),它会给你一个True / False数组,你可以总结一下来获得True条目的总数。
leaving_volume = (-np.in1d( pickup_ids, dropoff_ids )).sum()
transition_volume= np.in1d( dropoff_ids, pickup_ids).sum()
arriving_volume = (-np.in1d( dropoff_ids, pickup_ids)).sum()
不知怎的,我觉得transition_volume = len(pickup_ids) - arrival_volume但我现在不是100%确定。
另一个对你有用的函数是np.unique(),如果你想摆脱重复的条目,这样就会把你的数组变成一个集合。