熊猫找到当地最大和最小

Mus*_*ger 14 python numpy dataframe pandas

我有一个带有两列的pandas数据框,一个是温度,另一个是时间.

我想制作名为min和max的第三和第四列.这些列中的每一列都将用nan填充,除非存在局部最小值或最大值,然后它将具有该极值的值.

这是一个数据样本的样本,基本上我试图识别图中的所有峰值和低点.

在此输入图像描述

是否有任何带有熊猫的内置工具可以实现这一目标?

Foa*_*oad 31

fuglede提供的解决方案非常棒,但如果您的数据非常嘈杂(如图中的那个),您最终会产生许多误导性的本地外景.我建议你使用scipy.signal.argrelextrema功能.argrelextrema有其自身的局限性,但它有一个很酷的功能,你可以指定要比较的点数,类似于噪音过滤算法.例如:

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

# Generate a noisy AR(1) sample
np.random.seed(0)
rs = np.random.randn(200)
xs = [0]
for r in rs:
    xs.append(xs[-1]*0.9 + r)
df = pd.DataFrame(xs, columns=['data'])

n=5 # number of points to be checked before and after 
# Find local peaks
df['min'] = df.iloc[argrelextrema(df.data.values, np.less_equal, order=n)[0]]['data']
df['max'] = df.iloc[argrelextrema(df.data.values, np.greater_equal, order=n)[0]]['data']

# Plot results
plt.scatter(df.index, df['min'], c='r')
plt.scatter(df.index, df['max'], c='g')
plt.plot(df.index, df['data'])
plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

一些要点:

  • 你可能需要检查以后的点数,以确保没有彼此非常接近的点.
  • 你可以n用来过滤嘈杂的点
  • argrelextrema返回一个元组,[0]最后提取一个numpy数组

  • 这是很好的解决方案。我写了一个关于它的小博客文章:http://eddwardo.github.io/pandas/timeseries/2019/06/05/finding-local-extreams-in-pandas-time-series/ (4认同)
  • @Foad https://eddwardo.github.io/posts/2019-06-05-finding-local-extreams-in-pandas-time-series/ (4认同)
  • 优秀的博客文章@eddd,这确实帮助我理解了它! (2认同)
  • @eddd 页面已关闭 (2认同)
  • 最好也是最快的解决方案。不知道“argrelextrema” (2认同)

fug*_*ede 18

假设感兴趣的列被标记data,一个解决方案就是

df['min'] = df.data[(df.data.shift(1) > df.data) & (df.data.shift(-1) > df.data)]
df['max'] = df.data[(df.data.shift(1) < df.data) & (df.data.shift(-1) < df.data)]
Run Code Online (Sandbox Code Playgroud)

例如:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

# Generate a noisy AR(1) sample
np.random.seed(0)
rs = np.random.randn(200)
xs = [0]
for r in rs:
    xs.append(xs[-1]*0.9 + r)
df = pd.DataFrame(xs, columns=['data'])

# Find local peaks
df['min'] = df.data[(df.data.shift(1) > df.data) & (df.data.shift(-1) > df.data)]
df['max'] = df.data[(df.data.shift(1) < df.data) & (df.data.shift(-1) < df.data)]

# Plot results
plt.scatter(df.index, df['min'], c='r')
plt.scatter(df.index, df['max'], c='g')
df.data.plot()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


小智 5

您可以执行类似于Foad 的 .argrelextrema() 解决方案的操作,但使用 Pandas .rolling() 函数:

# Find local peaks
n = 5 #rolling period
local_min_vals = df.loc[df['data'] == df['data'].rolling(n, center=True).min()]
local_max_vals = df.loc[df['data'] == df['data'].rolling(n, center=True).max()]

plt.scatter(local_min_vals.index, local_min_vals, c='r')
plt.scatter(local_max_vals.index, local_max_vals, c='g')
Run Code Online (Sandbox Code Playgroud)

噪声信号的图像,其中红点显示局部最小值,绿点显示局部最大值。