2017-01-18 4 views
3

多くの場合、配列をトラバースして、各エントリに対して操作を実行する必要があります。この操作は、インデックスとエントリの値によって異なる場合があります。ここに簡単な例があります。numpyの配列を使ってforループをネストしたほうが良いでしょうか?

import numpy as np 

N=10 
M = np.zeros((N,N)) 

for i in range(N): 
    for j in range(N): 
     M[i,j] = 1/((i+2*j+1)**2) 

このようなタスクを実行するために、より短く、よりクリーンな、またはより平凡な方法がありますか?

答えて

1

これは、その繰り返しを実行するためのもっとも単純で普遍的に理解されている方法です。

代替は、私はちょうど可能(私のために発電機を作成するためにitertools.productを使用した値の上に反復処理することで、与えられた(i、j)のペア。ここ

import itertools 

N = 10 
M = np.zeros((N,N)) 

def do_work(i, j): 
     M[i,j] = 1/((i+2*j+1)**2) 

[do_work(i, j) for (i, j) in itertools.product(xrange(N), xrange(N))] 

する関数を呼び出します、j)の値を使って、forループを使うこともできます。

for (i, j) in itertools.product(xrange(N), xrange(N)): 
    M[i,j] = 1/((i+2*j+1)**2) 
5

あなたが示しているのは、Pythonのリストと反復アプローチを使用しているという意味では 'pythonic'です。 numpyを使用するのは、M{i,j] =という値を割り当てることだけです。リストは、その種のインデックスを持っていません。

numpyを最大限に活用するには、インデックスグリッドまたは配列を作成し、明示的なループを使わずにすべての値を一度に計算します。たとえば、あなたのケースで:

In [333]: N=10 
In [334]: I,J = np.ogrid[0:10,0:10] 
In [335]: I 
Out[335]: 
array([[0], 
     [1], 
     [2], 
     [3], 
     [4], 
     [5], 
     [6], 
     [7], 
     [8], 
     [9]]) 
In [336]: J 
Out[336]: array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]) 
In [337]: M = 1/((I + 2*J + 1)**2) 
In [338]: M 
Out[338]: 
array([[ 1.  , 0.11111111, 0.04  , 0.02040816, 0., 
     0.00826446, 0.00591716, 0.00444444, 0.00346021, 0.00277008], 
... 
     [ 0.01  , 0.00694444, 0.00510204, 0.00390625, 0.00308642, 
     0.0025 , 0.00206612, 0.00173611, 0.00147929, 0.00127551]]) 

ogridは一緒に「放送」することができますアレイの構築・セットのいくつかの方法の一つです。 meshgridも共通の機能です。

あなたの場合、方程式はこのような2つの配列でうまくいくものです。それはあなたが勉強すべき放送規則に非常に依存します。

関数がスカラ入力のみを使用する場合は、何らかの形の繰り返しを使用する必要があります。それはしばしばSOの質問でした。 [numpy] vectorizeを検索してください。

2

np.fromfunctionはそのためのものです:

それは手作り "ベクトル化の方法が、簡単に理解することslighty遅くなります。

関連する問題