重新采样一个 numpy 数组
Resample a numpy array
像
这样的数组重新采样很容易
a = numpy.array([1,2,3,4,5,6,7,8,9,10])
使用整数 重采样因子。例如,因子 2 :
b = a[::2] # [1 3 5 7 9]
但是对于非整数重采样因子,它不会那么容易工作:
c = a[::1.5] # [1 2 3 4 5 6 7 8 9 10] => not what is needed...
应该是(带线性插值):
[1 2.5 4 5.5 7 8.5 10]
或(取数组中最近的邻居)
[1 3 4 6 7 9 10]
如何使用非整数重采样因子对 numpy 数组进行重采样?
应用示例:音频信号重采样/重调
NumPy 有 numpy.interp
进行线性插值:
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 有 scipy.interpolate.interp1d
可以进行线性和最近的插值(尽管最近的点可能并不明显):
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.])
如果你想要整数采样
a = numpy.array([1,2,3,4,5,6,7,8,9,10])
factor = 1.5
x = map(int,numpy.round(numpy.arange(0,len(a),factor)))
sampled = a[x]
由于您提到这是来自音频 .WAV 文件的数据,您可能会查看 scipy.signal.resample
。
Resample x
to num
samples using Fourier method along the given axis.
The resampled signal starts at the same value as x
but is sampled
with a spacing of len(x) / num * (spacing of x)
. Because a
Fourier method is used, the signal is assumed to be periodic.
您的线性阵列 a
不适合用来测试它,因为它在外观上不是周期性的。但是考虑 sin
数据:
x=np.arange(10)
y=np.sin(x)
y1, x1 =signal.resample(y,15,x) # 10 pts resampled at 15
将它们与两者进行比较
y1-np.sin(x1) # or
plot(x, y, x1, y1)
由于scipy.signal.resample
可以,我搜索了其他适合音频的算法。
Erik de Castro Lopo 的 SRC(a.k.a。Secret Rabbit Code a.k.a。libsamplerate)似乎是可用的最佳重采样算法之一。
是scikit的scikit.samplerate
用的,但是这个库好像安装比较麻烦(我放弃了Windows)。
幸运的是,libsamplerate
有一个易于使用且易于安装的 Python 包装器,由 Tino Wagner 制作:https://pypi.org/project/samplerate/。使用 pip install samplerate
安装。用法:
import samplerate
from scipy.io import wavfile
sr, x = wavfile.read('input.wav') # 48 khz file
y = samplerate.resample(x, 44100 * 1.0 / 48000, 'sinc_best')
许多重采样解决方案的有趣阅读/比较:
http://signalsprocessed.blogspot.com/2016/08/audio-resampling-in-python.html
附录: 重采样频率扫描(20hz 至 20khz)的频谱图比较:
1) 原创
2) 使用 libsamplerate / samplerate
模块重新采样
3) 使用 numpy.interp
("One-dimensional linear interpolation") 重新采样:
在信号处理中,您可以将重采样视为基本上重新缩放数组并使用最近、线性、立方等方法对缺失值或具有非整数索引的值进行插值。
使用scipy.interpolate.interp1d
,可以使用下面的函数实现一维重采样
def resample(x, factor, kind='linear'):
n = np.ceil(x.size / factor)
f = interp1d(np.linspace(0, 1, x.size), x, kind)
return f(np.linspace(0, 1, n))
例如:
a = np.array([1,2,3,4,5,6,7,8,9,10])
resample(a, factor=1.5, kind='linear')
产量
array([ 1. , 2.5, 4. , 5.5, 7. , 8.5, 10. ])
和
a = np.array([1,2,3,4,5,6,7,8,9,10])
resample(a, factor=1.5, kind='nearest')
产量
array([ 1., 2., 4., 5., 7., 8., 10.])
像
这样的数组重新采样很容易 a = numpy.array([1,2,3,4,5,6,7,8,9,10])
使用整数 重采样因子。例如,因子 2 :
b = a[::2] # [1 3 5 7 9]
但是对于非整数重采样因子,它不会那么容易工作:
c = a[::1.5] # [1 2 3 4 5 6 7 8 9 10] => not what is needed...
应该是(带线性插值):
[1 2.5 4 5.5 7 8.5 10]
或(取数组中最近的邻居)
[1 3 4 6 7 9 10]
如何使用非整数重采样因子对 numpy 数组进行重采样?
应用示例:音频信号重采样/重调
NumPy 有 numpy.interp
进行线性插值:
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 有 scipy.interpolate.interp1d
可以进行线性和最近的插值(尽管最近的点可能并不明显):
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.])
如果你想要整数采样
a = numpy.array([1,2,3,4,5,6,7,8,9,10])
factor = 1.5
x = map(int,numpy.round(numpy.arange(0,len(a),factor)))
sampled = a[x]
由于您提到这是来自音频 .WAV 文件的数据,您可能会查看 scipy.signal.resample
。
Resample
x
tonum
samples using Fourier method along the given axis.The resampled signal starts at the same value as
x
but is sampled with a spacing oflen(x) / num * (spacing of x)
. Because a Fourier method is used, the signal is assumed to be periodic.
您的线性阵列 a
不适合用来测试它,因为它在外观上不是周期性的。但是考虑 sin
数据:
x=np.arange(10)
y=np.sin(x)
y1, x1 =signal.resample(y,15,x) # 10 pts resampled at 15
将它们与两者进行比较
y1-np.sin(x1) # or
plot(x, y, x1, y1)
由于scipy.signal.resample
可以
Erik de Castro Lopo 的 SRC(a.k.a。Secret Rabbit Code a.k.a。libsamplerate)似乎是可用的最佳重采样算法之一。
是scikit的
scikit.samplerate
用的,但是这个库好像安装比较麻烦(我放弃了Windows)。幸运的是,
libsamplerate
有一个易于使用且易于安装的 Python 包装器,由 Tino Wagner 制作:https://pypi.org/project/samplerate/。使用pip install samplerate
安装。用法:import samplerate from scipy.io import wavfile sr, x = wavfile.read('input.wav') # 48 khz file y = samplerate.resample(x, 44100 * 1.0 / 48000, 'sinc_best')
许多重采样解决方案的有趣阅读/比较: http://signalsprocessed.blogspot.com/2016/08/audio-resampling-in-python.html
附录: 重采样频率扫描(20hz 至 20khz)的频谱图比较:
1) 原创
2) 使用 libsamplerate / samplerate
模块重新采样
3) 使用 numpy.interp
("One-dimensional linear interpolation") 重新采样:
在信号处理中,您可以将重采样视为基本上重新缩放数组并使用最近、线性、立方等方法对缺失值或具有非整数索引的值进行插值。
使用scipy.interpolate.interp1d
,可以使用下面的函数实现一维重采样
def resample(x, factor, kind='linear'):
n = np.ceil(x.size / factor)
f = interp1d(np.linspace(0, 1, x.size), x, kind)
return f(np.linspace(0, 1, n))
例如:
a = np.array([1,2,3,4,5,6,7,8,9,10])
resample(a, factor=1.5, kind='linear')
产量
array([ 1. , 2.5, 4. , 5.5, 7. , 8.5, 10. ])
和
a = np.array([1,2,3,4,5,6,7,8,9,10])
resample(a, factor=1.5, kind='nearest')
产量
array([ 1., 2., 4., 5., 7., 8., 10.])