scipy.signal 的 medfilt 和 pandas 的 rolling().median 有什么区别?
What is the difference between medfilt from scipy.signal and rolling().median from pandas?
我想使用中值滤波器来平滑信号,我看到 Python 中有两种方法可以使用:
medfilt
来自 scipy.signal
DataFrame.rolling().median()
来自 pandas
通过为这两种方法选择相同的 window 大小,我得到了不同的结果。我附上了一个示例数据集。此外,在第二种方法中,数据点的数量在应用过滤器时发生变化(根据 window 大小),我希望这种情况会发生,但是在第二种方法中,平滑数据的数量与原始数据。
这两种方法有什么区别,为什么会得到不同的结果?
import pandas as pd
import scipy.signal as ss
signal = [4, 3.8, 3.75, 3.9, 3.53, 3.26, 2.33, 2.8, 2.5, 2.4, 2, 2.2, 1.5, 1.7]
# First method
SmoothedSignal = ss.medfilt(signal, kernel_size=5)
print(SmoothedSignal)
print(len(SmoothedSignal))
# Second method
signal = pd.DataFrame(signal)
RollingMedian = signal.rolling(5).median()
print(RollingMedian)
print(len(RollingMedian))
中值不同的原因是核的对齐。 pandas.DataFrame.rolling
right aligns the kernel by default, while scipy.signal.medfit
默认居中对齐内核。
您可以通过将 center
关键字参数设置为 True
来居中对齐 DataFrame.rolling
。
import pandas as pd
import scipy.signal as ss
signal = [4, 3.8, 3.75, 3.9, 3.53, 3.26, 2.33, 2.8, 2.5, 2.4, 2, 2.2, 1.5, 1.7]
# scipy
size = len(signal)
smoothed = ss.medfilt(signal, kernel_size=5)
# rolling - right aligned
signal = pd.DataFrame(signal)
rolling_right = signal.rolling(5).median()
# rolling - center aligned
signal = pd.DataFrame(signal)
rolling_center = signal.rolling(5 ,center = True).median()
df = pd.DataFrame()
df[ 'smooth' ] = smoothed
df[ 'rolling_center' ] = rolling_center
df[ 'rolling_right' ] = rolling_right
df
# output
smooth rolling_center rolling_right
0 3.75 NaN NaN
1 3.80 NaN NaN
2 3.80 3.80 NaN
3 3.75 3.75 NaN
4 3.53 3.53 3.80
5 3.26 3.26 3.75
6 2.80 2.80 3.53
7 2.50 2.50 3.26
8 2.40 2.40 2.80
9 2.40 2.40 2.50
10 2.20 2.20 2.40
11 2.00 2.00 2.40
12 1.70 NaN 2.20
13 1.50 NaN 2.00
您还会注意到 nan
填充与使用 rolling
的差异。
我想使用中值滤波器来平滑信号,我看到 Python 中有两种方法可以使用:
medfilt
来自scipy.signal
DataFrame.rolling().median()
来自pandas
通过为这两种方法选择相同的 window 大小,我得到了不同的结果。我附上了一个示例数据集。此外,在第二种方法中,数据点的数量在应用过滤器时发生变化(根据 window 大小),我希望这种情况会发生,但是在第二种方法中,平滑数据的数量与原始数据。
这两种方法有什么区别,为什么会得到不同的结果?
import pandas as pd
import scipy.signal as ss
signal = [4, 3.8, 3.75, 3.9, 3.53, 3.26, 2.33, 2.8, 2.5, 2.4, 2, 2.2, 1.5, 1.7]
# First method
SmoothedSignal = ss.medfilt(signal, kernel_size=5)
print(SmoothedSignal)
print(len(SmoothedSignal))
# Second method
signal = pd.DataFrame(signal)
RollingMedian = signal.rolling(5).median()
print(RollingMedian)
print(len(RollingMedian))
中值不同的原因是核的对齐。 pandas.DataFrame.rolling
right aligns the kernel by default, while scipy.signal.medfit
默认居中对齐内核。
您可以通过将 center
关键字参数设置为 True
来居中对齐 DataFrame.rolling
。
import pandas as pd
import scipy.signal as ss
signal = [4, 3.8, 3.75, 3.9, 3.53, 3.26, 2.33, 2.8, 2.5, 2.4, 2, 2.2, 1.5, 1.7]
# scipy
size = len(signal)
smoothed = ss.medfilt(signal, kernel_size=5)
# rolling - right aligned
signal = pd.DataFrame(signal)
rolling_right = signal.rolling(5).median()
# rolling - center aligned
signal = pd.DataFrame(signal)
rolling_center = signal.rolling(5 ,center = True).median()
df = pd.DataFrame()
df[ 'smooth' ] = smoothed
df[ 'rolling_center' ] = rolling_center
df[ 'rolling_right' ] = rolling_right
df
# output
smooth rolling_center rolling_right
0 3.75 NaN NaN
1 3.80 NaN NaN
2 3.80 3.80 NaN
3 3.75 3.75 NaN
4 3.53 3.53 3.80
5 3.26 3.26 3.75
6 2.80 2.80 3.53
7 2.50 2.50 3.26
8 2.40 2.40 2.80
9 2.40 2.40 2.50
10 2.20 2.20 2.40
11 2.00 2.00 2.40
12 1.70 NaN 2.20
13 1.50 NaN 2.00
您还会注意到 nan
填充与使用 rolling
的差异。