2

matplotlibのcontourfを使用して、関数の戻り値x、yから2D 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)

これをよりPython的な方法で行うにはどうすればよいですか?

ありがとう!

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

これによりパフォーマンスがまったく向上するかどうかはわかりませんが、 array の構築に使用できるnumpy.fromfunctionaがあります。ただし、自己完結型の優れた例がなければ、パフォーマンスの違いを確認するのは少し難しいでしょう。たとえば、実行するのにどのくらいかかりますaux_functions.final_potentialか? その関数が高価である場合、その周りのループをどれだけ最適化しても問題ありません。

また、a[i,j]よりもわずかに効率的a[i][j]だと思いますが、テストしていません。

于 2012-06-13T14:50:01.203 に答える