Python 如何在numpy中创建n维网格以计算任意n的函数?

Python 如何在numpy中创建n维网格以计算任意n的函数?,python,arrays,numpy,numerical-integration,Python,Arrays,Numpy,Numerical Integration,我试图创建一个简单的数值积分函数来说明高维蒙特卡罗积分的好处。我想要这样的东西: def quad_int(f, mins, maxs, numPoints=100): ''' Use the naive (Riemann sum) method to numerically integrate f on a box defined by the mins and maxs. INPUTS: f - A function handle.

我试图创建一个简单的数值积分函数来说明高维蒙特卡罗积分的好处。我想要这样的东西:

def quad_int(f, mins, maxs, numPoints=100):
    '''
    Use the naive (Riemann sum) method to numerically integrate f on a box 
    defined by the mins and maxs.

    INPUTS:
    f         - A function handle. Should accept a 1-D NumPy array 
        as input.
    mins      - A 1-D NumPy array of the minimum bounds on integration.
    maxs      - A 1-D NumPy array of the maximum bounds on integration.
    numPoints - An integer specifying the number of points to sample in 
        the Riemann-sum method. Defaults to 100.
    '''
    n = len(mins)

    # Create a grid of evenly spaced points to evaluate f on
    # Evaluate f at each point in the grid; sum all these values up
    dV = np.prod((maxs-mins/numPoints))
    # Multiply the sum by dV to get the approximate integral
# We don't want the last value since we are using left-hand Riemann sums
x = np.linspace(mins[0],maxs[0],numPoints)[:-1]
y = np.linspace(mins[1],maxs[1],numPoints)[:-1]
z = np.linspace(mins[2],maxs[2],numPoints)[:-1]

X, Y, Z = np.meshgrid(x,y,z)
tot = 0
for index, x in np.ndenumerate(X):
    tot += f(x, Y[index], Z[index])
我知道我的
dV
会导致数值稳定性问题,但现在我遇到的问题是创建域。如果尺寸的数量是固定的,只需像这样使用
np.meshgrid
就很容易了:

def quad_int(f, mins, maxs, numPoints=100):
    '''
    Use the naive (Riemann sum) method to numerically integrate f on a box 
    defined by the mins and maxs.

    INPUTS:
    f         - A function handle. Should accept a 1-D NumPy array 
        as input.
    mins      - A 1-D NumPy array of the minimum bounds on integration.
    maxs      - A 1-D NumPy array of the maximum bounds on integration.
    numPoints - An integer specifying the number of points to sample in 
        the Riemann-sum method. Defaults to 100.
    '''
    n = len(mins)

    # Create a grid of evenly spaced points to evaluate f on
    # Evaluate f at each point in the grid; sum all these values up
    dV = np.prod((maxs-mins/numPoints))
    # Multiply the sum by dV to get the approximate integral
# We don't want the last value since we are using left-hand Riemann sums
x = np.linspace(mins[0],maxs[0],numPoints)[:-1]
y = np.linspace(mins[1],maxs[1],numPoints)[:-1]
z = np.linspace(mins[2],maxs[2],numPoints)[:-1]

X, Y, Z = np.meshgrid(x,y,z)
tot = 0
for index, x in np.ndenumerate(X):
    tot += f(x, Y[index], Z[index])

是否有一个类似于np.meshgrid的程序可以对任意维度执行此操作,或者可以接受数组的元组?或者有没有其他方法可以在更高的维度上进行黎曼和?我曾经考虑过递归地执行它,但不知道它是如何工作的。

您可以使用列表理解来生成所有
linspaces
,然后使用
*
将该列表传递给
meshgrid
(将列表转换为参数元组)

XXX
现在是
n
数组的列表(每个
n
维度)

我使用的是直接的Python列表和参数操作

np.lib.index\u技巧
还有其他可能有用的索引和网格生成函数和类。这本书值得一读,只是为了看看如何做事情


为未知维度的数组编制索引时,在各种numpy函数中使用的一个巧妙技巧是构造所需索引的列表。它可以包括
切片(无)
您通常会看到的
。然后将其转换为元组并使用它

In [606]: index=[2,3]
In [607]: [slice(None)]+index
Out[607]: [slice(None, None, None), 2, 3]
In [609]: Y[tuple([slice(None)]+index)]
Out[609]: array([ 0. ,  0.5,  1. ,  1.5])
In [611]: Y[:,2,3]
Out[611]: array([ 0. ,  0.5,  1. ,  1.5])
他们使用需要更改元素的列表。并不总是需要转换为元组

index=[slice(None)]*3
index[1]=0
Y[index] # same as Y[:,0,:]

谢谢,这对创建域非常有效。在切片数组时,有没有办法解压元组?也就是说,给定一个来自
np.ndenumerate
索引,是否有一种简单的方法可以访问切片
X[:,索引[0],…,索引[n-1]?
现在我正在使用列表理解,但似乎应该有一种更快的方法。我添加了一些索引注释