python - 检测数字列表中的峰值并记录它们的位置
问题描述
我正在尝试创建一些代码来返回数值数组的“峰值”(或局部最大值)的位置和值。
例如,列表在值为(since equals )arr = [0, 1, 2, 5, 1, 0]
的位置有一个峰值。3
5
arr[3]
5
数组的第一个和最后一个元素不会被视为峰值(在数学函数的上下文中,您不知道之后和之前是什么,因此您不知道它是否是峰值)。
def pick_peaks(arr):
print(arr)
posPeaks = {
"pos": [],
"peaks": [],
}
startFound = False
n = 0
while startFound == False:
if arr[n] == arr[n+1]:
n += 1
else:
startFound = True
endFound = False
m = len(arr) - 1
while endFound == False:
if arr[m] == arr[m-1]:
m -= 1
else:
endFound = True
for i in range(n+1, m):
if arr[i] == arr[i-1]:
None
elif arr[i] >= arr[i-1] and arr[i] >= arr[i+1]:
posPeaks["pos"].append(i)
posPeaks["peaks"].append(arr[i])
return posPeaks
我的问题是高原。[1, 2, 2, 2, 1]
有高峰而[1, 2, 2, 2, 3]
没有。当高原是峰时,记录高原的第一个位置。
任何帮助表示赞赏。
解决方案
我建议您使用groupby对连续的相等值进行分组,然后为每个组存储第一个位置,例如[1, 2, 2, 2, 1]
它在 tuples 列表之后创建以下列表[(1, 0), (2, 1), (1, 4)]
,将所有内容放在一起:
from itertools import groupby
def peaks(data):
start = 0
sequence = []
for key, group in groupby(data):
sequence.append((key, start))
start += sum(1 for _ in group)
for (b, bi), (m, mi), (a, ai) in zip(sequence, sequence[1:], sequence[2:]):
if b < m and a < m:
yield m, mi
print(list(peaks([0, 1, 2, 5, 1, 0])))
print(list(peaks([1, 2, 2, 2, 1])))
print(list(peaks([1, 2, 2, 2, 3])))
输出
[(5, 3)]
[(2, 1)]
[]
推荐阅读
- vue.js - 如何在没有 API 请求的情况下使用 Nuxt.js 生成 100% 静态网站?
- python - 在 Visual Studio Code 中使用 Python 时出现问题
- android - Weex 在 Fragment 中渲染失败
- javascript - 无法通过密钥(Firestore)获取数据
- python - 1行布尔函数python
- python - 使用 Docker 在 Flask 中部署 SpaCY 应用程序
- regex - 设置 $/="\R" 是否允许 chomp() 正确处理 perl 中的大多数文件?
- python-3.x - 如何用python3做数学难题?
- odoo - 如何在odoo 9中创建选择字段
- appium - Appium-XCUITest-Driver 和 appium-dotnet-driver 有什么区别?