Python 重新采样一个 numpy 数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29085268/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Resample a numpy array
提问by Basj
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 :
具有整数重采样因子。例如,因子为 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?
如何使用非整数重采样因子对 numpy 数组进行重采样?
Example of application: audio signal resampling / repitching
应用示例:音频信号重采样/重音
采纳答案by Basj
As scipy.signal.resample
can be very slow, I searched for other algorithms adapted for audio.
由于scipy.signal.resample
可能非常慢,我搜索了适用于音频的其他算法。
It seems that Erik de Castro Lopo's SRC(a.k.a. Secret Rabbit Code a.k.a. libsamplerate) is one of the best resampling algorithms available.
Erik de Castro Lopo 的SRC(又名 Secret Rabbit Code 又名 libsamplerate)似乎是可用的最佳重采样算法之一。
It is used by scikit's
scikit.samplerate
, but this library seems to be complicated to install (I gave up on Windows).Fortunately, there is an easy-to-use and easy-to-install Python wrapper for
libsamplerate
, made by Tino Wagner: https://pypi.org/project/samplerate/. Installation withpip install samplerate
. Usage: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')
它被 scikit's 使用
scikit.samplerate
,但是这个库安装起来似乎很复杂(我放弃了 Windows)。幸运的是,有一个易于使用且易于安装的 Python 包装器
libsamplerate
,由 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')
Interesting reading / comparison of many resampling solutions: http://signalsprocessed.blogspot.com/2016/08/audio-resampling-in-python.html
许多重采样解决方案的有趣阅读/比较:http: //signalsprocessed.blogspot.com/2016/08/audio-resampling-in-python.html
Addendum:comparison of spectrograms of a resampled frequency sweep (20hz to 20khz):
附录:重采样频率扫描(20hz 到 20khz)的频谱图比较:
1) Original
1) 原创
2) Resampled with libsamplerate / samplerate
module
2) 使用 libsamplerate /samplerate
模块重新采样
3) Resampled with numpy.interp
("One-dimensional linear interpolation"):
3)重新采样numpy.interp
(“一维线性插值”):
回答by xnx
NumPy has numpy.interp
which does linear interpolation:
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 has scipy.interpolate.interp1d
which can do linear and nearest interpolation (though which point is nearest might not be obvious):
SciPyscipy.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.])
回答by EngineeredE
And if you wan the integer sampling
如果你想要整数采样
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]
回答by hpaulj
Since you mention this being data from an audio .WAV file, you might look at scipy.signal.resample
.
由于您提到这是来自音频 .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.
重新取样
x
到num
使用傅立叶方法沿给定轴的样品。重新采样的信号以与 相同的值开始,
x
但采样间隔为len(x) / num * (spacing of x)
。因为使用了傅立叶方法,所以假设信号是周期性的。
Your linear array a
is not a good one to test this on, since it isn't periodic in appearance. But consider sin
data:
您的线性阵列a
不适合对此进行测试,因为它的外观不是周期性的。但考虑sin
数据:
x=np.arange(10)
y=np.sin(x)
y1, x1 =signal.resample(y,15,x) # 10 pts resampled at 15
compare these with either
将这些与任一比较
y1-np.sin(x1) # or
plot(x, y, x1, y1)
回答by yellow01
In signal processing, you can think of resampling as basically rescaling the array and interpolating the missing values or values with non-integer index using nearest, linear, cubic, etc methods.
在信号处理中,您可以将重采样视为基本上重新缩放数组并使用最近、线性、三次等方法插入缺失值或具有非整数索引的值。
Using scipy.interpolate.interp1d
, you can achieve one dimensional resampling using the following function
使用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))
e.g.:
例如:
a = np.array([1,2,3,4,5,6,7,8,9,10])
resample(a, factor=1.5, kind='linear')
yields
产量
array([ 1. , 2.5, 4. , 5.5, 7. , 8.5, 10. ])
and
和
a = np.array([1,2,3,4,5,6,7,8,9,10])
resample(a, factor=1.5, kind='nearest')
yields
产量
array([ 1., 2., 4., 5., 7., 8., 10.])