如何在Python中去除信号的常数部分?
我有一个数据集,其中有些部分是恒定的,偶尔会有一些小的波动。这些恒定的部分可以出现在顶部,也可以在中间。我想把所有恒定的部分去掉,这样数据就能压缩成更小的长度。
比如说,如果有200个连续的数值是相同的(或者在一个可以接受的范围内被认为是恒定的),那么就把这一部分视为恒定。
任何解决方案的代码或逻辑建议都非常欢迎。谢谢你的时间。
我附上了一个样本数据的谷歌云盘链接,格式是.npy。
在下面的示例图片中,我用红色标出了我想要去掉的部分,作为一个例子:
2 个回答
1
这不是最优雅的解决方案,但它的做法是把一个长度为200的窗口在信号上滑动,观察信号的变化程度。如果变化程度超过某个特定的值,就认为这个信号不是恒定的。可能还有其他方法可以改进这个方案,但我用很少的努力就能去掉很多恒定的部分。
import numpy as np
import matplotlib.pyplot as plt
x = np.load(r"C:\Users\ryansenne\Downloads\sample.npy")
# Detects constant sections and removes them
def remove_constant_sections(signal, window_size=200, threshold=0.01):
filtered_signal = []
i = 0
while i < len(signal) - window_size:
window = signal[i:i+window_size]
if np.var(window) > threshold:
filtered_signal.extend(window)
i += window_size
else:
i += 1
# Add the remaining values that may not fit into a full window
filtered_signal.extend(signal[i:])
return np.array(filtered_signal)
filtered_signal = remove_constant_sections(x)
0
我想出了以下的解决方案。@rsenne 的回答帮我入门,但那并不是我想要的解决方案。如果你觉得我的方案还有什么可以改进的地方,请告诉我,这样可以提高性能。
import numpy as np
def remove_flat_segments(data, threshold, min_length):
"""
Remove flat segments from data within a threshold and with a minimum length.
Parameters:
data (ndarray): Input data array.
threshold (float): Threshold for flatness.
min_length (int): Minimum length of flat segment to be removed.
Returns:
ndarray: Data with flat segments removed.
"""
flat_segments = []
start_idx = None
for i in range(len(data)):
if start_idx is None:
start_idx = i
elif abs(data[i] - data[i-1]) > threshold:
if i - start_idx >= min_length:
flat_segments.append((start_idx, i-1))
start_idx = None
if start_idx is not None and len(data) - start_idx >= min_length:
flat_segments.append((start_idx, len(data)-1))
if len(flat_segments) > 0:
flat_indices = np.concatenate([np.arange(start, end+1) for start, end in flat_segments])
return np.delete(data, flat_indices)
else:
return data
threshold = 0.01
min_length = 1000
filtered_data = remove_flat_segments(data, threshold, min_length)
生成的图像看起来是这样的:
