簡體   English   中英

在python中通過不規則網格集成2D數據

[英]Integrating 2D data over an irregular grid in python

因此,我具有在一個域中不規則采樣的2D函數,並且我想計算表面下方的體積。 數據以[x,y,z] ,舉一個簡單的例子:

def f(x,y):
    return np.cos(10*x*y) * np.exp(-x**2 - y**2)

datrange1 = np.linspace(-5,5,1000)
datrange2 = np.linspace(-0.5,0.5,1000)

ar = []
for x in datrange1:
    for y in datrange2:
        ar += [[x,y, f(x,y)]]


for x in xrange2:
    for y in yrange2:
        ar += [[x,y, f(x,y)]] 

val_arr1 = np.array(ar)

data = np.unique(val_arr1)


xlist, ylist, zlist = data.T 

其中np.unique對第一列中的數據進行排序,然后對第二列中的數據進行排序。 數據是以這種方式排列的,因為我需要圍繞原點進行更多采樣,因為必須解決一個尖銳的特征。

現在,我想知道是使用構建二維插值功能scipy.interpolate.interp2d ,然后用這個積分, dblquad 事實證明,這不僅笨拙而且緩慢,而且還會引發錯誤:

RuntimeWarning: No more knots can be added because the number of B-spline
coefficients already exceeds the number of data points m. 

是否有更好的方法來集成以這種方式排列或克服此錯誤的數據?

如果您可以圍繞感興趣的特征以足夠高的分辨率對數據進行采樣,然后在其他地方進行稀疏采樣,那么問題定義就變成了如何定義每個采樣下的區域。 對於常規的矩形樣本,此操作很容易,並且可能以原點附近的分辨率為增量逐步進行。 我追求的方法是為每個樣本生成2維Voronoi單元,以確定它們的面積。 我把大部分的代碼從這個答案,因為它幾乎都已經所需的組件。

import numpy as np
from scipy.spatial import Voronoi

#taken from: # https://stackoverflow.com/questions/28665491/getting-a-bounded-polygon-coordinates-from-voronoi-cells
#computes voronoi regions bounded by a bounding box
def square_voronoi(xy, bbox): #bbox: (min_x, max_x, min_y, max_y)
    # Select points inside the bounding box
    points_center = xy[np.where((bbox[0] <= xy[:,0]) * (xy[:,0] <= bbox[1]) * (bbox[2] <= xy[:,1]) * (bbox[2] <= bbox[3]))]
    # Mirror points
    points_left = np.copy(points_center)
    points_left[:, 0] = bbox[0] - (points_left[:, 0] - bbox[0])
    points_right = np.copy(points_center)
    points_right[:, 0] = bbox[1] + (bbox[1] - points_right[:, 0])
    points_down = np.copy(points_center)
    points_down[:, 1] = bbox[2] - (points_down[:, 1] - bbox[2])
    points_up = np.copy(points_center)
    points_up[:, 1] = bbox[3] + (bbox[3] - points_up[:, 1])
    points = np.concatenate((points_center, points_left, points_right, points_down, points_up,), axis=0)
    # Compute Voronoi
    vor = Voronoi(points)
    # Filter regions (center points should* be guaranteed to have a valid region)
    # center points should come first and not change in size
    regions = [vor.regions[vor.point_region[i]] for i in range(len(points_center))]
    vor.filtered_points = points_center
    vor.filtered_regions = regions
    return vor

#also stolen from: https://stackoverflow.com/questions/28665491/getting-a-bounded-polygon-coordinates-from-voronoi-cells
def area_region(vertices):
    # Polygon's signed area
    A = 0
    for i in range(0, len(vertices) - 1):
        s = (vertices[i, 0] * vertices[i + 1, 1] - vertices[i + 1, 0] * vertices[i, 1])
        A = A + s
    return np.abs(0.5 * A)

def f(x,y):
    return np.cos(10*x*y) * np.exp(-x**2 - y**2)

#sampling could easily be shaped to sample origin more heavily
sample_x = np.random.rand(1000) * 10 - 5 #same range as example linspace
sample_y = np.random.rand(1000) - .5
sample_xy = np.array([sample_x, sample_y]).T

vor = square_voronoi(sample_xy, (-5,5,-.5,.5)) #using bbox from samples
points = vor.filtered_points
sample_areas = np.array([area_region(vor.vertices[verts+[verts[0]],:]) for verts in vor.filtered_regions])
sample_z = np.array([f(p[0], p[1]) for p in points])

volume = np.sum(sample_z * sample_areas)

我還沒有完全測試過,但是原理應該起作用,並且數學運算也可以完成。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM