Python 使用基于正则表达式的部分匹配来选择数据帧的子数据帧
我有一个数据框,它有两列,一列(列“进程参数”)有字符串,另一列(列“值”)有相应的浮点值。我需要筛选出一个子数据框,该子数据框部分匹配列“Process Parameter”中的一组键,并提取与这些键匹配的数据框的两列Python 使用基于正则表达式的部分匹配来选择数据帧的子数据帧,python,regex,pandas,dataframe,slice,Python,Regex,Pandas,Dataframe,Slice,我有一个数据框,它有两列,一列(列“进程参数”)有字符串,另一列(列“值”)有相应的浮点值。我需要筛选出一个子数据框,该子数据框部分匹配列“Process Parameter”中的一组键,并提取与这些键匹配的数据框的两列 df = pd.DataFrame({'Process Parameter' : ['Temperature', 'System Clk', 'Core Clk', 'Bilinear Coeff', 'Prec Coeff', 'Yield'], 'Value' : [1.2
df = pd.DataFrame({'Process Parameter' : ['Temperature', 'System Clk', 'Core Clk', 'Bilinear Coeff', 'Prec Coeff', 'Yield'], 'Value' : [1.2,2.0,3.0, 5.1, 6.2, 7.4]})
keys =['Clk', 'Coeff']
我应该得到一个输出
df_过滤为
Process Parameter Value
System Clk 3.0
Core Clk 2.0
Bilinear Coeff 5.1
Prec Coeff 6.2
我尝试了几种混乱的方法,比如将数据帧转换为列表,然后使用
re.search()、map、str.contains()等。任何人如果有非常有效的解决方案,请告诉我
谢谢和问候,
santosh与|
(regex或
)一起用于布尔掩码,然后通过以下方式进行过滤:
详情:
print (df['Process Parameter'].str.contains('|'.join(keys)))
0 False
1 True
2 True
3 True
4 True
5 False
Name: Process Parameter, dtype: bool
另一种解决方案是,对于不匹配的值,返回的值为NaN,因此有必要:
df = df[df['Process Parameter'].str.extract('('+'|'.join(keys)+')',expand=False).notnull()]
print (df)
Process Parameter Value
1 System Clk a 2.0
2 Core Clk a 3.0
3 Bilinear Coeff 5.1
4 Prec Coeff 6.2
计时:
a = 'Temperature System Clk Core Clk Bilinear Coeff Prec Coeff Yield'.split()
N = 200000
df = pd.DataFrame({'Process Parameter': [np.random.choice(a, size=np.random.randint(1,10)) for x in range(N)]})
df['Process Parameter'] = df['Process Parameter'].str.join(' ')
keys =['Clk', 'Coeff']
In [115]: %timeit df[df['Process Parameter'].str.contains('|'.join(keys))]
10 loops, best of 3: 140 ms per loop
In [116]: %timeit df[df['Process Parameter'].str.extract('('+'|'.join(keys)+')',expand=False).notnull()]
1 loop, best of 3: 247 ms per loop
编辑您需要的
单词边界
以进行匹配:
df = pd.DataFrame({'Process Parameter' : ['Clockspeed', 'System Clk', 'Core Clk',
'Bilinear Coeff', 'Prec Coeff', 'Yield'],
'Value' : [1.2,2.0,3.0, 5.1, 6.2, 7.4]})
keys =['Clk', 'Coeff']
print (df)
Process Parameter Value
0 Clockspeed 1.2
1 System Clk 2.0
2 Core Clk 3.0
3 Bilinear Coeff 5.1
4 Prec Coeff 6.2
5 Yield 7.4
pat = '|'.join(r"\b{}\b".format(x) for x in keys)
df = df[df['Process Parameter'].str.contains(pat)]
print (df)
Process Parameter Value
1 System Clk 2.0
2 Core Clk 3.0
3 Bilinear Coeff 5.1
4 Prec Coeff 6.2
选项1
str.findall
df = df[df['Process Parameter'].str.findall('|'.join(keys)).astype(bool)]
df
Process Parameter Value
1 System Clk 2.0
2 Core Clk 3.0
3 Bilinear Coeff 5.1
4 Prec Coeff 6.2
选项2
只是为了好玩,
str.split
+df.isin
:
m = df['Process Parameter'].str.split(expand=True).isin(keys).any(1)
m
0 False
1 True
2 True
3 True
4 True
5 False
dtype: bool
df[m]
Process Parameter Value
1 System Clk 2.0
2 Core Clk 3.0
3 Bilinear Coeff 5.1
4 Prec Coeff 6.2
此方法不使用基于正则表达式的检查,但是,它仅适用于单个完整单词匹配(而不是多单词或子字符串匹配)。选项1
您可以使用
numpy.core.defchararray.find
from numpy.core.defchararray import find
p = df['Process Parameter'].values.astype(str)
df[(find(p[:, None], keys) >= 0).any(1)]
Process Parameter Value
1 System Clk 2.0
2 Core Clk 3.0
3 Bilinear Coeff 5.1
4 Prec Coeff 6.2
解释
numpy.core.defchararray
标识在字符串中找到另一个字符串的位置。如果找不到,则返回-1
。所以我只需要检查>=0
。我还利用numpy
广播,然后检查是否在所有键中找到任何匹配项
选项2
我喜欢固定的逻辑
df[df['Process Parameter'].str.split().apply(set) & set(keys)]
Process Parameter Value
1 System Clk 2.0
2 Core Clk 3.0
3 Bilinear Coeff 5.1
4 Prec Coeff 6.2
@jezrael,因为它不适用于多个单词,正如你正确地说的。我不是100%确定,但我认为基于非正则表达式的比较比正则表达式快,但我不能保证,因为我没有计时。是的,这是可能的。但我认为这里有一个更好的更通用的解决方案,检查更多的单词键-如果OP不能保证总是一个单词的关键字。我重新排序了选项,我希望现在一切正常。嗯,第二个解决方案是最慢的,regex-win;)所有的键
都是一个词,或者可能是多个词,比如键=['Clk aa','Coeff b']
?我一直在等你回答!我完全被淹没了。我会被这里和那里的少量时间淹没一段时间(-:为了使这更复杂,在键列表中,我可以添加另一个约束,即字符串应该以这些键结尾。例如,我想匹配部分字符串“Clock”,但不想匹配“Clocks”…如果输入字符串是“System Clock”,“Core Clock”,“Clockspeed”,正则表达式匹配的输出应仅为“System Clock”和“Core Clock”-这是一个很好的方法!为了使这一点更加复杂,我可以在键列表中添加另一个约束,即字符串应以这些键结尾。例如,我想匹配部分字符串“Clock”,但不想匹配“Clocks”“……如果输入字符串为“系统时钟”、“核心时钟”、“时钟速度”,则正则表达式匹配的输出应仅为“系统时钟”和“核心时钟”
m = df['Process Parameter'].str.split(expand=True).isin(keys).any(1)
m
0 False
1 True
2 True
3 True
4 True
5 False
dtype: bool
df[m]
Process Parameter Value
1 System Clk 2.0
2 Core Clk 3.0
3 Bilinear Coeff 5.1
4 Prec Coeff 6.2
from numpy.core.defchararray import find
p = df['Process Parameter'].values.astype(str)
df[(find(p[:, None], keys) >= 0).any(1)]
Process Parameter Value
1 System Clk 2.0
2 Core Clk 3.0
3 Bilinear Coeff 5.1
4 Prec Coeff 6.2
df[df['Process Parameter'].str.split().apply(set) & set(keys)]
Process Parameter Value
1 System Clk 2.0
2 Core Clk 3.0
3 Bilinear Coeff 5.1
4 Prec Coeff 6.2