我正在为不同的时间戳执行以下代码,每个代码都有近一百万条记录。一个日期花了一个多小时,我总共有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
答案 0 :(得分:4)
我猜测你的df
是Pandas DataFrame
对象。 Pandas具有内置功能来计算滚动统计数据,包括滚动中位数。此功能可通过Pandas Series
和DataFrame
对象上的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。