我们说我的小区中有一个带有字符串内容的pandas数据帧。
找到与特定正则表达式匹配的字符串然后返回带有各自行和列索引的元组列表的最佳方法是什么?
即,
import pandas as pd
mydf = pd.DataFrame({'a':['hello', 'world'], 'b': ['hello', 'folks']})
def findIndex(mydf, regex):
return regex_indexes
如果我这样做:
regex = r"hello"
findIndex(mydf, regex) # it'd return [(0,0), (0,1)],
如果我这样做:
regex = r"matt"
findIndex(mydf, regex) # it'd return [(-1,-1)],
如果我这样做:
regex = r"folks"
findIndex(mydf, regex) # it'd return [(1,1)],
我可以在pd.DataFrame
做一个双循环,但想知道其他想法是否更好......
答案 0 :(得分:2)
您可以尝试使用apply
,str.match
和nonzero
。
def findIdx(df, pattern):
return df.apply(lambda x: x.str.match(pattern)).values.nonzero()
findIdx(mydf, r"hello")
(array([0, 0]), array([0, 1]))
df.apply(lambda x: x.str.match(pattern)).values
会返回df
相同大小的数组,其中True
表示匹配,否则为False
。
然后我们使用nonzero
查找1
(True
)部分的索引。
它将返回与数组元组中的模式匹配的索引。如果你需要
一个元组列表,使用list(zip(*findIdx(mydf, r"hello")))
[(0, 0), (0, 1)]
或np.transpose(findIdx(mydf, r"hello"))
。
如果在找不到任何内容时需要返回None
,可以尝试
def findIdx(df, pattern):
ret = df.apply(lambda x: x.str.match(pattern)).values.nonzero()
return None if len(ret[0]) == 0 else ret
注意:str.match
在钩子下使用re.match
。它将匹配此示例函数中以pattern
开头的字符串。如果想要查找字符串是否包含pattern
作为子字符串,请使用str.contains
而不是str.match
。