我有非常基本的编程知识,并且我一直在使用我在这里找到的一些技巧,在此先感谢您。
继续讨论这个问题,我正在分析来自光学传感器的数据,这些传感器正在测量车辆对路面造成的延伸。 我发现处理原始文件的最简单方法是使用一种 zscore 算法过滤噪声,因为每 10 分钟就会以 xlsx 格式生成 300.000 行。该算法将检测最突出的峰值,但不是我需要的所有峰值。 我的想法是获取检测到的这些峰的索引,并将它们中的每一个视为“块/通道”,然后单独分析每个块。 从最初找到的峰值开始,我想定义我需要收集之前的两秒和之后的三秒,因为这样相对于每个车辆/通道的整个时间空间就已经被覆盖了。 算法收集完这 5 秒后,我需要车辆的峰值/轴数、每个峰值的最大值以及相对于静止点的延伸增量(存在于第一个峰值之前的 2 秒) 。 我正在尝试挖掘 chatgpt 但我总是陷入死胡同:/
下面我将目前使用的算法留下来进行初步分析。 非常感谢你
所以我尝试了很多方法,包括使用 Savitzky 滤波器来平滑数据,然后根据导数找到峰值,但给我最好结果的策略是计算移动平均值和标准差,然后根据即,调整峰值的阈值、滞后和影响。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
df = pd.read_excel('2023_09_28_16_59_06.xlsx')
lag = 500
influence = 0.5
threshold = 10
def find_peak_indices(signal, lag, influence, threshold):
peak_indices = []
peaks = []
processed_signal = []
processed_signal.append(signal[:lag])
avg_list = []
sd_list = []
for index in range(lag, len(signal)):
y = signal[index]
avg_list.append(np.mean(processed_signal[-lag:]))
sd_list.append(np.std(processed_signal[-lag:]))
if abs(y - avg_list[-1]) > sd_list[-1] * threshold:
peak_indices.append(index)
peaks.append(signal[index])
if index > 0:
adjusted_value = (influence * y) + ((1 - influence) * processed_signal[-1])
else:
adjusted_value = (influence * y) # No previous value, take y as is
processed_signal = np.append(processed_signal, [adjusted_value])
processed_signal = processed_signal[1:]
return peak_indices, peaks
signal = df[df.columns[16]]
peak_indices, peak_values = find_peak_indices(signal, lag, influence, threshold)
moving_avg = df[df.columns[16]].rolling(window=lag).mean()
std_dev = df[df.columns[16]].rolling(window=lag).std()
plt.figure(figsize=(12, 12))
plt.plot(signal, label='Signal')
plt.plot(moving_avg, color='red', label='Moving Average')
plt.title('Signal with Moving Average')
plt.xlabel('Index')
plt.ylabel('Value')
plt.legend()
plt.show()
plt.plot(std_dev, color='green', label='Standard Deviation')
plt.title('Standard Deviation')
plt.xlabel('Index')
plt.ylabel('Value')
plt.legend()
plt.show()
plt.plot(signal, label='Signal')
plt.scatter(peak_indices, peak_values, color='red', label='Peaks')
plt.title('Signal with Peaks Detected')
plt.xlabel('Index')
plt.ylabel('Value')
plt.legend()
plt.show()
print("Picos encontrados:")
`for i in range(len(peak_indices)):`
`print("Índice:", peak_indices[i], "- Valor do pico:", peak_values[i])`
这将有助于查看表结构。这将有助于决定如何选择相对于峰值索引的行。如果您正在寻找突出的峰值,我会使用现有的峰值查找算法,例如 scipy.signal.find_peaks (docs)。将数据多次传递以过滤更突出的峰值:
from scipy.signal import find_peaks
def get_filtered_peaks(data: pd.Series, iterations: int = None):
"""
obtain prominent peaks by continuously filtering peak data
will always filter at least once
data: A signal containing peaks
iteration: optional arg for explicit number of filter passes
if unset, iterations will scale with data size
"""
if iterations is None:
iterations = len(data) // 100000 # change this however you like
i = 1
while True:
data = find_peaks(data, distance=1, width=0)
if i >= iterations:
break
i += 1
return data