pandas 和 "re" - 搜索全部和部分字符串
pandas and "re" - search for total and partial strings
这是 的扩展问题。我想在字符串中搜索全部和部分字符串,例如以下关键字 Series "w":
rigour*
*demeanour*
centre*
*arbour
fulfil
这显然意味着我想搜索像 rigor 和 rigour 这样的词s, endemeanour 和 demeanour s、center and centres、harbour and arbour,然后fulfil。所以我的关键字列表是要查找的完整字符串和部分字符串的混合。我想在此 DataFrame "df":
上应用搜索
ID;name
01;rigour
02;rigours
03;endemeanour
04;endemeanours
05;centre
06;centres
07;encentre
08;fulfil
09;fulfill
10;harbour
11;arbour
12;harbours
到目前为止我尝试的是以下内容:
r = re.compile(r'.*({}).*'.format('|'.join(w.values)), re.IGNORECASE)
然后我构建了一个掩码来过滤 DataFrame:
mask = [m.group(1) if m else None for m in map(r.search, df['Tweet'])]
为了获得包含找到的关键字的新列:
df['keyword'] = mask
我期待的是以下结果 DataFrame:
ID;name;keyword
01;rigour;rigour
02;rigours;rigour
03;endemeanour;demeanour
04;endemeanours;demeanour
05;centre;centre
06;centres;centre
07;encentre;None
08;fulfil;fulfil
09;fulfill;None
10;harbour;arbour
11;arbour;arbour
12;harbours;None
这可以使用不带 * 的 w 列表。现在,为了 运行 re.compile 正确发挥作用,我在格式化关键字 w List of words with the * conditions 时遇到了几个问题。
任何帮助将不胜感激。
您的输入序列 w
似乎需要调整才能用作正则表达式模式,如下所示:
rigour.*
.*demeanour.*
centre.*
\b.*arbour\b
\bfulfil\b
请注意,正则表达式中的 *
用于处理它本身不起作用的内容。这意味着后面的任何内容都可以重复0次或多次。
另请注意,fulfil
是 fulfill
的一部分,如果您想进行严格匹配,则需要告诉正则表达式。例如,通过使用 'word separator' - \b
- 它只会捕获整个字符串。
以下是您的正则表达式为您提供所需结果的方式:
s = '({})'.format('|'.join(w.values))
r = re.compile(s, re.IGNORECASE)
r
re.compile(r'(rigour.*|.*demeanour.*|centre*|\b.*arbour\b|\bfulfil\b)', re.IGNORECASE)
您的替换代码可以使用 pandas .where
方法完成,如下所示:
df['keyword'] = df.name.where(df.name.str.match(r), None)
df
ID name keyword
0 1 rigour rigour
1 2 rigours rigours
2 3 endemeanour endemeanour
3 4 endemeanours endemeanours
4 5 centre centre
5 6 centres centres
6 7 encentre None
7 8 fulfil fulfil
8 9 fulfill None
9 10 harbour harbour
10 11 arbour arbour
11 12 harbours None
这是
rigour*
*demeanour*
centre*
*arbour
fulfil
这显然意味着我想搜索像 rigor 和 rigour 这样的词s, endemeanour 和 demeanour s、center and centres、harbour and arbour,然后fulfil。所以我的关键字列表是要查找的完整字符串和部分字符串的混合。我想在此 DataFrame "df":
上应用搜索ID;name
01;rigour
02;rigours
03;endemeanour
04;endemeanours
05;centre
06;centres
07;encentre
08;fulfil
09;fulfill
10;harbour
11;arbour
12;harbours
到目前为止我尝试的是以下内容:
r = re.compile(r'.*({}).*'.format('|'.join(w.values)), re.IGNORECASE)
然后我构建了一个掩码来过滤 DataFrame:
mask = [m.group(1) if m else None for m in map(r.search, df['Tweet'])]
为了获得包含找到的关键字的新列:
df['keyword'] = mask
我期待的是以下结果 DataFrame:
ID;name;keyword
01;rigour;rigour
02;rigours;rigour
03;endemeanour;demeanour
04;endemeanours;demeanour
05;centre;centre
06;centres;centre
07;encentre;None
08;fulfil;fulfil
09;fulfill;None
10;harbour;arbour
11;arbour;arbour
12;harbours;None
这可以使用不带 * 的 w 列表。现在,为了 运行 re.compile 正确发挥作用,我在格式化关键字 w List of words with the * conditions 时遇到了几个问题。
任何帮助将不胜感激。
您的输入序列 w
似乎需要调整才能用作正则表达式模式,如下所示:
rigour.*
.*demeanour.*
centre.*
\b.*arbour\b
\bfulfil\b
请注意,正则表达式中的 *
用于处理它本身不起作用的内容。这意味着后面的任何内容都可以重复0次或多次。
另请注意,fulfil
是 fulfill
的一部分,如果您想进行严格匹配,则需要告诉正则表达式。例如,通过使用 'word separator' - \b
- 它只会捕获整个字符串。
以下是您的正则表达式为您提供所需结果的方式:
s = '({})'.format('|'.join(w.values))
r = re.compile(s, re.IGNORECASE)
r
re.compile(r'(rigour.*|.*demeanour.*|centre*|\b.*arbour\b|\bfulfil\b)', re.IGNORECASE)
您的替换代码可以使用 pandas .where
方法完成,如下所示:
df['keyword'] = df.name.where(df.name.str.match(r), None)
df
ID name keyword
0 1 rigour rigour
1 2 rigours rigours
2 3 endemeanour endemeanour
3 4 endemeanours endemeanours
4 5 centre centre
5 6 centres centres
6 7 encentre None
7 8 fulfil fulfil
8 9 fulfill None
9 10 harbour harbour
10 11 arbour arbour
11 12 harbours None