Phy*_*ist 2 arrays matlab numpy vectorization integral
我有一个 2D 数组(典型大小约为 400x100),如图所示(它看起来像一个梯形,因为右下角的元素是 nan)。对于数组中的每个元素,我想对多个元素(大约 10 个元素)沿列执行数值积分。在物理语言中,将颜色视为力的大小,我想找到通过计算 Fdz 积分所做的功。我可以使用双 for 循环trap
来完成这项工作,但是还有其他更有效的方法(可能是使用数组和矢量化)在 Matlab 或 python 中完成这项工作吗?我的最终目标是找到评估积分最大的点。因此,从黄色代表大值的图像中,我们期望积分在虚线上方右侧某处最大。
另外,如果我想要积分的点数是整数,那么相对容易,但是如果我想要积分,比如 7.5 个点怎么办?我正在考虑使用fit
插值点,但我不确定这是否使任务过于复杂。
您可以使用cumsum
来加速trap
。计算累积和(@Benjamin提出的一维积分图像)
>>> import numpy as np
>>> csdata = np.cumsum(data, axis=1)
Run Code Online (Sandbox Code Playgroud)
与离散长度积分
>>> npoints = 6
>>> result = np.zeros_like(data)
>>> result[:-npoints, :] = csdata[npoints:, :] - csdata[:-npoints, :]
Run Code Online (Sandbox Code Playgroud)
这是图像中每个元素result
的矢量化。最后一行将用零填充。如果你想防止这种情况,你可以使用边界。cumdata[i+npoints, j] - cumdata[i, j]
i, j
npoints
reflect
np.pad
对于非离散间隔,您可以使用插值:
>>> from scipy.interpolate import interp2d
>>> C = 0.5 # to interpolate every npoints+C pixels
>>> y, x = np.mgrid[:data.shape[0], :data.shape[1]]
>>> ynew, xnew = np.mgrid[C:data.shape[0]+C, :data.shape[1]]
>>> f = interp2d(x, y, csdata)
>>> csnew = f(xnew, ynew)
Run Code Online (Sandbox Code Playgroud)
上面的代码在方向上移动规则网格C
像素y
,并在这些点处对累积数据进行插值csdata
(实际上,它对每个像素进行向量插值)。
那么长度的积分npoints+C
可得为
>>> npoints = 6
>>> result = np.zeros_like(data)
>>> result[:-npoints, :] = csnew[npoints:, :] - csdata[:-npoints, :]
Run Code Online (Sandbox Code Playgroud)
请注意,现在是上限csnew
(移位 6 实际上得到 6.5 个元素),使其在实践中对每 6.5 个点进行积分。
然后您可以找到最大值点:
>>> idx = np.argmax(result.ravel()) # ravel to get the 1D maximum point
>>> maxy, maxx = np.unravel_index(idx, data.shape) # get 2D coordinates of idx
Run Code Online (Sandbox Code Playgroud)