Python Pandas:如何在多个循环中获取每个峰的最大值
Python Pandas: How to get the maximum value per peak in multiple cycles
我正在从一台有数千个周期的机器上导入数据。每个周期持续几分钟,并且有两个我需要记录的压力峰值。一个例子可以在下图中看到。
在此循环中,您可以看到有两个峰值,一个在 807 psi,一个在 936 psi。我需要记录这些值。我已经对数据进行了排序,因此我可以确定一个周期何时开启或关闭,但现在我需要弄清楚如何记录这两个最大值。我以前试过这个:
df2 = df.groupby('group')['Pressure'].nlargest(2).rename_axis (index=['group', 'row_index'])
获得最大值,但意识到这只会给我两个最大值,这两个最大值在某些周期中正好发生在峰值之前。
在此示例数据框中,我提供了一个周期:
import pandas as pd
data = {'Pressure' : [100,112,114,120,123,420,123,1230,1320,1,23,13,13,13,123,13,123,3,222,2303,1233,1233,1,1,30,20,40,401,10,40,12,122,1,12,333]}
df = pd.DataFrame(data)
此峰值应为 1320,而 2303 忽略这些峰值的缓慢增加。
感谢您的帮助!
(这也是大量循环,所以我需要它能够通过并记录每个循环的峰值)
好的,我试了一下,使用我在评论中建议的简单启发式方法。
def filter_peaks(df):
df["before"] = df["Pressure"].shift(1)
df["after"] = df["Pressure"].shift(-1)
df["max"] = df.max(axis=1)
df = df.fillna(0)
return df[df["Pressure"] == df["max"]]["Pressure"].to_frame()
filter_peaks(df) # test one application
如果将此应用于测试数据框一次,您将得到以下结果:
你可以看到,它几乎不起作用:第 21 行的值只需要稍微高一点就可以超过第 8 行的真实第二个峰值。
您可以通过迭代来解决这个问题,即使用 filter_peaks(filter_peaks(df))
。然后你最终会得到一个干净的数据框,你可以将你的 .nlargest
策略应用于。
编辑
完整代码示例:
import pandas as pd
data = {'Pressure' : [100,112,114,120,123,420,123,1230,1320,1,23,13,13,13,123,13,123,3,222,2303,1233,1233,1,1,30,20,40,401,10,40,12,122,1,12,333]}
df = pd.DataFrame(data)
def filter_peaks(df):
df["before"] = df["Pressure"].shift(1)
df["after"] = df["Pressure"].shift(-1)
df["max"] = df.max(axis=1)
df = df.fillna(0)
return df[df["Pressure"] == df["max"]]["Pressure"].to_frame()
df2 = filter_peaks(df) # or do it twice if you want to be sure: filter_peaks(filter_peaks(df))
df2["Pressure"].nlargest(2)
输出:
19 2303
8 1320
Name: Pressure, dtype: int64
我正在从一台有数千个周期的机器上导入数据。每个周期持续几分钟,并且有两个我需要记录的压力峰值。一个例子可以在下图中看到。
在此循环中,您可以看到有两个峰值,一个在 807 psi,一个在 936 psi。我需要记录这些值。我已经对数据进行了排序,因此我可以确定一个周期何时开启或关闭,但现在我需要弄清楚如何记录这两个最大值。我以前试过这个:
df2 = df.groupby('group')['Pressure'].nlargest(2).rename_axis (index=['group', 'row_index'])
获得最大值,但意识到这只会给我两个最大值,这两个最大值在某些周期中正好发生在峰值之前。
在此示例数据框中,我提供了一个周期:
import pandas as pd
data = {'Pressure' : [100,112,114,120,123,420,123,1230,1320,1,23,13,13,13,123,13,123,3,222,2303,1233,1233,1,1,30,20,40,401,10,40,12,122,1,12,333]}
df = pd.DataFrame(data)
此峰值应为 1320,而 2303 忽略这些峰值的缓慢增加。
感谢您的帮助!
(这也是大量循环,所以我需要它能够通过并记录每个循环的峰值)
好的,我试了一下,使用我在评论中建议的简单启发式方法。
def filter_peaks(df):
df["before"] = df["Pressure"].shift(1)
df["after"] = df["Pressure"].shift(-1)
df["max"] = df.max(axis=1)
df = df.fillna(0)
return df[df["Pressure"] == df["max"]]["Pressure"].to_frame()
filter_peaks(df) # test one application
如果将此应用于测试数据框一次,您将得到以下结果:
你可以看到,它几乎不起作用:第 21 行的值只需要稍微高一点就可以超过第 8 行的真实第二个峰值。
您可以通过迭代来解决这个问题,即使用 filter_peaks(filter_peaks(df))
。然后你最终会得到一个干净的数据框,你可以将你的 .nlargest
策略应用于。
编辑 完整代码示例:
import pandas as pd
data = {'Pressure' : [100,112,114,120,123,420,123,1230,1320,1,23,13,13,13,123,13,123,3,222,2303,1233,1233,1,1,30,20,40,401,10,40,12,122,1,12,333]}
df = pd.DataFrame(data)
def filter_peaks(df):
df["before"] = df["Pressure"].shift(1)
df["after"] = df["Pressure"].shift(-1)
df["max"] = df.max(axis=1)
df = df.fillna(0)
return df[df["Pressure"] == df["max"]]["Pressure"].to_frame()
df2 = filter_peaks(df) # or do it twice if you want to be sure: filter_peaks(filter_peaks(df))
df2["Pressure"].nlargest(2)
输出:
19 2303
8 1320
Name: Pressure, dtype: int64