在numpy中通过数组嵌套for循环更好吗?

2024-10-19 16:42:40 发布

您现在位置:Python中文网/ 问答频道 /正文

通常我需要遍历一个数组并对每个条目执行一些操作,其中操作可能取决于索引和条目的值。这里有一个简单的例子。在

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)

有没有一种更短、更干净或更像Python的方式来完成这些任务?在


Tags: inimport目的numpyforasnp方式
3条回答

我想说这是执行迭代的最直接和最普遍理解的方法。在

另一种方法是迭代这些值并为给定的(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))]

我刚用过itertools.product要为可能的(i,j)值创建生成器,您也可以使用for循环。在

^{pr2}$

np.fromfunction用于:

def f(i,j) : return 1/((i+2*j+1)**2) 
M = np.fromfunction(f,(N,N))

“手工制作”的矢量化方法稍慢一些,但很容易理解。在

您展示的是pythonic,它使用Python列表和迭代方法。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.01234568,
         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是另一个常见的函数。在

在您的例子中,这个等式可以很好地处理像这样的两个数组。这在很大程度上取决于广播规则,你应该学习这些规则。在

如果函数只接受标量输入,我们将不得不使用某种形式的迭代。这是一个经常出现的问题;搜索[numpy] vectorize。在

相关问题 更多 >