2

我必须使用matplotlib中的contourf从函数返回的值x,y创建一个二维numpy数组,到目前为止我使用的是类似“C”的结构,它在Python中似乎效率很低

    dim_x = np.linspace(self.min_x, self.max_x, self.step)
    dim_y = np.linspace(self.min_y, self.max_y, self.step)
    X, Y = np.meshgrid(dim_x, dim_y)

    len_x = len(dim_x)
    len_y = len(dim_y)


    a = np.zeros([len_x, len_y], dtype=complex)

    for i, y in enumerate(dim_y):
        for j, x in enumerate(dim_x):
            a[i][j] = aux_functions.final_potential(complex(x, y), element_list)

cs = plt.contourf(X, Y, (a.real), 100)

如何以更 Pythonic 的方式完成此操作?

谢谢!

4

2 回答 2

2

如果您可以重写final_potential为矢量化函数,那将是理想的。一个简单的,也许是太明显的例子:

>>> dim_x = np.linspace(0, 2, 5)
>>> dim_y = np.linspace(0, 2, 5)
>>> X * Y
array([[ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ],
       [ 0.  ,  0.25,  0.5 ,  0.75,  1.  ],
       [ 0.  ,  0.5 ,  1.  ,  1.5 ,  2.  ],
       [ 0.  ,  0.75,  1.5 ,  2.25,  3.  ],
       [ 0.  ,  1.  ,  2.  ,  3.  ,  4.  ]])

但如果你真的不能这样做,你也可以vectorize

>>> np.vectorize(lambda x, y: x * y + 2)(X, Y)
array([[ 2.  ,  2.  ,  2.  ,  2.  ,  2.  ],
       [ 2.  ,  2.25,  2.5 ,  2.75,  3.  ],
       [ 2.  ,  2.5 ,  3.  ,  3.5 ,  4.  ],
       [ 2.  ,  2.75,  3.5 ,  4.25,  5.  ],
       [ 2.  ,  3.  ,  4.  ,  5.  ,  6.  ]])

在您的情况下,它可能看起来像这样:

def wrapper(x, y): 
    return aux_functions.final_potential(complex(x, y), element_list)

a = np.vectorize(wrapper)(X, Y)

这可能会比嵌套for循环快一点,尽管 python 函数调用的开销会抵消很多 numpy 的效率。在我过去所做的测试中,使用vectorize提供了适度的 5 倍加速。(这与纯 numpy 操作的 100 倍或 1000 倍加速相比,如X * Y示例中所示。)

于 2012-06-13T15:01:05.967 回答
1

我不知道这是否会提高你的性能,但是有numpy.fromfunction可以用来构造你的数组a。如果没有一个很好的自包含示例,那么要确定时间来查看性能的差异会有点棘手。例如,运行需要多长时间aux_functions.final_potential?如果该功能很昂贵,那么您优化它周围的循环多少都没有关系。

另外,我想这a[i,j]比 更有效a[i][j],但我还没有测试过。

于 2012-06-13T14:50:01.203 回答