Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pandas finding local max and min

I have a pandas data frame with two columns one is temperature the other is time.

I would like to make third and fourth columns called min and max. Each of these columns would be filled with nan's except where there is a local min or max, then it would have the value of that extrema.

Here is a sample of what the data looks like, essentially I am trying to identify all the peaks and low points in the figure.

enter image description here

Are there any built in tools with pandas that can accomplish this?

like image 368
Mustard Tiger Avatar asked Dec 29 '17 14:12

Mustard Tiger


People also ask

How do you find min and max in pandas?

Pandas DataFrame min() Method The min() method returns a Series with the minimum value of each column. By specifying the column axis ( axis='columns' ), the max() method searches column-wise and returns the minimum value for each row.

What does .values in pandas do?

The values property is used to get a Numpy representation of the DataFrame. Only the values in the DataFrame will be returned, the axes labels will be removed. The values of the DataFrame. A DataFrame where all columns are the same type (e.g., int64) results in an array of the same type.

Is at and LOC same in pandas?

When you'd like to access just one value in a pandas DataFrame, both the loc and at functions will work fine. However, when you'd like to access a group of rows and columns, only the loc function is able to do so.


1 Answers

The solution offered by fuglede is great but if your data is very noisy (like the one in the picture) you will end up with lots of misleading local extremes. I suggest that you use scipy.signal.argrelextrema() method. The .argrelextrema() method has its own limitations but it has a useful feature where you can specify the number of points to be compared, kind of like a noise filtering algorithm. for example:

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() 
 

Some points:

  • you might need to check the points afterward to ensure there are no twine points very close to each other.
  • you can play with n to filter the noisy points
  • argrelextrema returns a tuple and the [0] at the end extracts a numpy array
like image 175
Foad S. Farimani Avatar answered Sep 21 '22 07:09

Foad S. Farimani