2015-10-15 99 views
0

我已阅读this blog,它显示了算法如何使用numpy提高250倍速度。我曾尝试使用numpy的改善以下代码,但我不能让它工作:如何使用numpy提高python代码性能

for i in nodes[1:]: 
     for lb in range(2, diameter+1): 
      not_valid_colors = set() 
      valid_colors = set() 

      for j in nodes: 
       if j == i: 
        break 

       if distances[i-1, j-1] >= lb: 
        not_valid_colors.add(c[j, lb]) 
       else: 
        valid_colors.add(c[j, lb]) 

       c[i, lb] = choose_color(not_valid_colors, valid_colors) 

    return c 

说明

上面的代码是用来计算自相似尺寸的算法的一部分一张图。它基本上通过构建双图G'来工作,其中如果两个图之间的距离大于或等于给定值(Lb),则节点与其他节点相连,然后计算这些双网上的图着色。

该算法描述如下:

  1. 从1分配一个唯一的ID N到所有网络节点,而不分配任何颜色爱好。
  2. 对于所有Lb的值,颜色值0分配给具有ID,IE C_1l
  3. 值= 1 = 0设置的ID I = 2。重复以下的节点,直到I = N.
    • a)计算从i到网络中所有节点的距离l_ij,id j小于i。 c)从l_ij≥Lb的所有节点j < i中选择一个未使用的颜色C [j] [l_ij]。这是给定Lb值的节点i的颜色C [i] [Lb]。
    • d)将Lb增加1并重复(c)直到Lb = Lb_max。
    • e)通过1

wrote it in python增加I,但它需要一分钟以上时尝试与具有100个节点和p = 0.9小型网络中使用它。

因为我还是新来的python和numpy,我没有找到提高效率的方法。

是否可以通过使用numpy.where找到路径比给定Lb更长的路径来删除循环?我试图实现它,但没有奏效...

+1

但是在SO上比在CR上有更多'numpy'知识丰富的海报。 CR对问题格式也很挑剔。 '矢量化'是SO'numpy'的共同话题。 – hpaulj

+2

'numpy'可以加速很多事情,如果你的问题在本质上是平行的 - 对一个元素做同样的事情,不管顺序如何。但如果问题是连续的 - 第i个元素的行为取决于先前对'i-1'的行为,那么'numpy'通常不起作用。 – hpaulj

+0

同意@hpaulj询问表现,在此处向量化相关问题。同样对于OP来说,如果代替集合,列表或甚至更好的情况下使用numpy数组,当查看向量化代码时会更容易。 – Divakar

回答

1

与numpy的数组矢量化操作快速,因为实际的计算是这样的底层库完成作为BLASLAPACK没有Python开销。使用循环密集型操作时,您不会看到这些好处。

您通常必须找出一种矢量化操作的方法(通常可以通过智能使用数组切片)。但是,有些操作本质上是循环密集型的,有时候对它们进行矢量化并不容易(对于您的代码来说似乎就是这种情况)。

在这些情况下,您可以先尝试Numba,它可以从Python函数生成优化的机器代码而不做任何修改。 (你只需注解该功能,它会自动为你做)。我没有太多的经验,并没有尝试过将它用于复杂的功能。

如果这不起作用,那么你可以使用Cython,它会自动转换类Python代码(有类型的变量)为有效的C代码,并生成一个Python扩展模块,它可以导入并在Python中使用。这通常会给你至少一个数量级(通常是两个数量级)的加速循环密集型操作。我通常发现Cython易于使用,因为与纯C不同,可以直接在Cython代码中访问您的numpy数组。

我推荐使用Anaconda Python distribution,因为您可以轻松安装这些软件包。对不起,我没有针对您的代码的特定答案。

+0

谢谢你的解释和建议,我会尝试这两个选项,并让你知道结果! – Hernandcb

+0

您不必使用'numpy'来使用'Cython'。实际上,它对于常规的Python列表操作可能更有效 - 请检查其文档。 – hpaulj

+0

我从来没有说过你必须这样做。 :) – joon

1

,如果你想去numpy的,你可以改变列表成阵列, 例如distances[i-1][j-1]成为distances[i-1, j-1]后声明的距离为numpy的阵列。与c[i][lb]相同。关于valid_colorsnot_valid_colors你应该多想一点,因为用numpy数组你不能附加东西:数组有固定长度,所以你应该在之前修复最大尺寸。另一个想法是,在你掌握了所有的东西之后,你可以将你的代码编码为,这意味着你的所有循环将变得非常快。在任何情况下,如果你不想用Cython,你看博客,可以看到distances声明为在数组中main()