更清洁的方式与2D中的scipy.trapz集成

时间:2017-12-19 11:58:13

标签: python performance numpy optimization scipy

我想在非均匀的2D网格上将离散函数与scipy.integrate.trapz集成。

例如,在5 * 5网格上,我有以下10个点坐标和值:

coord = np.array([(0,0),(2,1),(0,2),(2,3),(3,4),(4,0),(1,3),(4,2),(3,0),(1,4)])
values = np.array([1,5,1,4,6,3,2,0,5,2])

在网格上看起来像这样:

4  x 2 x 6 x
3  x 2 4 x x
2  1 x x x 0
1  x x 5 x x
0  1 x x 5 3

   0 1 2 3 4

我有以下代码,它似乎不起作用,效率不高或可以轻松扩展到具有更多分数的3D网格:

from scipy import integrate
import numpy as np

coord = coord.swapaxes(0,1)
nx = np.unique(coord[1]).size
ny = np.unique(coord[0]).size
intg_x = np.zeros(nx)

for x in range(nx):
    indices = np.where(coord[1] == x)[0]
    v = values[indices]
    c = coord[0][indices]
    intg_x[x] = integrate.trapz(v,c)

intg = integrate.trapz(intg_x,np.unique(coord[0]).sort())
print(intg)

Out[1]: -3.0

结果显然是错误的,因为只有正值才能整合。使用梯形法则手动积分,得到:integral_x = [13,0,2,3,8]和积分= 15,5。问题似乎来自于x的集成,但我没有得到迭代的错误。

有没有更简洁的方法来编写它,以便我可以将代码扩展到具有更多分数的3D网格?

编辑:

所以我设法修复了代码并获得了正确的结果!问题是c没有排序,所以trapz会给出负值,因为它会回溯。我现在使用以下几行:

for x in range(nx):
    inds = np.where(coord[1] == x)[0]
    c = coord[0][inds]
    inds = [x for _,x in sorted(zip(c,inds))]
    c = coord[0][inds]
    v = values[inds]
    intg_x[x] = integrate.trapz(v,c)

确实给出了正确的结果:

In [0]: print(intg_x,intg)
Out[0]: [ 13.   0.   2.   3.   8.] 15.5

我仍在寻找一种解决方案,使代码更简单,因为它很难转换为3D网格,因为它本身并不高效。提前感谢您提供给我的任何帮助!

0 个答案:

没有答案