simpler python equivalent of R-style grep, including multiple things to match
这个问题几乎与这个问题重复,并进行了一些调整。
获取以下数据框,并获取其中包含"sch"或"oa"的列的位置。 在R中足够简单:
1 2 3 4 5 6 7 8 9 10 11 12 | df <- data.frame(cheese = rnorm(10), goats = rnorm(10), boats = rnorm(10), schmoats = rnorm(10), schlomo = rnorm(10), cows = rnorm(10)) grep("oa|sch", colnames(df)) [1] 2 3 4 5 write.csv(df, file ="df.csv") |
现在在python中,我可以使用一些详细的列表理解:
1 2 3 4 5 6 | import pandas as pd df = pd.read_csv("df.csv", index_col = 0) matches = [i for i in range(len(df.columns)) if"oa" in df.columns[i] or"sch" in df.columns[i]] matches Out[10]: [1, 2, 3, 4] |
我想知道在python中是否有比上面的列表推导示例更好的方法。 具体来说,如果我有几十个字符串匹配怎么办? 在R中,我可以做类似的事情
1 2 | regex <- paste(vector_of_strings, sep ="|") grep(regex, colnames(df)) |
但是如何在python中使用列表理解来做到这一点并不明显。 也许我可以使用字符串操作以编程方式创建在列表中执行的字符串,以处理所有重复的
使用pandas的DataFrame.filter运行相同的正则表达式:
1 2 3 4 5 | df.filter(regex ="oa|sch").columns # Index(['goats', 'boats', 'schmoats', 'schlomo'], dtype='object') df.filter(regex ="oa|sch").columns.values # ['goats' 'boats' 'schmoats' 'schlomo'] |
数据
1 2 3 4 5 6 7 8 9 10 11 | import numpy as np import pandas as pd np.random.seed(21419) df = pd.DataFrame({'cheese': np.random.randn(10), 'goats': np.random.randn(10), 'boats': np.random.randn(10), 'schmoats': np.random.randn(10), 'schlomo': np.random.randn(10), 'cows': np.random.randn(10)}) |
并且要搜索多个字符串:
1 2 3 | rgx ="|".join(list_of_strings) df.filter(regex = rgx) |
要返回索引,请考虑来自@Divakar的这个矢量化numpy解决方案。 请注意,与R不同,Python是零索引的。
1 2 3 4 5 6 7 | def column_index(df, query_cols): cols = df.columns.values sidx = np.argsort(cols) return sidx[np.searchsorted(cols,query_cols,sorter=sidx)] column_index(df, df.filter(regex="oa|sch").columns) # [1 2 3 4] |
也许您正在寻找
1 2 3 4 | import re pattern = re.compile("oa|sch") [i for i in range(len(df.columns)) if pattern.search(df.columns[i])] # [1, 2, 3, 4] |
与R的矢量化相比,可能不是最好的,但列表理解应该没问题。
如果你想将字符串连接在一起,你可以做类似的事情
1 2 | "|".join(("oa","sch")) # 'oa|sch' |