我试图在Python中重塑数组并用平均值填充它。 例如:
更高级:我有一个包含1000个样本的数组。但我知道它应该是1300个样本长。如何将数组缩放到新的长度并用均值填充它? 插值解决方案也让我开心
编辑: 我被问及一个例子,我的意思是分布均匀的值。例如:传感器应提供100Hz的数据。但有时传感器无法提供完整的采样频率。而不是在13秒内获得1300个样本,我得到900到1300个样本之间的随机量。我不知道何时缺少价值。我想在整个数组上统一分配缺失值,并为它们分配一个有意义的值。
谢谢
答案 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)=1000
和new_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