Python Pandas Regex:在列中搜索带有通配符的字符串并返回匹配项[重复]

Posted

技术标签:

【中文标题】Python Pandas Regex:在列中搜索带有通配符的字符串并返回匹配项[重复]【英文标题】:Python Pandas Regex: Search for strings with a wildcard in a column and return matches [duplicate] 【发布时间】:2019-09-04 12:01:18 【问题描述】:

我在可能包含键的列中有一个搜索列表:'keyword1*keyword2' 尝试在单独的数据框列中查找匹配项。如何包含正则表达式通配符类型'keyword1.*keyword2'#using str.extract, extractall or findall?

使用.str.extract 可以很好地匹配精确的子字符串,但我还需要它来匹配关键字之间带有通配符的子字符串。

# dataframe column or series list as keys to search for: 
dfKeys = pd.DataFrame()
dfKeys['SearchFor'] = ['this', 'Something', 'Second', 'Keyword1.*Keyword2', 'Stuff', 'One' ]

# col_next_to_SearchFor_col
dfKeys['AdjacentCol'] = ['this other string', 'SomeString Else', 'Second String Player', 'Keyword1 Keyword2', 'More String Stuff', 'One More String Example' ]

# dataframe column to search in: 
df1['Description'] = ['Something Here','Second Item 7', 'Something There', 'strng KEYWORD1 moreJARGON 06/0 010 KEYWORD2 andMORE b4END', 'Second Item 7', 'Even More Stuff']]

# I've tried:
df1['Matched'] = df1['Description'].str.extract('(%s)' % '|'.join(key['searchFor']), flags=re.IGNORECASE, expand=False)

我还尝试用“extractall”和“findall”替换上面代码中的“extract”,但它仍然没有给我所需的结果。 我希望 'Keyword1*Keyword2' 匹配 "strng KEYWORD1 moreJARGON 06/0 010 KEYWORD2 andMORE b4END"

更新:'.*' 有效! 我还尝试从“SearchFor”列中匹配键旁边的单元格中添加值,即dfKeys['AdjacentCol']

我试过了: df1['From_AdjacentCol'] = df1['Description'].str.extract('(%s)' % '|'.join(key['searchFor']), flags=re.IGNORECASE, expand=False).map(dfKeys.set_index('SearchFor')['AdjacentCol'].to_dict()).fillna('') 适用于除带有通配符的键之外的所有内容。

# expected:
  Description                                      Matched            From_AdjacentCol
0 'Something Here'                                 'Something'         'this other string'
1 'Second Item 7'                                  'Second'            'Second String Player'
2 'Something There'                                'Something'         'this other string'  
3 'strng KEYWORD1 moreJARGON 06/0 010 KEYWORD2...' 'Keyword1*Keyword2' 'Keyword1 Keyword2'
4 'Second Item 7'                                  'Second'            'Second String Player'
5 'Even More Stuff'                                'Stuff'             'More String Stuff'

对此的任何帮助都非常感谢。谢谢!

【问题讨论】:

@Wiktor Stribiżew 我没有遇到过一些类似的问题,但没有一个能解决我遇到的通配符问题。 您正在使用不使用通配符的.str.extract,它使用正则表达式。匹配两个字符串之间的任何字符是一个过于频繁的正则表达式问题,因此是重复的原因。 【参考方案1】:

解决方案

您已接近解决方案,只需将* 更改为.*。阅读docs:

。 (点。)在默认模式下,这匹配除换行符以外的任何字符。如果指定了 DOTALL 标志,则匹配任何 包括换行符的字符。

* 使生成的 RE 匹配前一个 RE 的 0 个或多个重复,尽可能多的重复。 ab* 将匹配“a”, ‘ab’ 或 ‘a’ 后跟任意数量的 ‘b’。

在正则表达式中,星号 * 本身没有任何意义。它与 Unix/Windows 文件系统中通常的 glob 运算符 * 具有不同的含义。

星号是一个量词(即gready量词),它必须与某种模式相关联(这里.匹配任何字符)来表示什么。

MCVE

重塑你的 MCVE:

import re
import pandas as pd

keys = ['this', 'Something', 'Second', 'Keyword1.*Keyword2', 'Stuff', 'One' ]

df1 = pd.DataFrame()
df1['Description'] = ['Something Here','Second Item 7', 'Something There',
                      'strng KEYWORD1 moreJARGON 06/0 010 KEYWORD2 andMORE b4END',
                      'Second Item 7', 'Even More Stuff']


regstr = '(%s)' % '|'.join(keys)

df1['Matched'] = df1['Description'].str.extract(regstr, flags=re.IGNORECASE, expand=False)

正则表达式现在是:

(this|Something|Second|Keyword1.*Keyword2|Stuff|One)

并匹配缺失的大小写:

                                         Description                                Matched
0                                     Something Here                              Something
1                                      Second Item 7                                 Second
2                                    Something There                              Something
3  strng KEYWORD1 moreJARGON 06/0 010 KEYWORD2 an...  KEYWORD1 moreJARGON 06/0 010 KEYWORD2
4                                      Second Item 7                                 Second
5                                    Even More Stuff                                  Stuff

【讨论】:

谢谢!就是这样。有没有机会知道为什么 df1['col_Next_toMatched'] = df1['Description'].str.extract(regstr, flags=re.IGNORECASE, expand=False).map(dfKeys.set_index('keys')['col_Next_toKeys'].to_dict()).fillna('') 可以用于除通配符键之外的所有内容? @lodestar08 您能否更新您的帖子以显示dfKeys 是什么? 我已经更新了帖子 - 但不确定是否更清楚

以上是关于Python Pandas Regex:在列中搜索带有通配符的字符串并返回匹配项[重复]的主要内容,如果未能解决你的问题,请参考以下文章

在列中查找字母并提取包含特定字母的行

使用 Pandas 在列中循环字典

如何使用 Pandas 在列中添加值的超链接?

使用 Pandas 读取 CSV 时如何在列中保持前导零?

Pandas:通过在列中查找子字符串改进算法

pandas中的SQL查询:根据其他列的组合在列中连接多行