更快地执行numpy阵列的逐点交互?

更快地执行numpy阵列的逐点交互?,numpy,performance,curve-fitting,smoothing,Numpy,Performance,Curve Fitting,Smoothing,我有一个3D数据立方体,有两个空间维度,第三个是2D图像每个点的多波段光谱 H[x, y, bands] 给定一个波长(或波段号),我想提取对应于该波长的2D图像。这将是一个简单的数组片,如H[:,:,bnd]。类似地,给定一个空间位置(i,j),该位置的光谱为H[i,j] 我还想在光谱上“平滑”图像,以对抗光谱中的低光噪声。也就是说,对于频带bnd,我选择一个大小为wind的窗口,并将一个n次多项式拟合到该窗口中的频谱。使用polyfit和polyval,我可以找到波段bnd在该点的拟合光谱

我有一个3D数据立方体,有两个空间维度,第三个是2D图像每个点的多波段光谱

H[x, y, bands]
给定一个波长(或波段号),我想提取对应于该波长的2D图像。这将是一个简单的数组片,如
H[:,:,bnd]
。类似地,给定一个空间位置(i,j),该位置的光谱为
H[i,j]

我还想在光谱上“平滑”图像,以对抗光谱中的低光噪声。也就是说,对于频带
bnd
,我选择一个大小为
wind
的窗口,并将一个n次多项式拟合到该窗口中的频谱。使用polyfit和polyval,我可以找到波段
bnd
在该点的拟合光谱值

现在,如果我想从拟合值中得到
bnd
的整个图像,那么我必须在图像的每个
(I,j)
处执行此窗口拟合。我还想要
bnd
的二阶导数图像,即拟合光谱在每个点的二阶导数值


在点上运行时,我可以对每个
x*y
光谱进行polyfit polyval polyder。虽然这是可行的,但这是一个逐点操作。是否有一些pytho-numphonic方法可以更快地完成此操作?

如果对固定dx集的点(x+dx[i],y[i])进行最小二乘多项式拟合,然后在x处计算得到的多项式,结果是y[i]的(固定)线性组合。多项式的导数也是如此。所以你们只需要一个切片的线性组合。查找“Savitzky-Golay过滤器”

编辑以添加S-G过滤器工作原理的简要示例。我没有检查任何细节,因此您不应该依赖它来判断是否正确

因此,假设你使用一个宽度为5,阶数为2的过滤器。也就是说,对于每一个波段(忽略,暂时,在开始和结束时),我们将在两边取一个和两个,拟合一个二次曲线,并在中间看它的值。< /P> 所以,如果f(x)~=ax^2+bx+c和f(-2),f(-1),f(0),f(1),f(2)=p,q,r,s,t那么我们想要4a-2b+c~=p,a-b+c~=q,等等。最小二乘拟合意味着最小化(4a-2b+c-p)^2+(a-b+c-q)^2+(a+b+c-s)^2+(4a+2b+c-t)^2,这意味着(取偏导数w.r.t.a,b,c):

  • 4(4a-2b+c-p)+(a-b+c-q)+(a+b+c-s)+4(4a+2b+c-t)=0
  • -2(4a-2b+c-p)-(a-b+c-q)+(a+b+c-s)+2(4a+2b+c-t)=0
  • (4a-2b+c-p)+(a-b+c-q)+(c-r)+(a+b+c-s)+(4a+2b+c-t)=0
或者,简化

  • 22a+10c=4p+q+s+4t
  • 10b=-2p-q+s+2t
  • 10a+5c=p+q+r+s+t
所以a,b,c=p-q/2-r-s/2+t,(2(t-p)+(s-q))/10,(p+q+r+s+t)/5-(2p-q-2r-s+2t)

当然,c是拟合多项式在0处的值,因此是我们想要的平滑值。因此,对于每个空间位置,我们都有一个输入光谱数据的向量,从中我们通过乘以一个矩阵来计算平滑光谱数据,该矩阵的行(除了第一对和最后一对)看起来像[0…0-9/5 4/5 11/5 4/5-9/5 0…0],其中中心11/5位于矩阵的主对角线上

所以你可以对每个空间位置进行矩阵乘法;但是,因为它在任何地方都是相同的矩阵,所以只需调用
tensordot
即可。因此,如果
S
包含我刚才描述的矩阵(呃,等等,不是,我刚才描述的矩阵的转置),并且
A
是你的三维数据立方体,你的光谱平滑数据立方体将是
numpy.tensordot(A,S)


这将是重复我的警告的一个好时机:我没有检查上面几段中的任何细节,这只是为了说明它是如何工作的,以及为什么你可以在一个线性代数运算中完成整件事。

谢谢你提供的信息。SG滤波器确实是消除数据噪声的一个很好的工具。然而,这并不能真正回答我的问题,因为这仍然是对每个光谱的逐点计算。savitzky_golay过滤器采用一维数组作为输入。我想做一个立方体的形状(x,y,bnd-wind:bnd+wind)安装后,返回H[:,:,bnd]我不是建议你调用任何人的
savitzky_-golay
函数。我建议你先计算相关系数,然后逐面计算整个计算过程。事实上,你只需一次调用
numpy.tensordot
,就可以做到这一点。恐怕我不明白这个建议。请你详细说明一下,或者举个例子好吗?我现在不使用矩阵运算,只使用数组切片。在玩RTFM游戏时,我发现np.polyfit函数可以使用y列数组来适应
x[I],y[I]
。这可以将我的操作速度提高一个维度,因为我可以逐行处理多维数据集。这半成品回答了我自己的问题——但有更好的方法吗?听起来你只是在一个维度上平滑。。。为什么不直接调用scipy.ndimage.gaussian_filter1d(数据、窗口、轴=2)?