Python Pandas:在大 DF 中找到局部最大值的最佳方法
Python Pandas: Best way to find local maximums in large DF
我有一个由许多循环组成的大型数据帧,每个循环内部有 2 个最大峰值,我需要将其捕获到另一个数据帧中。
我创建了一个模拟我所看到的数据的示例数据框:
import pandas as pd
data = {'Cycle':[1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3], 'Pressure':[100,110,140,180,185,160,120,110,189,183,103,115,140,180,200,162,125,110,196,183,100,110,140,180,185,160,120,180,201,190]}
df = pd.DataFrame(data)
正如您在每个周期中看到的那样,有两个最大值,但我遇到问题的部分是第二个峰值通常高于第一个峰值,因此技术上可能有几行数字高于其他峰值循环中的最大值。结果应如下所示:
data2 = {'Cycle':[1,1,2,2,3,3], 'Peak Maxs': [185,189,200,196,185,201]}
df2= pd.DataFrame(data2)
我已经尝试了几种方法,包括每个周期 .nlargest(2),但问题是,由于其中一个峰值通常更高,它会拉取数据中第二高的数字,这不一定是另一个峰值.
此图显示了我希望能够找到的每个循环的峰值压力。
感谢您的帮助。
使用groupby().shift()
获取邻域值,然后比较:
g = df.groupby('Cycle')
local_maxes = (df['Pressure'].gt(g['Pressure'].shift()) # greater than previous row
& df['Pressure'].gt(g['Pressure'].shift(-1))] # greater than next row
)
df[local_maxes]
输出:
Cycle Pressure
4 1 185
8 1 189
14 2 200
18 2 196
24 3 185
28 3 201
来自 scipy
argrelextrema
from scipy.signal import argrelextrema
out = df.groupby('Cycle')['Pressure'].apply(lambda x : x.iloc[argrelextrema(x.values, np.greater)])
Out[124]:
Cycle
1 4 185
8 189
2 14 200
18 196
3 24 185
28 201
Name: Pressure, dtype: int64
out = out.sort_values().groupby(level=0).tail(2).sort_index()
out
Out[138]:
Cycle
1 4 185
8 189
2 14 200
18 196
3 24 185
28 201
Name: Pressure, dtype: int64
我有一个由许多循环组成的大型数据帧,每个循环内部有 2 个最大峰值,我需要将其捕获到另一个数据帧中。
我创建了一个模拟我所看到的数据的示例数据框:
import pandas as pd
data = {'Cycle':[1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3], 'Pressure':[100,110,140,180,185,160,120,110,189,183,103,115,140,180,200,162,125,110,196,183,100,110,140,180,185,160,120,180,201,190]}
df = pd.DataFrame(data)
正如您在每个周期中看到的那样,有两个最大值,但我遇到问题的部分是第二个峰值通常高于第一个峰值,因此技术上可能有几行数字高于其他峰值循环中的最大值。结果应如下所示:
data2 = {'Cycle':[1,1,2,2,3,3], 'Peak Maxs': [185,189,200,196,185,201]}
df2= pd.DataFrame(data2)
我已经尝试了几种方法,包括每个周期 .nlargest(2),但问题是,由于其中一个峰值通常更高,它会拉取数据中第二高的数字,这不一定是另一个峰值.
此图显示了我希望能够找到的每个循环的峰值压力。
感谢您的帮助。
使用groupby().shift()
获取邻域值,然后比较:
g = df.groupby('Cycle')
local_maxes = (df['Pressure'].gt(g['Pressure'].shift()) # greater than previous row
& df['Pressure'].gt(g['Pressure'].shift(-1))] # greater than next row
)
df[local_maxes]
输出:
Cycle Pressure
4 1 185
8 1 189
14 2 200
18 2 196
24 3 185
28 3 201
来自 scipy
argrelextrema
from scipy.signal import argrelextrema
out = df.groupby('Cycle')['Pressure'].apply(lambda x : x.iloc[argrelextrema(x.values, np.greater)])
Out[124]:
Cycle
1 4 185
8 189
2 14 200
18 196
3 24 185
28 201
Name: Pressure, dtype: int64
out = out.sort_values().groupby(level=0).tail(2).sort_index()
out
Out[138]:
Cycle
1 4 185
8 189
2 14 200
18 196
3 24 185
28 201
Name: Pressure, dtype: int64