Resample a numpy array

Basj picture Basj · Mar 16, 2015 · Viewed 50k times · Source

It's easy to resample an array like

 a = numpy.array([1,2,3,4,5,6,7,8,9,10])

with an integer resampling factor. For instance, with a factor 2 :

b = a[::2]    # [1 3 5 7 9]

But with a non-integer resampling factor, it doesn't work so easily :

c = a[::1.5]    # [1 2 3 4 5 6 7 8 9 10]  => not what is needed...

It should be (with linear interpolation):

[1 2.5 4 5.5 7 8.5 10]

or (by taking the nearest neighbour in the array)

[1 3 4 6 7 9 10]

How to resample a numpy array with a non-integer resampling factor?

Example of application: audio signal resampling / repitching

Answer

xnx picture xnx · Mar 16, 2015

NumPy has numpy.interp which does linear interpolation:

In [1]: numpy.interp(np.arange(0, len(a), 1.5), np.arange(0, len(a)), a)
Out[1]: array([  1. ,   2.5,   4. ,   5.5,   7. ,   8.5,  10. ])

SciPy has scipy.interpolate.interp1d which can do linear and nearest interpolation (though which point is nearest might not be obvious):

In [2]: from scipy.interpolate import interp1d
In [3]: xp = np.arange(0, len(a), 1.5)
In [4]: lin = interp1d(np.arange(len(a)), a)

In [5]: lin(xp)
Out[5]: array([  1. ,   2.5,   4. ,   5.5,   7. ,   8.5,  10. ])

In [6]: nearest = interp1d(np.arange(len(a)), a, kind='nearest')

In [7]: nearest(xp)
Out[7]: array([  1.,   2.,   4.,   5.,   7.,   8.,  10.])