【发布时间】:2020-07-02 18:22:14
【问题描述】:
我目前正在尝试学习如何通过 pandas 和 matplotlib 使用 csv 数据。我有这个问题,对于一个明显有数据峰值的数据集,我需要在评估任何东西之前“清理”它。但我很难理解如何“检测”图表中的尖峰......
所以我正在处理的数据集如下:
df = pd.DataFrame({'price':[340.6, 35.66, 33.98, 38.67, 32.99, 32.04, 37.64,
38.22, 37.13, 38.57, 32.4, 34.98, 36.74, 32.9,
32.52, 38.83, 33.9, 32.62, 38.93, 32.14, 33.09,
34.25, 34.39, 33.28, 38.13, 36.25, 38.91, 38.9,
36.85, 32.17, -2.07, 34.49, 35.7, 32.54, 37.91,
37.35, 32.05, 38.03, 0.32, 33.87, 33.16, 34.74,
32.47, 33.31, 34.54, 36.6, 36.09, 35.49, 370.51,
37.33, 37.54, 33.32, 35.09, 33.08, 38.3, 34.32,
37.01, 33.63, 36.35, 33.77, 33.74, 36.62, 36.74,
37.76, 35.58, 38.76, 36.57, 37.05, 35.33, 36.41,
35.54, 37.48, 36.22, 36.19, 36.43, 34.31, 34.85,
38.76, 38.52, 38.02, 36.67, 32.51, 321.6, 37.82,
34.76, 33.55, 32.85, 32.99, 35.06]},
index = pd.date_range('2014-03-03 06:00','2014-03-06 22:00',freq='H'))
生成此图:
所以所有这些值都在 32 到 38 的范围内。我特意在 [0, 30, 38, 48, 82] 的索引上放置了非常大的数字,以在图表中创建峰值。
现在我试图在图表上查找如何执行所谓的“步进检测”,而我发现的唯一真正有用的答案是通过this question here,因此利用它我想出了这个整体代码...
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import argrelextrema
df = pd.DataFrame({'price':[340.6, 35.66, 33.98, 38.67, 32.99, 32.04, 37.64,
38.22, 37.13, 38.57, 32.4, 34.98, 36.74, 32.9,
32.52, 38.83, 33.9, 32.62, 38.93, 32.14, 33.09,
34.25, 34.39, 33.28, 38.13, 36.25, 38.91, 38.9,
36.85, 32.17, -2.07, 34.49, 35.7, 32.54, 37.91,
37.35, 32.05, 38.03, 0.32, 33.87, 33.16, 34.74,
32.47, 33.31, 34.54, 36.6, 36.09, 35.49, 370.51,
37.33, 37.54, 33.32, 35.09, 33.08, 38.3, 34.32,
37.01, 33.63, 36.35, 33.77, 33.74, 36.62, 36.74,
37.76, 35.58, 38.76, 36.57, 37.05, 35.33, 36.41,
35.54, 37.48, 36.22, 36.19, 36.43, 34.31, 34.85,
38.76, 38.52, 38.02, 36.67, 32.51, 321.6, 37.82,
34.76, 33.55, 32.85, 32.99, 35.06]},
index = pd.date_range('2014-03-03 06:00','2014-03-06 22:00',freq='H'))
# df.plot()
# plt.show()
threshold = int(len(df['price']) * 0.75)
maxPeaks = argrelextrema(df['price'].values, np.greater, order=threshold)
minPeaks = argrelextrema(df['price'].values, np.less, order=threshold)
df2 = df.copy()
price_column_index = df2.columns.get_loc('price')
allPeaks = maxPeaks + minPeaks
for peakList in allPeaks:
for peak in peakList:
print(df2.iloc[peak]['price'])
但问题在于它似乎只返回了 30 和 82 的索引,并且它没有抓住索引 0 中的大值,也没有在负值下跌时抓住任何东西。虽然我很确定我错误地使用了这些方法。
现在,我了解对于这个特定问题,我可以只在列中查找大于或小于某个值的值,但我正在考虑处理 1000 多个条目的情况,其中处理“最低/最高正常值”无法准确确定,因此我只想要一个无论规模如何都能正常工作的尖峰检测。
所以我的问题如下:
1) 我一直在查看的有关步数检测的信息似乎非常密集,而且我很难理解。谁能提供有关如何处理这些“步骤检测”问题的一般规则?
2) 是否有任何公共图书馆可以更轻松地完成此类工作?如果有,它们是什么?
3) 如何使用 vanilla Python 实现相同的结果?我曾在许多不允许安装任何其他库的工作场所,强制制定不使用任何这些有用的外部库的解决方案,所以我想知道是否有某种公式/函数可以被写来达到类似的结果......
4) 从数据分析的角度来看,我可以使用哪些其他方法来处理此问题?我读过一些关于相关性、标准差的文章,但我实际上并不知道如何利用这些来识别尖峰在哪里......
编辑:另外,我发现this answer 以及使用 scipy 的 find_peaks 方法,但阅读它的文档我并不真正理解它们代表什么,以及传递的值来自哪里......对此的任何澄清都会不胜感激...
【问题讨论】:
-
这很有趣,我刚刚使用
find_peaks运行了您的数据,但在df['price'][0]处没有找到峰值
标签: python pandas numpy matplotlib scipy