最大值出现在最小值之前的最后一次索引

5
这里需要翻译的内容是:

标题可能不太直观,让我举个例子。假设我有一个使用以下代码创建的df

a = np.array([[ 1. ,  0.9,  1. ],
              [ 0.9,  0.9,  1. ],
              [ 0.8,  1. ,  0.5],
              [ 1. ,  0.3,  0.2],
              [ 1. ,  0.2,  0.1],
              [ 0.9,  1. ,  1. ],
              [ 1. ,  0.9,  1. ],
              [ 0.6,  0.9,  0.7],
              [ 1. ,  0.9,  0.8],
              [ 1. ,  0.8,  0.9]])

idx = pd.date_range('2017', periods=a.shape[0])
df = pd.DataFrame(a, index=idx, columns=list('abc'))

我可以使用以下方法获取每列最小值的索引位置:
df.idxmin()

现在,我该如何找到列向最大值的最后一次出现位置,直到最小值的位置为止?
视觉上,我想找到下面绿色最大值的位置:

enter image description here

忽略最小出现后的最大值。

我可以使用.apply来完成这个任务,但是能否使用掩码/高级索引来完成?

期望结果:

a   2017-01-07
b   2017-01-03
c   2017-01-02
dtype: datetime64[ns]

澄清:如果一列变成了“1 0 2”,您是否希望忽略2,只获取1的索引? - user2357112
你的索引是否已排序? - cs95
如果您有重复的最小值呢? - Bharath M Shetty
是的 @user2357112。首先找到最小值,屏蔽该最小值后出现的所有值,在该屏蔽框架中找到最大值的最后一个出现位置。 - Brad Solomon
@Dark 假设为简单起见,没有重复的最小值。 - Brad Solomon
显示剩余2条评论
3个回答

8

应用一个掩码,然后在反转的数据帧上调用idxmax

df.mask((df == df.min()).cumsum().astype(bool))[::-1].idxmax()

a   2017-01-07
b   2017-01-03
c   2017-01-02
dtype: datetime64[ns]

细节

首先,确定每列最小项的位置。

df.min()

a    0.6
b    0.2
c    0.1
dtype: float64

i = df == df.min()
i

                a      b      c
2017-01-01  False  False  False
2017-01-02  False  False  False
2017-01-03  False  False  False
2017-01-04  False  False  False
2017-01-05  False   True   True
2017-01-06  False  False  False
2017-01-07  False  False  False
2017-01-08   True  False  False
2017-01-09  False  False  False
2017-01-10  False  False  False

现在,掩盖那些值及其以上的值!
j = df.mask(i).cumsum().astype(bool))
j

              a    b    c
2017-01-01  1.0  0.9  1.0
2017-01-02  0.9  0.9  1.0
2017-01-03  0.8  1.0  0.5
2017-01-04  1.0  0.3  0.2
2017-01-05  1.0  NaN  NaN
2017-01-06  0.9  NaN  NaN
2017-01-07  1.0  NaN  NaN
2017-01-08  NaN  NaN  NaN
2017-01-09  NaN  NaN  NaN
2017-01-10  NaN  NaN  NaN

要找到最后一个最大值,只需反转并调用 idxmax
j[::-1].idxmax()

a   2017-01-07
b   2017-01-03
c   2017-01-02
dtype: datetime64[ns]

4

使用遮罩 -

>>> a = df.values
>>> mask = a.argmin(0) > np.arange(a.shape[0])[:,None]
>>> idx = a.shape[0] - (a*mask)[::-1].argmax(0) - 1
>>> df.index[idx]
DatetimeIndex(['2017-01-07', '2017-01-03', '2017-01-02'], dtype='datetime64[ns]', freq=None)

这里有另一个基于掩码的方法,它将每列中无效的元素设为NaN,然后利用np.nanargmax函数:

a = df.values
min_idx = a.argmin(0)
mask = min_idx < np.arange(a.shape[0])[:,None]
a[mask] = np.nan
idx = a.shape[0]-np.nanargmax(a[::-1],axis=0) - 1
out = df.index[idx]

1
通过使用last_valid_index
df[df==df.min()]=0

(df.mask((df.cumprod()==0)|(df!=df.max()))).apply(lambda x : x.last_valid_index())
Out[583]:
a   2017-01-07
b   2017-01-03
c   2017-01-02
dtype: datetime64[ns]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接