首页 > 解决方案 > 如何从正则表达式匹配中获取 Pandas 数据帧的行索引

问题描述

有人问过这个问题,但我没有找到完整的答案。我有一个数据框,在第一行中有不必要的值,我想找到动物的行索引:

df = pd.DataFrame({'a':['apple','rhino','gray','horn'],
                   'b':['honey','elephant', 'gray','trunk'],
                   'c':['cheese','lion', 'beige','mane']})

       a         b       c
0  apple     honey  cheese
1  rhino  elephant    lion
2   gray      gray   beige
3   horn     trunk    mane

ani_pat = r"rhino|zebra|lion"

这意味着我想找到“1”——与模式匹配的行索引。我在这里看到的一个解决方案是这样的;适用于我的问题...

def findIdx(df, pattern):
    return df.apply(lambda x: x.str.match(pattern, flags=re.IGNORECASE)).values.nonzero()

animal = findIdx(df, ani_pat)
print(animal)
(array([1, 1], dtype=int64), array([0, 2], dtype=int64))

该输出是 NumPy 数组的元组。我已经掌握了 NumPy 和 Pandas 的基础知识,但我不确定如何处理它或它与上面的 df 有何关系。

我像这样更改了那个 lambda 表达式:

df.apply(lambda x: x.str.match(ani_pat, flags=re.IGNORECASE))

       a      b      c
0  False  False  False
1   True  False   True
2  False  False  False
3  False  False  False

这更有意义。但仍在尝试获取 True 值的行索引。我怎样才能做到这一点?

标签: python-3.xpandasnumpy

解决方案


我们可以从过滤器中选择 DataFrame index,其中包含具有anyTrue 值的行:

idx = df.index[
    df.apply(lambda x: x.str.match(ani_pat, flags=re.IGNORECASE)).any(axis=1)
]

idx

Int64Index([1], dtype='int64')

any在轴 1 上将采用布尔 DataFrame 并根据行的内容将其减少到单个维度。

之前any

       a      b      c
0  False  False  False
1   True  False   True
2  False  False  False
3  False  False  False

之后any

0    False
1     True
2    False
3    False
dtype: bool

然后我们可以使用这些布尔值作为掩码index(选择具有 True 值的索引):

Int64Index([1], dtype='int64')

如果需要,我们可以使用tolist来获取列表:

idx = df.index[
    df.apply(lambda x: x.str.match(ani_pat, flags=re.IGNORECASE)).any(axis=1)
].tolist()

idx

[1]

推荐阅读