我有一个大的网格数据点网格,我是从模拟中产生的,并且与xy平面中的每个点相关联的是z值(模拟的结果)。
我将x,y,z值转储到纯文本文件中,我想要做的是测量xy平面(即.z = 0)和由此定义的“平面”之间的体积。数据点。数据点目前不是均匀间隔的,尽管它们应该在模拟运行完毕后才会出现。
我一直在查看scipy文档,我不确定scipy.integrate是否提供了我需要的功能 - 似乎只有能够在2d中执行此操作,而不是我需要的3d。
首先,除非必要,我可以不进行插值,纯粹基于“梯形规则”或类似近似的积分是一个很好的基础。
感谢任何帮助。
感谢
编辑:下面描述的解决方案都运行良好。在我的情况下,事实证明使用样条曲线可以在平面中的尖锐最大值周围引起“涟漪”,因此Delaunay方法效果更好,但我建议人们检查两者。
答案 0 :(得分:4)
答案 1 :(得分:3)
如果你想严格遵守梯形规则,你可以做类似的事情:
import numpy as np
import scipy.spatial
def main():
xyz = np.random.random((100, 3))
area_underneath = trapezoidal_area(xyz)
print area_underneath
def trapezoidal_area(xyz):
"""Calculate volume under a surface defined by irregularly spaced points
using delaunay triangulation. "x,y,z" is a <numpoints x 3> shaped ndarray."""
d = scipy.spatial.Delaunay(xyz[:,:2])
tri = xyz[d.vertices]
a = tri[:,0,:2] - tri[:,1,:2]
b = tri[:,0,:2] - tri[:,2,:2]
proj_area = np.cross(a, b).sum(axis=-1)
zavg = tri[:,:,2].sum(axis=1)
vol = zavg * np.abs(proj_area) / 6.0
return vol.sum()
main()
样条曲线或线性(梯形)插值是否更适合将在很大程度上取决于您的问题。
答案 2 :(得分:2)
Joe Kington 的回答几乎不错(并且性能很高),但并不完全正确。 这是正确的代码,使用@ 运算符将操作保持在正确的级别,并具有完整的 numpy 性能。
import numpy as np
import scipy.spatial
def main():
xyz = np.random.random((100, 3))
area_underneath = trapezoidal_area(xyz)
print(area_underneath)
def trapezoidal_area(xyz):
"""Calculate volume under a surface defined by irregularly spaced points
using delaunay triangulation. "x,y,z" is a <numpoints x 3> shaped ndarray."""
d = scipy.spatial.Delaunay(xyz[:,:2])
tri = xyz[d.vertices]
a = tri[:,0,:2] - tri[:,1,:2]
b = tri[:,0,:2] - tri[:,2,:2]
vol = np.cross(a, b) @ tri[:,:,2]
return vol.sum() / 6.0
main()