Python - ValueError: The length of the input vector x must be greater than padlen, which is 6

Viewed 9830

I am using the function filtfilt in Python as follows

import numpy as np
from scipy.signal import filtfilt

a = np.array([1, -lambd]).T
b = np.array([-lambd,1]).T
delayed = filtfilt(b,a,sig)

where sig has shape (6,). As a result, I get the following error:

ValueError: The length of the input vector x must be greater than padlen, which is 6.

generated by scipy.signal.

The same code works fine if sig has shape (7,) or longer, while it returns the same error for any shape smaller than (6,). Any idea?

3 Answers

If the error is saying:

ValueError: The length of the input vector x must be greater than padlen, which is 6 [or whatever].

Why not filtering the length of the signal sub-elements > 6?

df = df[[len(x) > 6 for x in df['listSignal']]]

For me, it was already enough to filter for a len(x) > 1 to avoid the error. I had quite a few 0-length and 1-length signal lists in the nested 'test' column. I assume that > 1 is needed since only a length of 2 provides one item on the left and one on the right.

The functions that I borrowed from https://github.com/leilamr/LowPassFilter stay untouched:

import pandas as pd
from scipy.signal import butter, freqz, filtfilt

def butter_lowpass(cutoff, fs, order=5):
    nyq = 0.5 * fs
    normal_cutoff = cutoff / nyq
    b, a = butter(order, normal_cutoff, btype='low', analog=False, fs=None)
    return b, a

def butter_lowpass_filter(x, cutoff, fs, order=5):
    b, a = butter_lowpass(cutoff, fs, order=order)
    return filtfilt(b, a, x)

No error with the filtered df len(x) > 1 (try yourself, yours might be higher):

df = df[[len(x) > 1 for x in df['test']]]
df['testFilt'] = [butter_lowpass_filter(x, cutoff, fs, order) for x in df['test']]

Thanks go to @DavideNardone with his idea of filtering the return value of the function, wheras I am now filtering the main df in advance, the idea is the same.

An explanation as to why this happens:

Applying a filter on a signal is actually convolving the signal with the filter.
The convolution operation is only defined when both the signal and the filter can fully overlap.
Since your filter is of size 6, the signal has to be of at least size 6 for the convolution to be deined.

Dealing with it

One easy way to deal with this is to ignore short signals.
Another is to pad the signal with zeros or otherwise such as here.


@questionto42's answer shows another nice way of dealing with the problem.

Use padlen less than length of sig array.

Like following code:

import numpy as np
from scipy.signal import filtfilt

a = np.array([1, -lambd]).T
b = np.array([-lambd,1]).T
delayed = filtfilt(b,a,sig, padlen=len(sig)-1)
Related