R pandas中的矢量化列式正则表达式匹配 第一部分

R pandas中的矢量化列式正则表达式匹配 第一部分,r,regex,pandas,dplyr,vectorization,R,Regex,Pandas,Dplyr,Vectorization,假设我有一个数据集df,如下所示: x | y ----|-------- foo | 1.foo-ya bar | 2.bar-ga baz | 3.ha-baz qux | None 我想在y中精确地包含y包含x的行(不开始也不结束),即匹配模式“^ ++W+.+$,命中行1和2”,不包括NON/NAN: x | y ----|----- foo | 1.foo-ya bar | 2.bar-ga 这是一种典型的成对字符比较,在SQL中很容易实现: 从df中选择x,y,

假设我有一个数据集df,如下所示:

x   | y     
----|--------
foo | 1.foo-ya
bar | 2.bar-ga
baz | 3.ha-baz
qux | None
我想在y中精确地包含y包含x的行(不开始也不结束),即匹配模式“^ ++W+.+$,命中行1和2”,不包括NON/NAN:

x   | y
----|-----
foo | 1.foo-ya
bar | 2.bar-ga
这是一种典型的成对字符比较,在SQL中很容易实现:

从df中选择x,y,其中y像concat('^.+',x'.+%');
或在R中:

库(dplyr)
图书馆(stringr)
图书馆(胶水)
df%>%过滤器(str_检测(y,glue('^.+{x}.+$))
但由于我不是熊猫方面的专家,似乎熊猫中没有类似的简单“矢量化”正则表达式匹配方法?我采用了lambda方法:

将熊猫作为pd导入
进口稀土
df.loc[df.apply(lambda行:bool)(重新搜索(
“^.+'+行.x+'.+$”,行.y))
如果row.x和row.y为False,则轴=1),:]
熊猫有没有更优雅的方法来完成它

第二部分 此外,我想提取第一部分中生成的匹配记录中的前导数字(1,2,…):

x   | y        |  z
----|----------|---
foo | 1.foo-ya |  1
bar | 2.bar-ga |  2
在R中,我可以直接进行管道争吵:

df%>%
过滤器(str_detect(y,glue('^.+{x}.+$)))%>%
突变(z=str_替换(y,粘合('^(\\d+\\\.{x}.+$'),'\\1')%>%
as(数字)
但在熊猫中,我只知道lambda方法。有没有比这更好的方法

a=df.loc[df.apply(lambda行:bool(
重新搜索('^.+'+行.x+'.+$',行.y))
如果第x行和第y行为假,则轴=1),
['x','y']]
a['z']=a.apply(lambda行:re.sub(
r'^(\d+\.+row.x+'.+$',r'\1',row.y),轴=1.aType('int'))
A.
顺便说一句,
assign
方法无法工作

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))

谢谢大家!

字符串操作构建在python的字符串和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

感谢所有鼓舞人心的回复。我不得不说,尽管Python在很多方面都很优秀,但在这种矢量化操作方面,我更喜欢R。所以我为这个案子重新设计了轮子

def str_detect(字符串:pd.Series,模式:pd.Series)->List[bool]:
“”“模拟str\u在R中检测
"""
如果len(字符串)>len(模式):
extend([pattern[-1]]*(len(string)-len(pattern)))
elif len(字符串)List[str]:
“”“模仿R中的stru提取”
"""
如果len(字符串)>len(模式):
extend([pattern[-1]]*(len(string)-len(pattern)))
elif len(字符串)
然后

df.loc[str\u检测(
df['y'],'^.+'+df['x']+'.+$),['x',y']]
(df)
.assign(z=str\u extract(df['y'],r'^(\d+)(=\.+df['x']+'))
.dropna(子集=['z'])
.loc[:,['x','y','z']]

您是否需要
df[df['x'].eq(df['y'].str.split('\.\124;-').str[1])]
?您可以根据需要更改拆分的正则表达式df.assign(foo=df['y'].str.extract('\d\.(\w+))).query('x==foo').drop('foo',axis=1)。assign(num=df['y'].str.extract('(^\d'))是一次性解决方案。@datanoveler,谢谢。“正好在中间”只意味着匹配模式r'^.+{column x}.+$”。上面的方法有效吗?@datanoveler,是的,两者都有效。谢谢但如果模式在整个数据集中不一致怎么办?是否有一种矢量化的方法来首先识别按列匹配?