2013-05-08 61 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) 

编辑:其实,我应该正确地阅读这个问题。这仍然使用循环,只有一个循环。