Python:嵌套循环非常慢

时间:2019-02-18 13:37:01

标签: python performance loops for-loop nested

我大约有。 266680个用户(我的user_num变量的值为266680)和一个包含用户索引键和业务索引列表值的映射。例如:users_businesses[0] = 1,5,7,9,11,15表示索引为0的用户已经对索引为1,5,7,9,11,15的企业进行了投票。我的任务是在用户之间创建边缘列表,这些用户至少具有5个共同评级的企业。 例如,如果:users_businesses[1] = 1,5,7,9,11,13 -> (0,1)将成为优势,因为0和1个用户拥有5个共同评价的业务。

我尝试了以下方法:

def Length_Elements(element_list):
    num=0
    for element in element_list:
        num=num+1
    return num

def More_Than_Five_Common_Businesses(list1, list2):
    common_elements = list(set(list1).intersection(list2))
    num = Length_Elements(common_elements)
    if(num >= 5):
        return True
    return False

tuple_list = []
for user1 in range(user_num):
    for user2 in range(user_num):
        if(More_Than_Five_Common_Businesses(users_businesses[user1],users_businesses[user2])):
            tuple_list.append((user1,user2))

这当然非常慢,因为嵌套的for循环迭代266680 * 266680次。 您能给我一个更好的解决方案吗?我会很感激。谢谢!

3 个答案:

答案 0 :(得分:0)

您可以使用filter

以下是比较嵌套循环和过滤器所花费时间的实验:

import numpy as np
import time
import itertools

def compare(t):
    a, b = t
    return a > b

a1 = np.random.randint(0, 100, size=2000)

start = time.time()
result = filter(compare, itertools.product(a1, a1))
print(time.time() - start) # takes 0.0s

result2 = []
start = time.time()
for i in range(a1.shape[0]):
    for j in range(a1.shape[0]):
        if a1[i] > a1[j]:
            result2.append((a1[i], a1[j]))
print(time.time() - start) # takes 5.867310285568237s

print(len(list(result))) #1979249
print(len(list(result2))) #1979249

答案 1 :(得分:0)

我没有最好的算法,但是我看到两个问题。

第一:主循环使工作量增加了两倍。更好的用户是这样的:

In [3]: for x in range(5):
   ...:     for y in range(1, 5-x):
   ...:         print x,y+x
   ...:         
0 1
0 2
0 3
0 4
1 2
1 3
1 4
2 3
2 4
3 4

第二:使用您熟悉的编程语言。 len(s)Sequence Types — list, tuple, range

答案 2 :(得分:0)

您可以遍历企业,然后连接该企业中的所有用户,并计算一个用户与另一个用户建立联系的次数。

因此本质上您需要3个for循环:

  1. 第一个for循环是列出每个企业的用户列表。
  2. 第二个for循环是遍历业务并连接该业务列表中的所有用户。 为此,您可以为每个用户保留一个元组映射,每个元组都包含一个用户ID和连接数。
  3. 第三个循环遍历用户,然后为每个用户遍历元组并在数字大于或等于5时添加边。

这可能更快,具体取决于数据的密度。如果每个用户彼此之间至少有1个连接,则这同样会很慢,因为第二个和第三个循环的速度将与原始解决方案一样慢。