【问题标题】:Optimization of for loop in pythonpython中for循环的优化
【发布时间】:2017-02-21 15:34:14
【问题描述】:

我正在为不同的时间戳执行以下代码,每个代码将有接近一百万条记录。一个约会用了一个多小时,我总共有 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

【问题讨论】:

  • 您是否尝试过分析您的代码?对于超过 1 亿条记录,您发布的代码中的任何内容都不应远程接近 1 小时。
  • 代码还有一些其他的计算。在我包含这段代码之前很快

标签: python loops pandas for-loop optimization


【解决方案1】:

我猜你的 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-loop 的解决方案大约需要0.61 秒,因此使用rolling 可以加快代码增加了 200 多倍。

所以在你的情况下,

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

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

请注意,计算滚动统计数据的语法在 Pandas 0.18 中发生了变化,因此您至少需要 0.18 版本才能使用上述代码。对于早期版本的 Pandas,请查看 rolling_median 函数。

【讨论】:

  • 是的,完全正确。正要发布这个。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2015-04-15
    • 2020-11-07
    • 1970-01-01
    • 1970-01-01
    • 2017-01-17
    • 1970-01-01
    • 1970-01-01
    • 2017-05-28
    相关资源
    最近更新 更多