- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试使用一个带时变截止频率的带通滤波器来使用Python。我目前使用的例程将我的信号分割成等长度的时间段,然后在每次将信号合并之前,对每个段应用一个具有特定于时间的参数的滤波器。参数是基于预先存在的估计。
我所遇到的问题是,在应用了过滤器之后出现的每个时间段的边缘都有“涟漪”。这会导致我的信号不连续,干扰我的滤波后数据分析。
我希望有人能告诉我,在Python中是否存在用于实现具有时变参数的过滤器的现有例程?另外,关于我如何解决这个问题的建议将非常感谢。
编辑——下面添加了我想做的事情的示例。
假设我有一个信号x(t)。我想用参数(100200)Hz的带通滤波器对上半部分进行滤波。下半部分我想用参数(140, 240)Hz滤波。我迭代X(t),将我的过滤器应用到每一半,然后重新组合结果。一些示例代码可能如下所示:
outputArray = np.empty(len(x))
segmentSize = len(x) / 2
filtParams = [(100, 200), (140, 240)]
for i in range(2):
tempData = x[i*segmentSize:(i+1)*segmentSize]
tempFiltered = bandPassFilter(tempData, parameters=filtParams[i])
outputArray[i*segmentSize:(i+1)*segmentSize] = tempFiltered
from audiolazy import *
import scipy.signal as sig
import numpy as np
from pylab import *
def sineGenerator( ts, f, rate, noiseLevel=None ):
"""generate a sine tone with time, frequency, sample rate and noise specified"""
fs = np.ones(len(ts)) * f
y = np.sin(2*np.pi*fs*ts)
if noiseLevel: y = y + np.random.randn(len(y))/float(noiseLevel)
return y
def bandPassFilter( y, passFreqs, rate, order ):
"""STATIC bandpass filter using scipy.signal Butterworth filter"""
nyquist = rate / 2.0
Wn = np.array([passFreqs[0]/nyquist, passFreqs[1]/nyquist])
z, p, k = sig.butter(order, Wn, btype='bandpass', output='zpk')
b, a = sig.zpk2tf(z, p, k)
return sig.lfilter(b, a, y)
if __name__ == '__main__':
rate = 1e4
ts = np.arange(0, 10, 1/rate)
# CHANGING THE FILTER AFFECTS THE LEVEL OF NOISE
ys = sineGenerator(ts, 600.0, 1e4, noiseLevel=1.0) # a 600Hz signal with noise
filts = [[500, 700], [550, 650], [580, 620]]
for f in filts:
tempFilt = bandPassFilter( ys, f, rate, order=2 )
tempFreq = instantaneousFrequency( tempFilt, rate )
plot( ts[1:], tempFreq, alpha=.7, label=str(f).strip('[]') )
ylim( 500, 750 )
xlabel( 'time' )
ylabel( 'instantaneous frequency (Hz)' )
legend(frameon=False)
title('changing filter passband and instantaneous frequency')
savefig('changingPassBand.png')
def audioLazyFilter( y, rate, Wp, Ws ):
"""implement a Butterworth filter using audiolazy"""
s, Hz = sHz(rate)
Wp = Wp * Hz # Bandpass range in rad/sample
Ws = Ws * Hz # Bandstop range in rad/sample
order, new_wp_divpi = sig.buttord(Wp/np.pi, Ws/np.pi, gpass=dB10(.6), gstop=dB10(.1))
ssfilt = sig.butter(order, new_wp_divpi, btype='bandpass')
filt_butter = ZFilter(ssfilt[0].tolist(), ssfilt[1].tolist())
return list(filt_butter(y))
AL_filtered = audioLazyFilter( ys, rate, np.array([580, 620]), np.array([570, 630]) )
SP_filtered = bandPassFilter( ys, [580, 620], rate, order=2 )
plot(ts[1:], instantaneousFrequency( SP_filtered, 1e4 ), alpha=.75, label='scipy.signal Butterworth filter')
plot(ts[1:], instantaneousFrequency( AL_filtered, 1e4 ), 'r', alpha=.75, label='audiolazy Butterworth filter')
最佳答案
使用时变滤波器的本地工作原理
from audiolazy import sHz, white_noise, line, resonator, AudioIO
rate = 44100
s, Hz = sHz(rate)
sig = white_noise() # Endless white noise Stream
dur = 8 * s # Some few seconds of audio
freq = line(dur, 200, 800) # A lazy iterable range
bw = line(dur, 100, 240)
filt = resonator(freq * Hz, bw * Hz) # A simple bandpass filter
with AudioIO(True) as player:
player.play(filt(sig), rate=rate)
list(filt(sig))
或< > >。还有很多其他的资源可能是有用的,例如在z变换滤波器方程中直接应用时变系数。
In [1]: from audiolazy import *
In [2]: resonator
Out[2]:
{('freq_poles_exp',): <function audiolazy.lazy_filters.freq_poles_exp>,
('freq_z_exp',): <function audiolazy.lazy_filters.freq_z_exp>,
('poles_exp',): <function audiolazy.lazy_filters.poles_exp>,
('z_exp',): <function audiolazy.lazy_filters.z_exp>}
In [3]: resonator.default
Out[3]: <function audiolazy.lazy_filters.poles_exp>
filt(sig).take(inf)
在内部调用
StrategyDict
函数,从中可以获得一些帮助
In [4]: resonator.poles_exp?
Type: function
String Form:<function poles_exp at 0x2a55b18>
File: /usr/lib/python2.7/site-packages/audiolazy/lazy_filters.py
Definition: resonator.poles_exp(freq, bandwidth)
Docstring:
Resonator filter with 2-poles (conjugated pair) and no zeros (constant
numerator), with exponential approximation for bandwidth calculation.
Parameters
----------
freq :
Resonant frequency in rad/sample (max gain).
bandwidth :
Bandwidth frequency range in rad/sample following the equation:
``R = exp(-bandwidth / 2)``
where R is the pole amplitude (radius).
Returns
-------
A ZFilter object.
Gain is normalized to have peak with 0 dB (1.0 amplitude).
filt = resonator.poles_exp(freq=freq * Hz, bandwidth=bw * Hz)
resonator
只是一个数字,将单元从HZ转换到RAAD/SAMPLE,就像大多数音频文件中使用的一样。
resonator.poles_exp
和
Hz
(
freq = pi/4
已经在
bw = pi/8
命名空间中):
In [5]: filt = resonator(freq=pi/4, bandwidth=pi/8)
In [6]: filt
Out[6]:
0.233921
------------------------------------
1 - 1.14005 * z^-1 + 0.675232 * z^-2
In [7]: type(filt)
Out[7]: audiolazy.lazy_filters.ZFilter
pi
对象。
In [8]: freq, bw = pi/4, pi/8
In [9]: R = e ** (-bw / 2)
In [10]: c = cos(freq) * 2 * R / (1 + R ** 2) # AudioLazy included the cosine
In [11]: gain = (1 - R ** 2) * sqrt(1 - c ** 2)
audiolazy
来完成:
In [12]: denominator = 1 - 2 * R * c * z ** -1 + R ** 2 * z ** -2
In [13]: gain / denominator
Out[14]:
0.233921
------------------------------------
1 - 1.14005 * z^-1 + 0.675232 * z^-2
In [15]: type(_) # The "_" is the last returned value in IPython
Out[15]: audiolazy.lazy_filters.ZFilter
In [16]: coeff = Stream([1, -1, 1, -1, 1, -1, 1, -1, 1, -1]) # Cast from a list
In [17]: (1 - coeff * z ** -2)(impulse()).take(inf)
Out[17]: [1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
z
流:
In [18]: coeff = Stream((1, -1, 1, -1, 1, -1, 1, -1, 1, -1)) # Cast from a tuple
In [19]: (1 - coeff * z ** -2)([1, 0, 0, 0, 0, 0, 0]).take(inf)
Out[19]: [1.0, 0.0, -1, 0, 0, 0, 0]
In [20]: from numpy import array
In [21]: array_data = array([1, -1, 1, -1, 1, -1, 1, -1, 1, -1])
In [22]: coeff = Stream(array_data) # Cast from an array
In [23]: (1 - coeff * z ** -2)([0, 1, 0, 0, 0, 0, 0]).take(inf)
Out[23]: [0.0, 1.0, 0, 1, 0, 0, 0]
z
,它获取范围“length”而不是“step”。
In [24]: import numpy
In [25]: numpy.linspace(10, 20, 5) # Start, stop (included), length
Out[25]: array([ 10. , 12.5, 15. , 17.5, 20. ])
In [26]: numpy.linspace(10, 20, 5, endpoint=False) # Makes stop not included
Out[26]: array([ 10., 12., 14., 16., 18.])
In [27]: line(5, 10, 20).take(inf) # Length, start, stop (range-like)
Out[27]: [10.0, 12.0, 14.0, 16.0, 18.0]
In [28]: line(5, 10, 20, finish=True).take(inf) # Include the "stop"
Out[28]: [10.0, 12.5, 15.0, 17.5, 20.0]
In [29]: five_items = _ # List from the last Out[] value
In [30]: @tostream
....: def repeater(sig, n):
....: for el in sig:
....: for _ in xrange(n):
....: yield el
....:
In [31]: repeater(five_items, 2).take(inf)
Out[31]: [10.0, 10.0, 12.5, 12.5, 15.0, 15.0, 17.5, 17.5, 20.0, 20.0]
impulse()
和
numpy.linspace
变成:
chunk_size = 100
freq = repeater(line(dur / chunk_size, 200, 800), chunk_size)
bw = repeater(line(dur / chunk_size, 100, 240), chunk_size)
signal = thub(sig, 2) # T-Hub is a T (tee) auto-copy
filt1(signal) * line(dur, 0, 1) + filt2(signal) * line(dur, 1, 0)
freq
并给予半功率带宽(~3dB)直接。我已经做了四个例子,代码是AA>,并且我已经更新了AdioLoZy以包含一个
bw
高斯分布的噪声流。请注意,GIST中的代码没有优化,它是在这个特定的情况下工作的,并且Chirp示例使得它由于“每个样本”系数查找行为而变得非常慢。瞬时频率可以从/采样中的[过滤]数据得到:
diff(unwrap(phase(hilbert(filtered_data))))
thub
或另一种在离散时间内找到导数的方法中,
sig1, sig2 = tee(sig, 2)
是从“cc>函数中给出的解析信号(离散希尔伯特变换是它的结果的虚部),另外两个是来自AdioLoZy的辅助函数。
filt(sig1)
这最后一个噪声啁啾。
filt(sig2)
要快,并且更容易实现,因为所有
order = 2
策略都接受流实例作为有效输入。以下是两个谐振器级联(即二阶滤波器)的曲线图:
关于python - 在Python中应用时变过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18128057/
我正在处理一组标记为 160 个组的 173k 点。我想通过合并最接近的(到 9 或 10 个组)来减少组/集群的数量。我搜索过 sklearn 或类似的库,但没有成功。 我猜它只是通过 knn 聚类
我有一个扁平数字列表,这些数字逻辑上以 3 为一组,其中每个三元组是 (number, __ignored, flag[0 or 1]),例如: [7,56,1, 8,0,0, 2,0,0, 6,1,
我正在使用 pipenv 来管理我的包。我想编写一个 python 脚本来调用另一个使用不同虚拟环境(VE)的 python 脚本。 如何运行使用 VE1 的 python 脚本 1 并调用另一个 p
假设我有一个文件 script.py 位于 path = "foo/bar/script.py"。我正在寻找一种在 Python 中通过函数 execute_script() 从我的主要 Python
这听起来像是谜语或笑话,但实际上我还没有找到这个问题的答案。 问题到底是什么? 我想运行 2 个脚本。在第一个脚本中,我调用另一个脚本,但我希望它们继续并行,而不是在两个单独的线程中。主要是我不希望第
我有一个带有 python 2.5.5 的软件。我想发送一个命令,该命令将在 python 2.7.5 中启动一个脚本,然后继续执行该脚本。 我试过用 #!python2.7.5 和http://re
我在 python 命令行(使用 python 2.7)中,并尝试运行 Python 脚本。我的操作系统是 Windows 7。我已将我的目录设置为包含我所有脚本的文件夹,使用: os.chdir("
剧透:部分解决(见最后)。 以下是使用 Python 嵌入的代码示例: #include int main(int argc, char** argv) { Py_SetPythonHome
假设我有以下列表,对应于及时的股票价格: prices = [1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11] 我想确定以下总体上最
所以我试图在选择某个单选按钮时更改此框架的背景。 我的框架位于一个类中,并且单选按钮的功能位于该类之外。 (这样我就可以在所有其他框架上调用它们。) 问题是每当我选择单选按钮时都会出现以下错误: co
我正在尝试将字符串与 python 中的正则表达式进行比较,如下所示, #!/usr/bin/env python3 import re str1 = "Expecting property name
考虑以下原型(prototype) Boost.Python 模块,该模块从单独的 C++ 头文件中引入类“D”。 /* file: a/b.cpp */ BOOST_PYTHON_MODULE(c)
如何编写一个程序来“识别函数调用的行号?” python 检查模块提供了定位行号的选项,但是, def di(): return inspect.currentframe().f_back.f_l
我已经使用 macports 安装了 Python 2.7,并且由于我的 $PATH 变量,这就是我输入 $ python 时得到的变量。然而,virtualenv 默认使用 Python 2.6,除
我只想问如何加快 python 上的 re.search 速度。 我有一个很长的字符串行,长度为 176861(即带有一些符号的字母数字字符),我使用此函数测试了该行以进行研究: def getExe
list1= [u'%app%%General%%Council%', u'%people%', u'%people%%Regional%%Council%%Mandate%', u'%ppp%%Ge
这个问题在这里已经有了答案: Is it Pythonic to use list comprehensions for just side effects? (7 个答案) 关闭 4 个月前。 告
我想用 Python 将两个列表组合成一个列表,方法如下: a = [1,1,1,2,2,2,3,3,3,3] b= ["Sun", "is", "bright", "June","and" ,"Ju
我正在运行带有最新 Boost 发行版 (1.55.0) 的 Mac OS X 10.8.4 (Darwin 12.4.0)。我正在按照说明 here构建包含在我的发行版中的教程 Boost-Pyth
学习 Python,我正在尝试制作一个没有任何第 3 方库的网络抓取工具,这样过程对我来说并没有简化,而且我知道我在做什么。我浏览了一些在线资源,但所有这些都让我对某些事情感到困惑。 html 看起来
我是一名优秀的程序员,十分优秀!