Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >pandas中的矢量化列式正则表达式匹配

pandas中的矢量化列式正则表达式匹配
EN

Stack Overflow用户
提问于 2020-04-26 05:41:37
回答 3查看 159关注 0票数 2

第一部分

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
x   | y     
----|--------
foo | 1.foo-ya
bar | 2.bar-ga
baz | 3.ha-baz
qux | None

我想过滤y在中间恰好包含x的行(既不是开始也不是结束,即匹配模式'^.+\w+.+$',命中第1&2行),不包括None/NaN:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
x   | y
----|-----
foo | 1.foo-ya
bar | 2.bar-ga

这是一个典型的成对字符比较,这在SQL中很容易实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
select x, y from df where y like concat('^.+', x, '.+%');

或在R中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
library(dplyr)
library(stringr)
library(glue)
df %>% filter(str_detect(y, glue('^.+{x}.+$')))

但是,既然我不是熊猫方面的专家,那么在熊猫中似乎没有类似的简单的“矢量化”正则表达式匹配方法?我应用了lambda方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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), :]

在熊猫中有没有更优雅的方法来完成这件事?

第二部分

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
x   | y        |  z
----|----------|---
foo | 1.foo-ya |  1
bar | 2.bar-ga |  2

在R中,我可以做一个直接的管道争论:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
df %>%
  filter(str_detect(y, glue('^.+{x}.+$'))) %>%
  mutate(z=str_replace(y, glue('^(\\d+)\\.{x}.+$'), '\\1') %>%
           as.numeric)

但在熊猫中,我只知道lambda方法。还有比它更“好”的方法吗?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

顺便说一句,assign方法无法工作。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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))

谢谢!

EN

回答 3

Stack Overflow用户

发布于 2020-04-26 08:29:00

pandas字符串操作建立在python的string和re模块之上。试一试,看看这是不是你想要的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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
票数 1
EN

Stack Overflow用户

发布于 2020-04-26 11:55:29

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def str_detect(string: pd.Series, pattern: pd.Series) -> List[bool]:
    """mimic str_detect in R
    """
    if len(string) > len(pattern):
        pattern.extend([pattern[-1]] * (len(string)-len(pattern)))
    elif len(string) < len(pattern):
        pattern = pattern[1:len(string)]

    return [bool(re.match(y, x)) if x and y else False
            for x, y in zip(string, pattern)]

def str_extract(string: pd.Series, pattern: pd.Series) -> List[str]:
    """mimic str_extract in R
    """
    if len(string) > len(pattern):
        pattern.extend([pattern[-1]] * (len(string)-len(pattern)))
    elif len(string) < len(pattern):
        pattern = pattern[1:len(string)]
    o = [re.search(y, x) if x and y else None
         for x, y in zip(string, pattern)]

    return [x.group() if x else np.nan for x in o]

然后

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
df.loc[str_detect(
    df['y'], '^.+' + df['x']+'.+$'), ['x', 'y']]
(df
  .assign(z=str_extract(df['y'], r'^(\d+)(?=\.' + df['x'] + ')'))
  .dropna(subset=['z'])
  .loc[:, ['x', 'y', 'z']])
票数 0
EN

Stack Overflow用户

发布于 2021-06-25 00:28:11

这是你想要的方式吗?几乎复制了你在R中所做的事情:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> from numpy import vectorize
>>> from pipda import register_func
>>> from datar.all import f, tribble, filter, grepl, paste0, mutate, sub, as_numeric
[2021-06-24 17:27:16][datar][WARNING] Builtin name "filter" has been overriden by datar.
>>> 
>>> df = tribble(
...   f.x,   f.y,
...   "foo", "1.foo-ya",
...   "bar", "2.bar-ga",
...   "baz", "3.ha-baz",
...   "qux", None
... )
>>> 
>>> @register_func(None)
... @vectorize
... def str_detect(text, pattern):
...   return grepl(pattern, text)
... 
>>> @register_func(None)
... @vectorize
... def str_replace(text, pattern, replacement):
...   return sub(pattern, replacement, text)
... 
>>> df >> \
...   filter(str_detect(f.y, paste0('^.+', f.x, '.+$'))) >> \
...   mutate(z=as_numeric(str_replace(f.y, paste0(r'^(\d+)\.', f.x, '.+$'), r'\1')))
         x         y         z
  <object>  <object> <float64>
0      foo  1.foo-ya       1.0
1      bar  2.bar-ga       2.0

免责声明:我是datar包的作者。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61436313

复制
相关文章
PHP中的正则表达式及模式匹配
PHP中对于正则处理文本提供了两种方式,一种是PCRE方式(PCRE库是一个实现了与perl 5在语法和语义上略有差异(详见下文)的正则表达式模式匹配功能的函数集. 当前的实现对应于perl 5.005.);另一个是POSIX方式。
大江小浪
2018/07/25
2.9K0
正则表达式来了,Excel中的正则表达式匹配示例
当需要在单元格区域中找到某个值时,可以使用MATCH函数。在单元格中查找特定字符串时,FIND函数和SEARCH函数非常方便。如何知道单元格中是否包含与给定模式匹配的信息?显然,可以使用正则表达式。
fanjy
2021/11/10
22.1K0
正则表达式来了,Excel中的正则表达式匹配示例
正则表达式在密码强度匹配中的使用
  今天领导让我写几个正则表达式来对密码做强度验证,听到写正则表达式内心是这样的感觉(哈哈,三分钟搞定,今天又可以打鱼了)。需求如下:密码组成只能是数字,字母,英文可见半角符号,然后需要如下4个表达式:
用户2038589
2018/09/06
4K0
[剑指offer] 正则表达式匹配
请实现一个函数用来匹配包括’.’和’*’的正则表达式。模式中的字符’.’表示任意一个字符,而’*’表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串”aaa”与模式”a.a”和”ab*ac*a”匹配,但是与”aa.a”和”ab*a”均不匹配
尾尾部落
2018/09/04
1.3K0
正则表达式:.Net Framework平衡组/递归匹配搜索源码中的函数/方法({}匹配)
版权声明:本文为博主原创文章,转载请注明源地址。 https://blog.csdn.net/10km/article/details/52230558
10km
2019/05/25
1.4K0
正则表达式匹配
该文讲述了如何用正则表达式匹配包括‘.’和‘*’在内的正则表达式。‘.’表示任意一个字符,而‘*’表示它前面的字符可以出现任意次(包含0次)。该算法利用动态规划的思想,结合字符串和模式的特点,进行匹配。
用户1148830
2018/01/03
1.6K0
正则表达式中请问怎么匹配小于100的数字?
前几天在Python最强王者交流群【Chloe】问了一道Pandas处理的问题,如下图所示。
前端皮皮
2022/08/17
1.4K0
正则表达式中请问怎么匹配小于100的数字?
利用Python进行数据分析(15) pandas基础: 字符串操作
index()方法和find()方法的区别是:如果不包含子字符串,index()会抛出一个异常,而find()会返回-1。
公众号---人生代码
2019/10/23
4500
利用Python进行数据分析(15) pandas基础: 字符串操作
正则表达式匹配_正则表达式匹配字符串长度
请实现一个函数用来匹配包括’.’和’*’的正则表达式。模式中的字符’.’表示任意一个字符,而’*’表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串”aaa”与模式”a.a”和”ab*ac*a”匹配,但是与”aa.a”和”ab*a”均不匹配
全栈程序员站长
2022/09/19
2K0
Python中的正则表达式及其常用匹配函数用法简介
正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。在这篇文章之前,小编整理过Python正则表达式系列文章,如下所示:
Python进阶者
2020/05/29
1.3K0
正则表达式范围匹配
近期小编在进行评测语料的制作时,涉及到一些复杂字符串的过滤和提取等内容,例如找出某一句话中在某个特定语句结构下出现的文字,虽然使用循环,if-else等语句可以搞定,但是比较麻烦,使用正则表达式处理就比较方便。
用户5521279
2020/03/19
3.2K0
【pandas】pandas中的常见函数
4、pandas.get_dummies(data):将某列数据用one-hot编码表示
西西嘛呦
2020/08/26
2K0
正则表达式 : 检索匹配的利器
淡定
2017/08/29
1.7K0
检索匹配的利器:正则表达式
正则表达式(Regular Expression,下文简称为Regular或正则)是开发中一个不可多得的利器,它广泛应用于字符串的查找、匹配以及替换等场景。以其简短的表现形式和高效的查找匹配效率赢得众多程序员的喜爱。本文旨在帮助大家入门正则并学会解决常见的正则问题,希望能帮到大家。
wxdut.com
2018/05/09
4.2K2
检索匹配的利器:正则表达式
php匹配url的正则表达式
//https?://([-\w.]+)+(:\d+)?(/([\w/_.]*(\?\S+)?)?)? //PHP Example: Automatically link URL's inside t
大师级码师
2021/10/27
2.1K0
pandas中使用excel的模糊匹配通配符,真香
因为在 pandas 中可以把筛选和统计两种逻辑分开编写,所以代码清晰好用。 问题在于pandas 中要实现模糊匹配,只能使用正则表达式或某种具体的函数。
咋咋
2023/02/10
1.8K0
pandas中使用excel的模糊匹配通配符,真香
Java匹配中文的正则表达式
[\u4E00-\u9FA5]汉字﹐[\uFE30-\uFFA0]全角字符 [\u4E00-\u9FA5]汉字﹐[\uFE30-\uFFA0]全角字符所以说 ,Java的正则表达式是可以匹配中文字符的,同时,用中文字符来写表达式也是可以的.
大师级码师
2021/10/29
2.2K0
对比python字符串函数,轻松学习pandas的 str 矢量化字符串函数
python字符串应该是python里面最重要的数据类型了,因此学会怎么处理各种各样的字符串,显得尤为重要。
朱小五
2020/07/02
1.3K0
对比python字符串函数,轻松学习pandas的 str 矢量化字符串函数
点击加载更多

相似问题

分列式csv pandas

13

pandas中循环的矢量化

10

Pandas数据矢量化

10

Python pandas中的矢量化函数

114

Pandas - Python中的矢量化操作

14
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文