python中for循环的优化

时间:2016-10-12 17:55:30

标签: python loops pandas for-loop optimization

我正在为不同的时间戳执行以下代码,每个代码都有近一百万条记录。一个日期花了一个多小时,我总共有35个日期的数据。

有没有办法优化此代码?

def median(a, b, c,d,e):
    I=[a,b,c,d,e]
    I.sort()
    return I[2]

for i in range(2, len(df['num'])-2):
    num_smooth= median(df['num'][i-1], df['num'][i-2], df['num'][i],
                       df['num'][i+1], df['num'][i+2])
    df.set_value(i,'num_smooth',num_smooth)
df['num_smooth'].fillna(df['num'], inplace=True)

...........................................
Remaining code

2 个答案:

答案 0 :(得分:4)

我猜测你的df是Pandas DataFrame对象。 Pandas具有内置功能来计算滚动统计数据,包括滚动中位数。此功能可通过Pandas SeriesDataFrame对象上的rolling方法获得。

>>> s = pd.Series(np.random.rand(10))
>>> s
0    0.500538
1    0.598179
2    0.747391
3    0.371498
4    0.244869
5    0.930303
6    0.327856
7    0.317395
8    0.190386
9    0.976148
dtype: float64
>>> s.rolling(window=5, center=True).median()
0         NaN
1         NaN
2    0.500538
3    0.598179
4    0.371498
5    0.327856
6    0.317395
7    0.327856
8         NaN
9         NaN
dtype: float64

有关使用rolling及相关功能的更多常规信息,请参阅Window Functions上的Pandas文档。作为一般规则,当性能很重要时,您应该优先使用内置的Pandas和NumPy函数和方法而不是显式的Python级for循环,尽管如此,您应该确定您的解决方案。在我的机器上,使用包含一百万随机浮点数的df['num']系列,基于rolling的解决方案大约需要129秒,而基于for - 循环的解决方案大约需要0.61秒,所以使用rolling可将代码速度提高200倍以上。

所以在你的情况下,

df['num_smooth'] = df['num'].rolling(window=5, center=True).median()

以及您已经拥有的fillna步骤应该为您提供接近您需要的东西。

请注意,计算滚动统计信息的语法在Pandas 0.18中已更改,因此您至少需要0.18版才能使用上述代码。对于早期版本的Pandas,请查看rolling_median函数。

答案 1 :(得分:0)

逐行分析python代码性能的一个很好的工具是kernprof

相关问题