Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 寻找局部最大值和最小值_Python_Pandas_Dataframe_Numpy_Time Series - Fatal编程技术网

Python 寻找局部最大值和最小值

Python 寻找局部最大值和最小值,python,pandas,dataframe,numpy,time-series,Python,Pandas,Dataframe,Numpy,Time Series,我有一个熊猫数据框,有两列,一列是温度,另一列是时间 我想把第三列和第四列分别命名为min和max。这些列中的每一列都用nan填充,除非有一个局部min或max,那么它将具有该极值的值 这是一个数据的样本,本质上我试图识别图中的所有峰值和低点 是否有任何带有pandas的内置工具可以实现这一点?假设感兴趣的列被标记为data,一种解决方案是 df['min'] = df.data[(df.data.shift(1) > df.data) & (df.data.shift(-1)

我有一个熊猫数据框,有两列,一列是温度,另一列是时间

我想把第三列和第四列分别命名为min和max。这些列中的每一列都用nan填充,除非有一个局部min或max,那么它将具有该极值的值

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


是否有任何带有pandas的内置工具可以实现这一点?

假设感兴趣的列被标记为
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)]
df['min']=df.data[(df.data.shift(1)>df.data)和(df.data.shift(-1)>df.data)]
df['max']=df.data[(df.data.shift(1)
例如:

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()
将numpy导入为np
将matplotlib.pyplot作为plt导入
作为pd进口熊猫
#生成一个有噪声的AR(1)样本
np.random.seed(0)
rs=np.random.randn(200)
xs=[0]
对于rs中的r:
追加(xs[-1]*0.9+r)
df=pd.DataFrame(xs,columns=['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)
很好,但如果你的数据非常嘈杂(如图中所示),你最终会遇到许多误导性的局部极端情况。我建议您使用
scipy.signal.argrelextrema()
方法。
.argrelextrema()
方法有其自身的局限性,但它有一个有用的功能,可以指定要比较的点数,有点像噪声过滤算法。例如:

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()
将numpy导入为np
将matplotlib.pyplot作为plt导入
作为pd进口熊猫
从scipy.signal导入argrelextrema
#生成一个有噪声的AR(1)样本
np.random.seed(0)
rs=np.random.randn(200)
xs=[0]
对于rs中的r:
追加(xs[-1]*0.9+r)
df=pd.DataFrame(xs,columns=['data']))
n=5#前后要检查的点数
#寻找局部峰值
df['min']=df.iloc[argrelextrema(df.data.values,np.less_equal,
订单=n)[0]['data']
df['max']=df.iloc[argrelextrema(df.data.values,np.morer_equal,
订单=n)[0]['data']
#绘图结果
plt.散射(测向指数,测向['min',c='r')
plt.散射(测向指数,测向['max'],c='g')
plt.绘图(df.index,df['data']))
plt.show()
有几点:

  • 之后可能需要检查这些点,以确保没有非常接近的绳线点
  • 您可以使用
    n
    来过滤噪声点
  • argrelextrema
    返回一个元组,最后的
    [0]
    提取一个
    numpy
    数组

    • 使用Numpy

      ser = np.random.randint(-40, 40, 100) # 100 points
      peak = np.where(np.diff(ser) < 0)[0]
      

      使用熊猫

      ser = pd.Series(np.random.randint(2, 5, 100))
      peak_df = ser[(ser.shift(1) < ser) & (ser.shift(-1) < ser)]
      peak = peak_df.index
      
      ser=pd.Series(np.random.randint(2,5100))
      峰值df=ser[(ser.shift(1)
      结果是否应具有抗噪性?否则,您可以将序列的值与其位移进行比较。我不担心噪声。在这种情况下,如果它是一个噪声信号,我只需对其进行滤波,然后在滤波结果上查找最大值/最小值。您也可以将一个非常简单的(例如,具有一个或两个协变量的线性)模型拟合到数据中,然后从残差项中保留偏差在
      q
      %最小或最大类别的项,使用。这是一个很好的解决方案。我写了一篇关于它的小博文:优秀的博文@eddd,这真的帮助我理解它@eddd页面向下@Foad我发现,当重复数据值时,例如,使用值为7的多行,仅使用<或>将丢失作为“最小值”或“最大值”的数据点。将此解决方案修改为“.shift(1)=”实际上允许识别重复值的“min”和“max”值。逻辑是,包含重复值的最后一行将被视为“min”或“max”
      ser = pd.Series(np.random.randint(2, 5, 100))
      peak_df = ser[(ser.shift(1) < ser) & (ser.shift(-1) < ser)]
      peak = peak_df.index