第一部分
假设我有一个如下所示的数据集 df:
x | y
----|--------
foo | 1.foo-ya
bar | 2.bar-ga
baz | 3.ha-baz
qux | None
我想过滤 y 恰好在中间包含 x 的行(既不开始也不结束,即匹配模式 '^.+\w+.+$',命中第 1 行和第 2 行),不包括 None/NaN:
x | y
----|-----
foo | 1.foo-ya
bar | 2.bar-ga
这是典型的成对字符比较,在 SQL 中很容易实现:
select x, y from df where y like concat('^.+', x, '.+%');
或在 R 中:
library(dplyr)
library(stringr)
library(glue)
df %>% filter(str_detect(y, glue('^.+{x}.+$')))
但是由于我不是pandas方面的专家,pandas中似乎没有类似的简单的“矢量化”正则表达式匹配方法?我应用了 lambda 方法:
import pandas as pd
import re
df.loc[df.apply(lambda row: bool(re.search(
'^.+' + row.x + '.+$', row.y))
if row.x and row.y else False, axis=1), :]
pandas 中有没有更优雅的方法来完成它?
第二部分
此外,我想提取第一部分中生成的匹配记录中的前导数字(1, 2, ...):
x | y | z
----|----------|---
foo | 1.foo-ya | 1
bar | 2.bar-ga | 2
在 R 中,我可以进行直接的管道处理:
df %>%
filter(str_detect(y, glue('^.+{x}.+$'))) %>%
mutate(z=str_replace(y, glue('^(\\d+)\\.{x}.+$'), '\\1') %>%
as.numeric)
但是在 pandas 中,我只知道 lambda 方法。还有比它“更好”的方法吗?
a = df.loc[df.apply(lambda row: bool(
re.search('^.+' + row.x + '.+$', row.y))
if row.x and row.y else False, axis=1),
['x', 'y']]
a['z'] = a.apply(lambda row: re.sub(
r'^(\d+)\.' + row.x + '.+$', r'\1', row.y), axis=1).astype('int')
a
顺便说一句,分配
方法无法工作。
df.loc[df.apply(lambda row: bool(re.search(
'^.+' + row.x + '.+$', row.y))
if row.x and row.y else False, axis=1),
['x', 'y']].assign(z=lambda row: re.sub(
r'^(\d+)\.' + row.x + '.+$', r'\1', row.y))
谢谢!
最佳答案
pandas 字符串操作建立在 python 的 string 和 re 模块之上。尝试一下,看看它是否是您想要的:
import re
#find out if values in column x are in column y
#according to the pattern u wrote in the question
pattern = [re.match(fr'^.+{a}.+$',b)
for a,b
in zip(df.x.str.strip(),
df.y.str.strip())
]
match = [ent.group() if ent is not None else np.nan for ent in pattern]
#extract values for digit immediately preceding val in col x
ext = [re.search(fr'\d(?=\.{a})', b) for a,b in
zip(df.x.str.strip(),
df.y.str.strip())]
extract = [ent.group() if ent is not None else np.nan for ent in ext]
df['match'], df['extract'] = match, extract
x y match extract
1 foo 1.foo-ya 1.foo-ya 1
2 bar 2.bar-ga 2.bar-ga 2
3 baz 3.ha-baz NaN NaN
4 qux None NaN NaN
关于r - pandas 中的向量化按列正则表达式匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61436313/