如何获取满足掩码条件的第一行索引?

3 投票
4 回答
78 浏览
提问于 2025-04-14 15:44

这是我的数据表:

import pandas as pd

df = pd.DataFrame(
    {
        'a': [100, 1123, 123, 100, 1, 0, 1],
        'b': [1000, 11123, 1123, 0, 55, 0, 1],
    },
    index=range(100, 107)
)

这是我想要的输出结果。我想创建一个名为 c 的新列:

       a      b      c
100   100   1000    NaN
101  1123  11123    NaN
102   123   1123    NaN
103   100      0    3.0
104     1     55    NaN
105     0      0    NaN
106     1      1    NaN

我用的条件是:

mask = ((df.a > df.b))

我想找到这个条件第一次出现的行的索引。我希望保留原来的索引,但想要获取 reset_index() 的值。在这个例子中,条件第一次出现的索引是 3

我可以通过以下方式找到条件第一次出现的位置:

df.loc[mask.cumsum().eq(1) & mask, 'c'] = 'the first row'

但是我不知道怎么获取这个索引。

4 个回答

2

你可以对索引进行 布尔索引,并切片获取第一个项目:

df.loc[df.index[mask][:1], 'c'] = 'the first row'

注意:使用 [:1] 而不是 [1],这样即使没有 True 的情况也能正常工作。

输出结果:

        a      b              c
100   100   1000            NaN
101  1123  11123            NaN
102   123   1123            NaN
103   100      0  the first row
104     1     55            NaN
105     0      0            NaN
106     1      1            NaN

如果没有匹配的结果,这样会创建一个空列:

        a      b    c
100   100   1000  NaN
101  1123  11123  NaN
102   123   1123  NaN
103   100      0  NaN
104     1     55  NaN
105     0      0  NaN
106     1      1  NaN
3

下面的代码会检查数据表中的每一行,使用 .apply() 方法。当满足条件 a > b 时,它会返回这一行的线性索引。最后,结果会被写入一个新的列 'c' 中。

df['c'] = df.apply(
    lambda row: df.index.get_loc(row.name) if row.a > row.b else np.NaN,
    axis=1
)

结果:

    a    b     c
100 100  1000  NaN  
101 1123 11123 NaN  
102 123  1123  NaN  
103 100  0     3.0
104 1    55    NaN
105 0    0     NaN
106 1    1     NaN

3

代码

这段代码可以修改一下,不仅可以查找第一个项目,还可以查找第二个和第三个项目。

cond1 = df['a'] > df['b']
cond2 = df.groupby(cond1).cumcount().eq(0)
df.loc[cond1 & cond2, 'c'] = 'the first row'

数据框(df):

        a      b              c
100   100   1000            NaN
101  1123  11123            NaN
102   123   1123            NaN
103   100      0  the first row
104     1     55            NaN
105     0      0            NaN
106     1      1            NaN

如果你只想找第一个值,下面的代码可能会更简单:

df.loc[df['a'].gt(df['b']).cummax().cumsum().eq(1), 'c'] = 'the first row'

更新答案

如果你只想要索引的位置,可以使用以下代码:

cond1 = df['a'] > df['b']
idx = cond1.idxmax()
loc = df.index.get_loc(idx)

位置(loc):

3

df.loc[df.index == idx, 'c'] = loc

数据框(df):

        a      b    c
100   100   1000  NaN
101  1123  11123  NaN
102   123   1123  NaN
103   100      0    3
104     1     55  NaN
105     0      0  NaN
106     1      1  NaN

撰写回答