You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何scipy.signal.sosfilt使用阶数>2的butter生成sos时报错?

问题:scipy.signal.sosfilt4阶滤波时触发TypeError错误

用scipy.signal处理pysoundfile导入的WAV文件,filtfilt实现2阶、4阶高通滤波都正常,sosfilt实现2阶高通也没问题,但指定阶数为4时sosfilt报错:

TypeError: only integer scalar arrays can be converted to a scalar index

复现代码

import soundfile
import numpy
import scipy

def butter_highpass_sosfilt(data, lowcut, fs, order=2):
    return scipy.signal.sosfilt(*scipy.signal.butter(order, [lowcut], fs=fs, btype='high', output='sos'), data)

def butter_highpass_filtfilt(data, lowcut, fs, order=1):
    return scipy.signal.filtfilt(*scipy.signal.butter(order, [lowcut], fs=fs, btype='high', output='ba'), data)

audio, samplerate = soundfile.read("Test Audio.wav") # 24bit 44100 PCM格式音频

output1 = numpy.zeros((numpy.size(audio[:,0]),2))
output1[:,0] = butter_highpass_filtfilt(audio[:,0], 160, samplerate, order=2)
output1[:,1] = butter_highpass_filtfilt(audio[:,1], 160, samplerate, order=2)
soundfile.write("test output 1.wav", output1, samplerate, 'PCM_24')

output2 = numpy.zeros((numpy.size(audio[:,0]),2))
output2[:,0] = butter_highpass_filtfilt(audio[:,0], 160, samplerate, order=4)
output2[:,1] = butter_highpass_filtfilt(audio[:,1], 160, samplerate, order=4)
soundfile.write("test output 2.wav", output2, samplerate, 'PCM_24')

output3 = numpy.zeros((numpy.size(audio[:,0]),2))
output3[:,0] = butter_highpass_sosfilt(audio[:,0], 160, samplerate, order=2)
output3[:,1] = butter_highpass_sosfilt(audio[:,1], 160, samplerate, order=2)
soundfile.write("test output 3.wav", output3, samplerate, 'PCM_24')

output4 = numpy.zeros((numpy.size(audio[:,0]),2))
output4[:,0] = butter_highpass_sosfilt(audio[:,0], 160, samplerate, order=4)
output4[:,1] = butter_highpass_sosfilt(audio[:,1], 160, samplerate, order=4)
soundfile.write("test output 4.wav", output4, samplerate, 'PCM_24')

报错栈

Traceback (most recent call last):
  File "M:\Documents\Python\DSP try\Sosfilt error mre\Sosfilt error mre.py", line 29, in <module>
    output4[:,0] = butter_highpass_sosfilt(audio[:,0], 160, int(samplerate/3), order=4)
  File "M:\Documents\Python\DSP try\Sosfilt error mre\Sosfilt error mre.py", line 6, in butter_highpass_sosfilt
    return scipy.signal.sosfilt(*scipy.signal.butter(order, [lowcut], fs=fs, btype='high', output='sos'), data)
  File "C:\Users\edwar\AppData\Local\Programs\Python\Python311\Lib\site-packages\scipy\signal\_signaltools.py", line 4277, in sosfilt
    x_zi_shape[axis] = 2
TypeError: only integer scalar arrays can be converted to a scalar index

解决方案

问题出在参数传递逻辑错误:当butter函数指定output='sos'时,返回的是单个2D数组(sos矩阵),但你用*解包后,会把数组的每一行作为独立参数传给sosfilt,这完全不符合函数的参数要求。

修改butter_highpass_sosfilt函数,直接传入sos数组即可:

def butter_highpass_sosfilt(data, lowcut, fs, order=2):
    sos = scipy.signal.butter(order, [lowcut], fs=fs, btype='high', output='sos')
    return scipy.signal.sosfilt(sos, data)

补充说明

order=2时没报错是巧合:此时butter返回的sos数组是(1,6)形状,解包后会把这一行的6个元素作为参数传入,虽然不符合要求,但没触发明显异常;而order=4时,sos数组是(2,6)形状,解包后会把两行作为两个参数传入,导致函数内部处理索引时出错。

内容的提问来源于stack exchange,提问作者Edward

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 08:37:35