【问题标题】:Smoothing data for determining peak values in Python平滑数据以确定 Python 中的峰值
【发布时间】:2020-01-03 17:37:31
【问题描述】:

我有一个带峰和谷的样带,并想确定两者的峰值。数据集有相当多的噪音,所以目前,峰值不会作为单个值返回。 我尝试使用滚动平均值来平滑数据,即使结果比不平滑时要好,但仍然存在多个“峰值”。 [CSV file here]

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from scipy.signal import argrelextrema
from pandas import read_csv
from numpy import mean
from matplotlib import pyplot
import csv

df = pd.read_csv('transect2.csv', delimiter=',', header=None, names=['x', 'y'])

plt.plot(df['x'], df['y'], label='Original Height')

rolling = df.rolling(window=100)
rolling_mean = rolling.mean()

plt.xlabel('Distance')
plt.ylabel('Height')

plt.plot(rolling_mean['x'], rolling_mean['y'], label='Mean Height 100')
plt.legend(loc='upper left')
plt.show()

n=1000

ilocs_min = argrelextrema(rolling_mean.y.values, np.less_equal, order=n)[0]
ilocs_max = argrelextrema(rolling_mean.y.values, np.greater_equal, order=n)[0]

df.y.plot (color='gray')
df.iloc[ilocs_max].y.plot(style='.', lw=10, color='red', marker="v");
df.iloc[ilocs_min].y.plot(style='.', lw=10, color='green', marker="^");

进一步平滑数据并不能代表现实,因此我可以改进这种平滑或使用不同的平滑函数。

【问题讨论】:

  • 在我的特定问题中,将信号与高斯窗口进行卷积效果很好(参见例如this answer)。

标签: python pandas csv smoothing


【解决方案1】:

我的第一直觉是使用Savitzky-Golay filter 进行平滑处理。第二个是当你有一个嘈杂的数据集时忘记 argrelextrema。以这种方式使用它,我从来没有任何好的结果。更好的选择是find_peaksfind_peaks_cwt

我解决了:


import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from scipy.signal import argrelextrema
from scipy.signal import savgol_filter, find_peaks, find_peaks_cwt
from pandas import read_csv
import csv

df = pd.read_csv('transect2.csv', delimiter=',', header=None, names=['x', 'y'])

plt.plot(df['x'], df['y'], label='Original Height')

#apply a Savitzky-Golay filter
smooth = savgol_filter(df.y.values, window_length = 351, polyorder = 5)

#find the maximums
peaks_idx_max, _ = find_peaks(smooth, prominence = 0.01)

#reciprocal, so mins will become max
smooth_rec = 1/smooth

#find the mins now
peaks_idx_mins, _ = find_peaks(smooth_rec, prominence = 0.01)

plt.xlabel('Distance')
plt.ylabel('Height')


plt.plot(df['x'], smooth, label='smoothed')

#plot them
plt.scatter(df.x.values[peaks_idx_max], smooth[peaks_idx_max], s = 55,
            c = 'green', label = 'max')
plt.scatter(df.x.values[peaks_idx_mins], smooth[peaks_idx_mins], s = 55,
            c = 'black', label = 'min')
plt.legend(loc='upper left')
plt.show()

输出到this

【讨论】:

  • 是否可以让脚本读取具有多个样带的 .csv 文件,计算不同的峰值并选择具有最高海拔变化的样带? (有问题的.csv 更新)
  • 当然,您必须收集数据并将它们与 np.argmax 进行比较。
猜你喜欢
  • 2015-08-09
  • 1970-01-01
  • 1970-01-01
  • 2019-10-13
  • 1970-01-01
  • 2015-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多