Python 散乱数据的快速平滑
我正在寻找一种方法,可以平滑分散的数据集。分散的数据集来自于对表示光栅的非常大的阵列进行采样。我必须对这个数组进行矢量化,以便对其进行降采样。我使用Python 散乱数据的快速平滑,python,numpy,matplotlib,smoothing,Python,Numpy,Matplotlib,Smoothing,我正在寻找一种方法,可以平滑分散的数据集。分散的数据集来自于对表示光栅的非常大的阵列进行采样。我必须对这个数组进行矢量化,以便对其进行降采样。我使用matplotlib.pyplot.contour()函数实现了这一点,并获得了一组合理的点-值对 问题是这个信号有噪声,我需要平滑它。平滑原始数组不好,我需要平滑散乱的数据。我能找到的最好的函数是下面的函数,它是我从Matlab中重写的。虽然此函数执行此任务,但速度非常慢。我正在寻找其他函数来平滑这些数据,或者寻找一种使下面的函数更快的方法 def
matplotlib.pyplot.contour()
函数实现了这一点,并获得了一组合理的点-值对
问题是这个信号有噪声,我需要平滑它。平滑原始数组不好,我需要平滑散乱的数据。我能找到的最好的函数是下面的函数,它是我从Matlab中重写的。虽然此函数执行此任务,但速度非常慢。我正在寻找其他函数来平滑这些数据,或者寻找一种使下面的函数更快的方法
def limgrad(self,三角测量,值,dfdx,imax=100):
"""
看见https://github.com/dengwirda/mesh2d/blob/master/hjac-util/limgrad.m
对于原始源代码。
"""
#三角剖分是matplotlib.tri.triangulation实例
边=三角剖分。边
dx=np.subtract(
triangulation.x[edge[:,0]],triangulation.x[edge[:,1]]
dy=np.subtract(
triangulation.y[edge[:,0]],triangulation.y[edge[:,1]]
元素=np.sqrt(dx**2+dy**2)
aset=np.零(值.形状)
ftol=np.min(值)*np.sqrt(np.finfo(float.eps)
对于范围内的i(1,imax+1):
aidx=np.其中(aset==i-1)[0]
如果len(aidx)==0:
打破
active_idxs=np.argsort(值[aidx])
对于active_idx中的active_idx:
adj_edges_idxs=np.where(
np.any(边==活动的_idx,轴=1))[0]
相邻_边=边[调整_边_idxs]
对于节点1,相邻_边中的节点2:
如果值[nod1]>值[nod2]:
fun1=值[nod2]+elen[active_idx]*dfdx
如果值[nod1]>fun1+ftol:
值[nod1]=fun1
aset[nod1]=i
其他:
fun2=值[nod1]+elen[active_idx]*dfdx
如果值[nod2]>fun2+ftol:
值[nod2]=fun2
aset[nod2]=i
返回值
我找到了我自己问题的答案,我在这里发布供参考。上面的算法很慢,因为调用np.where()来生成adj_edges_idx的开销很大。相反,我预计算了节点邻居,这消除了开销。它从每秒约80次迭代增加到80000 It/s
最终版本如下所示:
def limgrad(tri, values, dfdx=0.2, imax=100):
"""
See https://github.com/dengwirda/mesh2d/blob/master/hjac-util/limgrad.m
for original source code.
"""
xy = np.vstack([tri.x, tri.y]).T
edge = tri.edges
dx = np.subtract(xy[edge[:, 0], 0], xy[edge[:, 1], 0])
dy = np.subtract(xy[edge[:, 0], 1], xy[edge[:, 1], 1])
elen = np.sqrt(dx**2+dy**2)
ffun = values.flatten()
aset = np.zeros(ffun.shape)
ftol = np.min(ffun) * np.sqrt(np.finfo(float).eps)
# precompute neighbor table
point_neighbors = defaultdict(set)
for simplex in tri.triangles:
for i, j in permutations(simplex, 2):
point_neighbors[i].add(j)
# iterative smoothing
for _iter in range(1, imax+1):
aidx = np.where(aset == _iter-1)[0]
if len(aidx) == 0.:
break
active_idxs = np.argsort(ffun[aidx])
for active_idx in active_idxs:
adjacent_edges = point_neighbors[active_idx]
for adj_edge in adjacent_edges:
if ffun[adj_edge] > ffun[active_idx]:
fun1 = ffun[active_idx] + elen[active_idx] * dfdx
if ffun[adj_edge] > fun1+ftol:
ffun[adj_edge] = fun1
aset[adj_edge] = _iter
else:
fun2 = ffun[adj_edge] + elen[active_idx] * dfdx
if ffun[active_idx] > fun2+ftol:
ffun[active_idx] = fun2
aset[active_idx] = _iter
flag = _iter < imax
return ffun, flag
def limgrad(tri,值,dfdx=0.2,imax=100):
"""
看见https://github.com/dengwirda/mesh2d/blob/master/hjac-util/limgrad.m
对于原始源代码。
"""
xy=np.vstack([tri.x,tri.y]).T
边=三条边
dx=np.减法(xy[边[:,0],0],xy[边[:,1],0])
dy=np.减法(xy[边[:,0],1],xy[边[:,1],1])
元素=np.sqrt(dx**2+dy**2)
ffun=values.flatte()
aset=np.零(ffun.形状)
ftol=np.min(ffun)*np.sqrt(np.finfo(float.eps)
#预计算邻居表
点=默认DICT(设置)
对于三角形中的单纯形:
对于置换中的i,j(单纯形,2):
点[i]。添加(j)
#迭代平滑
对于范围内的_iter(1,imax+1):
aidx=np.where(aset==\U iter-1)[0]
如果len(aidx)==0:
打破
active_idxs=np.argsort(ffun[aidx])
对于active_idx中的active_idx:
相邻_边=点_邻居[活动_idx]
对于相邻_边中的调整_边:
如果ffun[adj_edge]>ffun[active_idx]:
fun1=ffun[active_idx]+elen[active_idx]*dfdx
如果ffun[adj_edge]>fun1+ftol:
ffun[adj_边]=fun1
aset[adj_edge]=\u iter
其他:
fun2=ffun[adj_edge]+elen[active_idx]*dfdx
如果ffun[active_idx]>fun2+ftol:
ffun[active_idx]=fun2
aset[active_idx]=\u iter
flag=\u iter
也许你可以看看这个,看看是否有什么对你有用的东西。它主要是关于插值,但样条函数也可用于平滑。