重塑xAxis上的数组并在Python中填充平均值?

时间:2015-11-27 16:50:20

标签: python arrays numpy

我试图在Python中重塑数组并用平均值填充它。 例如:

  • 给定数组:[2,3,-20,10,4]
  • 搜索阵列:[2,2.5,3,-8.5,-20, -5,10,7,4]

更高级:我有一个包含1000个样本的数组。但我知道它应该是1300个样本长。如何将数组缩放到新的长度并用均值填充它? 插值解决方案也让我开心

编辑: 我被问及一个例子,我的意思是分布均匀的值。例如:传感器应提供100Hz的数据。但有时传感器无法提供完整的采样频率。而不是在13秒内获得1300个样本,我得到900到1300个样本之间的随机量。我不知道何时缺少价值。我想在整个数组上统一分配缺失值,并为它们分配一个有意义的值。

谢谢

3 个答案:

答案 0 :(得分:3)

这取决于分布均匀的值的含义。假设您的值位于均匀间隔的网格上,则使用插值的以下解决方案可能有意义:

>>> import numpy as np
>>> new_length = 9
>>> b = np.interp(np.linspace(0,len(a)-1,new_length),range(len(a)),a)
>>> b
array([  2. ,   2.5,   3. ,  -8.5, -20. ,  -5. ,  10. ,   7. ,   4. ])

这也适用于len(a)=1000new_length=1300

答案 1 :(得分:1)

您可以在np.diff处使用区分技巧。因此,假设A作为输入数组,您可以 -

out = np.empty(2*A.size-1)
out[0::2] = A
out[1::2] = (np.diff(A) + 2*A[:-1]).astype(float)/2 # Interpolated values

这里的技巧是,当添加两个前一个元素时,两个连续元素之间的区别将是这两个元素之间的平均值。我们只是在输入1D数组的整个范围内使用这个技巧来获得我们想要的插值数组。

示例运行 -

In [34]: A
Out[34]: array([  2,   3, -20,  10,   4])

In [35]: out = np.empty(2*A.size-1)
    ...: out[0::2] = A
    ...: out[1::2] = (np.diff(A) + 2*A[:-1]).astype(float)/2
    ...: 

In [36]: out
Out[36]: array([  2. ,   2.5,   3. ,  -8.5, -20. ,  -5. ,  10. ,   7. ,   4. ])

我认为@thomas's solution将是这里的首选方法,因为我们基本上在考虑特定情况时进行插值。但是,因为我最感兴趣的是代码的性能,这是一个比较这两个解决方案的运行时测试 -

In [62]: def interp_based(A):   # @thomas's solution
    ...:    new_length = 2*A.size-1
    ...:    return np.interp(np.linspace(0,len(A)-1,new_length),range(len(A)),A)
    ...: 
    ...: def diff_based(A): 
    ...:    out = np.empty(2*A.size-1)
    ...:    out[0::2] = A
    ...:    out[1::2] = (np.diff(A) + 2*A[:-1]).astype(float)/2
    ...:    return out
    ...: 

In [63]: A = np.random.randint(0,10000,(10000))

In [64]: %timeit interp_based(A)
1000 loops, best of 3: 932 µs per loop

In [65]: %timeit diff_based(A)
10000 loops, best of 3: 148 µs per loop

答案 2 :(得分:0)

我写了一个对我来说更好的解决方案。我在大型数组上出现浮动错误时遇到了一些问题。 为了纠正那些我随机插入一些丢失的。也许有人知道如何避免这种情况 我确信代码非常优化,随意这样做。

import numpy as np
def resizeArray(data, newLength):

    datalength = len(data)
    if (datalength == newLength): return data

    appendIndices = []
    appendNow = 0
    step = newLength / datalength
    increase =  step % 1
    for i in np.arange(0, datalength-2, step):
        appendNow += increase
        if appendNow >= 1:
            appendIndices.append(round(i,0))
            appendNow = appendNow % 1

    #still missing values due to floating errors?
    diff = newLength - datalength - len(appendIndices)
    if diff > 0:
        for i in range(0, diff):
            appendIndices.append(np.random.randint(1, datalength - 2))

    #insert average at the specified indizes
    appendVals = [(data[i] + data[i+1]) / 2 for i in appendIndices]
    a = np.insert(data, appendIndices, appendVals)

    return a