改善使用for循环的代码的性能

时间:2020-02-16 17:50:02

标签: python performance

我试图基于一些数据创建一个列表,但是当我在大数据上运行它时,我使用的代码非常慢。因此,我怀疑我没有将所有Python功能都用于此任务。在Python中,有没有更有效,更快捷的方法?

下面是代码的说明:

您可以将这个问题看成一个游戏列表(list_type),每个游戏列表都有一个参与团队的列表以及游戏中每个团队的得分(list_xx)。对于当前游戏中的每个对,它首先计算与先前比赛的得分差异之和(win_comp_past_difs);仅包括当前游戏中的配对。然后,它会根据得分差异更新当前游戏中的每对游戏。使用defaultdict可以跟踪每个游戏中每对游戏的得分,并在每个游戏进行时更新该得分。

在下面的示例中,基于一些数据,有用于创建新变量list_zz的for循环。

数据和for循环代码:

import pandas as pd
import numpy as np
from collections import defaultdict
from itertools import permutations

list_type = [['A', 'B'], ['B'], ['A', 'B', 'C', 'D', 'E'], ['B'], ['A', 'B', 'C'], ['A'], ['B', 'C'], ['A', 'B'], ['C', 'A', 'B'], ['A'], ['B', 'C']]

list_xx = [[1.0, 5.0], [3.0], [2.0, 7.0, 3.0, 1.0, 6.0], [3.0], [5.0, 2.0, 3.0], [1.0], [9.0, 3.0], [2.0, 7.0], [3.0, 6.0, 8.0], [2.0], [7.0, 9.0]]

list_zz= []
#for-loop
wd = defaultdict(float)
for i, x in zip(list_type, list_xx):
    # staff 1
    if len(i) == 1:
        #print('NaN')
        list_zz.append(np.nan)
        continue
    # Pairs and difference generator for current game (i)
    pairs = list(permutations(i, 2))
    dgen = (value[0] - value[1] for value in permutations(x, 2))
    # Sum of differences from previous games incluiding only pair of teams in the current game
    for team, result in zip(i, x):
        win_comp_past_difs = sum(wd[key] for key in pairs if key[0] == team)
        #print(win_comp_past_difs)
        list_zz.append(win_comp_past_difs)
    # Update pair differences for current game
    for pair, diff in zip(pairs, dgen):
        wd[pair] += diff
print(list_zz)

看起来像这样:

[0.0,
 0.0,
 nan,
 -4.0,
 4.0,
 0.0,
 0.0,
 0.0,
 nan,
 -10.0,
 13.0,
 -3.0,
 nan,
 3.0,
 -3.0,
 -6.0,
 6.0,
 -10.0,
 -10.0,
 20.0,
 nan,
 14.0,
 -14.0]

如果您可以详细说明代码以使其更高效,更快地执行,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

在不检查代码总体设计的情况下,我想到了一项改进:将代码移至函数。

如当前所写,您使用的所有变量都是全局变量。由于全局名称空间的动态性质,Python必须在每次访问时使用它来查找您使用的每个全局变量。(1)在CPython中,这对应于哈希表查找,可能很昂贵,尤其是在存在哈希冲突的情况下。

相反,局部变量在编译时是已知的,因此存储在固定大小的数组中。因此,访问这些变量仅涉及取消引用指针,这相对要快得多。

牢记这一原则,通过将所有代码移至“ main”函数中,您应该能够提高性能(运行时间减少约40%):

def main():
    ...
    # Your code here

if __name__ == '__main__':
    main()

(1) Source