2013-05-08 29 views
1

我對Python很新穎(過去我使用過Mathematica,Maple或Matlab腳本)。 NumPy如何在數組上評估函數,但在嘗試在多個維度上實現時遇到了問題,這讓我印象深刻。我的問題很簡單(請不要笑):有沒有一種更優雅和有效的方式來評估一些函數f(它是在R^2上定義的)而不是使用循環?Python:一種優雅/高效的評估二維索引函數的方法?

import numpy  
M=numpy.zeros((10,10)) 
for i in range(0,10): 
    for j in range(0,10): 
     M[i,j]=f(i,j) 
return M 
+1

http://stackoverflow.com/q/1316068/139010 – 2013-05-08 03:39:42

+2

另見'numpy.vectorize'和'numpy.ufunc' 。我很少使用它們,它已經很久了,但我記得它們確實派上用場(只要記住在用自己的函數進行定製之前儘可能使用內置和numpy提供的函數)。 – mdscruggs 2013-05-08 04:00:02

+0

謝謝:這似乎是做這項工作。我在查找相關問題時沒有看到它。我應該刪除我原來的問題嗎? – 2013-05-08 04:04:13

回答

1

使用numpy編碼時的目標是儘可能地在整個數組上實現您的計算。所以,如果你的功能,例如,f(x,y) = x**2 +2*y,你想它適用於所有整數對x,y[0,10]x[0,10],做到:

x,y = np.mgrid[0:10, 0:10] 
fxy = x**2 + 2*y 

如果你沒有找到一個方式來表達你的函數以這樣的方式,然後:

  1. 請教如何做到這一點(和國家明令函數定義)
  2. 使用numpy.vectorize

同例如,使用vectorize

def f(x,y): return x**2 + 2*y 

x,y = np.mgrid[0:10, 0:10] 
fxy = np.vectorize(f)(x.ravel(),y.ravel()).reshape(x.shape) 

注意,實際上我只用vectorize類似蟒蛇map當陣列的內容不是數字。一個典型的例子是計算在列表中的一個陣列中的所有列表的長度:

# construct a sample list of lists 
list_of_lists = np.array([range(i) for i in range(1000)]) 
print np.vectorize(len)(list_of_lists) 
# [0,1 ... 998,999] 
0

是的,許多numpy函數在N維數組上運行。就拿這個例子:

>>> M = numpy.zeros((3,3)) 
>>> M[0][0] = 1 
>>> M[2][2] = 1 
>>> M 
array([[ 1., 0., 0.], 
     [ 0., 0., 0.], 
     [ 0., 0., 1.]]) 
>>> M > 0.5 
array([[ True, False, False], 
     [False, False, False], 
     [False, False, True]], dtype=bool) 
>>> numpy.sum(M) 
2.0 

注numpy.sum之間的區別,這在N維數組操作,並且金額,只去1平深:

>>> sum(M) 
array([ 1., 0., 1.]) 

所以,如果你建立你的功能f()不在n維數組上運行的操作中,那麼f()本身將在n維數組上運行。

+0

我想我的問題很不公平,對不起。使用你的例子:我想找到一種構造M的快速方式,而不是評估M.的特性。馬特的評論 - 即使用itertools.product似乎是一個有希望的方向。我應該刪除我原來的問題嗎? – 2013-05-08 04:02:15

0

您還可以使用numpy多維切片,如下所示。你只需爲每個維度提供片:

arr = np.zeros((5,5)) # 5 rows, 5 columns 

# update only first column 
arr[:,0] = 1 

# update only last row ... same as arr[-1] = 1 
arr[-1,:] = 1 

# update center 
arr[1:-1, 1:-1] = 1 

print arr 

輸出:

array([[ 1., 0., 0., 0., 0.], 
     [ 1., 1., 1., 1., 0.], 
     [ 1., 1., 1., 1., 0.], 
     [ 1., 1., 1., 1., 0.], 
     [ 1., 1., 1., 1., 1.]]) 
0

一個純Python的答案,不依賴於numpy的工具,是使兩個序列的笛卡爾乘積:

from itertools import product 
for i, j in product(range(0, 10), range(0, 10)): 
    M[i,j]=f(i,j) 

編輯:其實,我應該正確地閱讀這個問題。這仍然使用循環,只有一個循環。