说我some_data
形状为(1, n)
。我有一个新的incoming_data
形状(1, n±x)
,其中x是一个比n
小得多的正整数。我想挤压或拉伸incoming_data
,使其长度与n
相同。如何使用SciPy堆栈完成这项工作?
这是我想要完成的一个例子。
# Stretch arr2 to arr1's shape while "filling in" interpolated value
arr1 = np.array([1, 5, 2, 3, 7, 2, 1])
arr2 = np.array([1, 5, 2, 3, 7, 1])
result
> np.array([1, 5, 2, 3, 6.x, 2.x 1]) # of shape (arr1.shape)
另一个例子:
# Squeeze arr2 to arr1's shape while placing interpolated value.
arr1 = np.array([1, 5, 2, 3, 7, 2, 1])
arr2 = np.array([1, 5, 2, 3, 4, 7, 2, 1])
result
> np.array([1, 5, 2, 3.x, 7.x, 2.x, 1]) # of shape (arr1.shape)
答案 0 :(得分:9)
您可以使用scipy.interpolate.interp1d
实现此简单压缩或拉伸数据。我不是说这一定是有道理的(你使用什么样的插值会产生很大的不同,如果你能正确猜出底层函数的行为,你通常只会得到一个合理的结果),但你可以做到这一点。
我们的想法是将原始数组作为x
值插入其索引,然后使用较稀疏的x
网格执行插值,同时保持其端点相同。因此,基本上您必须对离散数据进行连续近似,并在必要的点重新采样:
import numpy as np
import scipy.interpolate as interp
import matplotlib.pyplot as plt
arr_ref = np.array([1, 5, 2, 3, 7, 1]) # shape (6,), reference
arr1 = np.array([1, 5, 2, 3, 7, 2, 1]) # shape (7,), to "compress"
arr2 = np.array([1, 5, 2, 7, 1]) # shape (5,), to "stretch"
arr1_interp = interp.interp1d(np.arange(arr1.size),arr1)
arr1_compress = arr1_interp(np.linspace(0,arr1.size-1,arr_ref.size))
arr2_interp = interp.interp1d(np.arange(arr2.size),arr2)
arr2_stretch = arr2_interp(np.linspace(0,arr2.size-1,arr_ref.size))
# plot the examples, assuming same x_min, x_max for all data
xmin,xmax = 0,1
fig,(ax1,ax2) = plt.subplots(ncols=2)
ax1.plot(np.linspace(xmin,xmax,arr1.size),arr1,'bo-',
np.linspace(xmin,xmax,arr1_compress.size),arr1_compress,'rs')
ax2.plot(np.linspace(xmin,xmax,arr2.size),arr2,'bo-',
np.linspace(xmin,xmax,arr2_stretch.size),arr2_stretch,'rs')
ax1.set_title('"compress"')
ax2.set_title('"stretch"')
结果图:
在图中,蓝色圆圈是原始数据点,红色方块是插值的(这些在边界处重叠)。正如您所看到的,我称之为压缩和拉伸实际上是底层(默认情况下为线性)函数的上采样和下采样。这就是为什么我说你必须非常小心插值:如果你的期望与你的数据不符,你会得到非常错误的结果。
答案 1 :(得分:2)
还有另外一个非常适合上采样和下采样的软件包:resampy
。它的命令比scipy.interpolate.interp1d
更简单,但仅使用单个插值函数。正如@Andras Deak所说,在选择插值函数时必须小心。
import numpy as np
import resampy
from matplotlib import pyplot as plt
x_mesh = np.linspace(0,1,10)
short_arr = np.sin(x_mesh*2*np.pi)
plt.plot(short_arr)
interp_arr = resampy.resample(short_arr, 20, 100)
plt.plot(interp_arr)
resampy
使用“带限制的正弦插值”。查看文档以获取更多信息。如果您的阵列最初来自具有本地频率分量的数据,例如声音,图像和其他时间序列数据。我在音频上的一些tensorflow示例中使用了它。我不确定您的示例数组是否为演示目的而较小,但是如果确实是数组的大小,则无论您使用线性,样条线还是其他方法,插值都是不好的。
您的示例展示的不仅仅是插值。看来您找到了一部分匹配的数组(例如[1,5,2,3]
),然后对其余部分进行了插值。根据您要匹配数组的开头还是任意数量的补丁,您可能需要两种方法:一种是识别要插值的数组的正确部分,另一种是插值这些部分的方法。如果是这种情况,请查看numpy.isin
中的基本方法,或查看levenshtein距离以更广泛地匹配一组子字符串。