高级峰值“块”分析

问题描述 投票:0回答:1

我有非常基本的编程知识,并且我一直在使用我在这里找到的一些技巧,在此先感谢您。

继续讨论这个问题,我正在分析来自光学传感器的数据,这些传感器正在测量车辆对路面造成的延伸。 我发现处理原始文件的最简单方法是使用一种 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])`
python moving-average standard-deviation peaks.js
1个回答
0
投票

这将有助于查看表结构。这将有助于决定如何选择相对于峰值索引的行。如果您正在寻找突出的峰值,我会使用现有的峰值查找算法,例如 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

© www.soinside.com 2019 - 2024. All rights reserved.