Python 如何通过使用浮点和整数窗口大小的平均方法对一维数组值进行下采样?

Python 如何通过使用浮点和整数窗口大小的平均方法对一维数组值进行下采样?,python,numpy,scipy,signal-processing,downsampling,Python,Numpy,Scipy,Signal Processing,Downsampling,我尝试使用平均法将固定的[Mx1]向量向下采样到任何给定的[Nx1]维度。我有一个动态窗口大小,根据所需的输出数组每次都会更改。所以,在某些情况下,我很幸运,得到了与窗口大小完全匹配的int窗口大小,有时我得到了浮点数作为窗口大小。但是,如何使用浮动大小窗口从固定的[Mx1]向量生成[Nx1]大小的向量 下面是我尝试过的代码: chunk = 0.35 def fixed_meanVector(vec, chunk): size = (vec.size*chunk) #size of ou

我尝试使用平均法将固定的[Mx1]向量向下采样到任何给定的[Nx1]维度。我有一个动态窗口大小,根据所需的输出数组每次都会更改。所以,在某些情况下,我很幸运,得到了与窗口大小完全匹配的int窗口大小,有时我得到了浮点数作为窗口大小。但是,如何使用浮动大小窗口从固定的[Mx1]向量生成[Nx1]大小的向量

下面是我尝试过的代码:

chunk = 0.35
def fixed_meanVector(vec, chunk):
   size = (vec.size*chunk) #size of output according to the chunk
   R    = (vec.size/size) #windows size to transform array into chunk size
   pad_size = math.ceil(float(vec.size)/R)*R - vec.size
   vec_padded = np.append(vec, np.zeros(pad_size)*np.NaN)

   print "Org Vector: ",vec.size, "output Size: ",size, "Windows Size: ",R, "Padding size", pad_size
   newVec = scipy.nanmean(vec_padded.reshape(-1,R), axis=1)
   print "New Vector shape: ",newVec.shape
   return newVec

print "Word Mean of N values Similarity: ",cosine(fixed_meanVector(vector1, chunk)
                                                      ,fixed_meanVector(vector2, chunk))
New Vector shape:  (200,)
Org Vector:  400 output Size:  140.0 Windows Size:  2.85714285714 Padding  size 0.0
New Vector shape:  (200,)
0.46111661289
输出:

chunk = 0.35
def fixed_meanVector(vec, chunk):
   size = (vec.size*chunk) #size of output according to the chunk
   R    = (vec.size/size) #windows size to transform array into chunk size
   pad_size = math.ceil(float(vec.size)/R)*R - vec.size
   vec_padded = np.append(vec, np.zeros(pad_size)*np.NaN)

   print "Org Vector: ",vec.size, "output Size: ",size, "Windows Size: ",R, "Padding size", pad_size
   newVec = scipy.nanmean(vec_padded.reshape(-1,R), axis=1)
   print "New Vector shape: ",newVec.shape
   return newVec

print "Word Mean of N values Similarity: ",cosine(fixed_meanVector(vector1, chunk)
                                                      ,fixed_meanVector(vector2, chunk))
New Vector shape:  (200,)
Org Vector:  400 output Size:  140.0 Windows Size:  2.85714285714 Padding  size 0.0
New Vector shape:  (200,)
0.46111661289
在上面的示例中,我需要在Nx1([140x1])维度中向下采样([400x1])向量。因此,动态窗口大小[2.857x1]可用于减少样本[Mx1]向量。但是,在这种情况下,我得到的是一个向量[200x1]作为我的输出,而不是[140x1],这是因为它将浮动窗口提升到面粉(2.85),并使用->[2x1]进行下采样。
填充为零,因为我的窗口大小非常适合新的[Nx1]维度。那么,是否有任何方法可以使用这种类型的窗口大小来对[Mx1]向量进行下采样?

一旦
M%N>0
就可以对其进行向量化,但这并不自然。因为用于构建结果数组的单元格数量不是恒定的,在您的示例中是3到4

自然的方法是穿过阵列,在每个箱子处进行调整:

这个想法是把每个箱子装满,直到溢出来。然后切下溢出物(携带)并保存到下一个垃圾箱。使用int算法,最后一个进位总是空的

守则:

def resized(data,N):
    M=data.size
    res=empty(N,data.dtype)
    carry=0
    m=0
    for n in range(N):
        sum = carry
        while m*N - n*M < M :
            sum += data[m]
            m += 1
        carry = (m-(n+1)*M/N)*data[m-1]
        sum -= carry
        res[n] = sum*N/M
    return res
它起作用了,但不是很快。幸运的是,您可以使用
numba

from numba import jit
resized2=jit(resized)             

In [7]: %timeit resized2(rand(400),140)
1 loops, best of 3: 8.21 µs per loop
可能比任何纯
numpy
解决方案都快(此处为
N=3*M
):

注意:如果
M>N
,它也可以工作

In [9]: resized(arange(4.),9)
Out[9]: array([ 0.  ,  0.  ,  0.75,  1.  ,  1.5 ,  2.  ,  2.25,  3.  ,  3.  ])

你做错了,你为你所需要的抽取建立了一个窗口,而不是相反

说你不能有一个高于fs/2的BW,否则你会有讨厌的别名

所以要解决这个问题,你不只是“平均”,而是低通,这样高于fs/2的频率就低于你可接受的噪声下限

是一种有效的低通滤波器,您只是将其应用于错误的阵列

通常的情况是

因此,为了能够任意抽取N到M个样本,算法如下:

  • 在当前样本和目标样本之间查找
  • 通过
    LCM/N

  • 使用停止频率设计一个滤波器
    wsn是固定数吗?@sung No。。。它是输出的大小。。。在代码中它是。。。size=(vec.size*chunk)如果M和N都不固定,那么提出一个非常通用的算法有点复杂。因为你的向量不是太大,我会说迭代地做。我的意思是,用一个有底限的整数做移动平均。然后,您将得到一个大于所需的采样向量。您可以使用新向量再次重复该过程,等等。@Sung[Mx1]是固定的,我们需要将其降采样到任何[Nx1]维度。我对这个问题做了一些修改,请再读一遍,谢谢你的关注:)嘿,你的方法很酷!我已经尝试过你的方法,它可以将向量减少到任何大小。不知道你的方法有什么局限性。我只是想了解你是怎么做的:)我补充了一些解释,时间不早了;)哇!这是一个很好的答案:)。。如果可能,请添加更多信息。。你的函数在某种程度上类似于savgol_滤波器(Savitzky-Golay滤波器)和插值,但更好,因为输出向量的期望值独立于某个固定的窗口长度,对吗?你一次就解决了我的两个问题。你建议的方法对我来说有点混乱,因为我认为它在信号处理等方面非常适用。但是,我只想通过平均值对数组进行下采样。有没有比这种方法更好的方法请分享。你的答案很难理解:)所以,看起来你并不太在意结果,只要做
    window=np.ones(ceil(float(n)/len(x))
    window=window/len(window)
    scipy.signal.resample(x,n,window=window)
    当然我也会尝试这种方法:)但是是否可以通过保留原始向量中的实际含义来减少数组的采样?顺便说一句,您所做的是信号处理。或者如果您根本不关心别名,请调用
    scipy.signal.resample(x,n)
     Upsample -> Lowpass -> Downsample
    
    2/K <= M/LCM
    
    ceil(2*LCM/M) = K