如何找到每个组的第一个本地最大值?

use*_*015 8 python dataframe python-3.x pandas

假设我有一个Pandas数据框如下:

Test Parameter Value

X1     0        0.033285423511615113
X1     1        0.78790279861666179
X1     2        0.79136989638378297
X1     3        0.80063190842016707
X1     4        0.7884653622402551
X1     5        0.78561849214309198...
...
X1     22       22: 0.82241991278171311...
...
X2 ...
Run Code Online (Sandbox Code Playgroud)

我想得到参数值为3的行.这是在第一次下降之前具有最后一个增加值的行.请注意,稍后我们可能会有更高的值(例如第22行).基本上,我试图在"第一"减少值之前得到"最后"数字.

另请注意,有多个测试,所以我可能需要做类似的事情:

myDF.groupby("Test").Something
Run Code Online (Sandbox Code Playgroud)

And*_*den 7

Coldspeed几乎拥有它,只获得第一组你可以使用cumprod,或类似的

In [11]: df[((df.Value.diff().fillna(1) > 0).cumprod()) == 1].tail(1)
Out[11]:
  Test  Parameter     Value
3   X1          3  0.800632
Run Code Online (Sandbox Code Playgroud)

诀窍是:

In [12]: (df.Value.diff().fillna(1) > 0)
Out[12]:
0     True
1     True
2     True
3     True
4    False
5    False
6     True
Name: Value, dtype: bool

In [13]: (df.Value.diff().fillna(1) > 0).cumprod()
Out[13]:
0    1
1    1
2    1
3    1
4    0
5    0
6    0
Name: Value, dtype: int64
Run Code Online (Sandbox Code Playgroud)

注意:我的df是这样的:

In [21]: df
Out[21]:
  Test  Parameter     Value
0   X1          0  0.033285
1   X1          1  0.787903
2   X1          2  0.791370
3   X1          3  0.800632
4   X1          4  0.788465
5   X1          5  0.785618
6   X1         22  0.822420
Run Code Online (Sandbox Code Playgroud)


piR*_*red 6

使用时np.diff,它会自然地减少一个数组的长度,当我使用np.flatnonzero它时将识别先前的序数位置.

df.iloc[[np.flatnonzero(np.diff(df.Value) < 0)[0]]]

  Test  Parameter     Value
3   X1          3  0.800632
Run Code Online (Sandbox Code Playgroud)

注意:
我们可以通过访问底层的numpy数组来加快速度

df.iloc[[np.flatnonzero(np.diff(df.Value.values) < 0)[0]]]
Run Code Online (Sandbox Code Playgroud)

说明

得到分歧

np.diff(df.Value)

array([ 0.754618,  0.003467,  0.009262, -0.012167, -0.002847,  0.036802])
Run Code Online (Sandbox Code Playgroud)

找出差异为负的地方

np.flatnonzero(np.diff(df.Value) < 0)

array([3, 4])
Run Code Online (Sandbox Code Playgroud)

我想要第一个

np.flatnonzero(np.diff(df.Value) < 0)[0]

3
Run Code Online (Sandbox Code Playgroud)

使用双括号 iloc

df.iloc[[3]]

  Test  Parameter     Value
3   X1          3  0.800632
Run Code Online (Sandbox Code Playgroud)

该集团看起来像

f = lambda d: d.iloc[[np.flatnonzero(np.diff(d.Value.values) < 0)[0]]]
df.groupby('Test').apply(f)

       Test  Parameter     Value
Test                            
X1   3   X1          3  0.800632
Run Code Online (Sandbox Code Playgroud)