use*_*097 4 python regex r regex-group pandas
出于所有目的和目的,我是Python用户,每天使用Pandas库。正则表达式中的命名捕获组非常有用。因此,例如,提取特定单词或短语的出现并在数据帧的新列中生成结果的串联字符串是相对琐碎的。下面是如何实现此目的的示例:
import numpy as np
import pandas as pd
import re
myDF = pd.DataFrame(['Here is some text',
'We all love TEXT',
'Where is the TXT or txt textfile',
'Words and words',
'Just a few works',
'See the text',
'both words and text'],columns=['origText'])
print("Original dataframe\n------------------")
print(myDF)
# Define regex to find occurrences of 'text' or 'word' as separate named groups
myRegex = """(?P<textOcc>t[e]?xt)|(?P<wordOcc>word)"""
myCompiledRegex = re.compile(myRegex,flags=re.I|re.X)
# Extract all occurrences of 'text' or 'word'
myMatchesDF = myDF['origText'].str.extractall(myCompiledRegex)
print("\nDataframe of matches (with multi-index)\n--------------------")
print(myMatchesDF)
# Collapse resulting multi-index dataframe into single rows with concatenated fields
myConcatMatchesDF = myMatchesDF.groupby(level = 0).agg(lambda x: '///'.join(x.fillna('')))
myConcatMatchesDF = myConcatMatchesDF.replace(to_replace = "^/+|/+$",value = "",regex = True) # Remove '///' at start and end of strings
print("\nCollapsed and concatenated matches\n----------------------------------")
print(myConcatMatchesDF)
myDF = myDF.join(myConcatMatchesDF)
print("\nFinal joined dataframe\n----------------------")
print(myDF)
Run Code Online (Sandbox Code Playgroud)
这将产生以下输出:
Original dataframe
------------------
origText
0 Here is some text
1 We all love TEXT
2 Where is the TXT or txt textfile
3 Words and words
4 Just a few works
5 See the text
6 both words and text
Dataframe of matches (with multi-index)
--------------------
textOcc wordOcc
match
0 0 text NaN
1 0 TEXT NaN
2 0 TXT NaN
1 txt NaN
2 text NaN
3 0 NaN Word
1 NaN word
5 0 text NaN
6 0 NaN word
1 text NaN
Collapsed and concatenated matches
----------------------------------
textOcc wordOcc
0 text
1 TEXT
2 TXT///txt///text
3 Word///word
5 text
6 text word
Final joined dataframe
----------------------
origText textOcc wordOcc
0 Here is some text text
1 We all love TEXT TEXT
2 Where is the TXT or txt textfile TXT///txt///text
3 Words and words Word///word
4 Just a few works NaN NaN
5 See the text text
6 both words and text text word
Run Code Online (Sandbox Code Playgroud)
我已经印制了每个阶段,以使其易于遵循。
问题是,我可以在R中做类似的事情吗?我已经在网上搜索了,但是找不到任何描述命名组用法的信息(尽管我是R新手,所以可能正在搜索错误的库或描述性术语)。
我已经能够识别出包含一个或多个匹配项的项目,但是看不到如何提取特定匹配项或如何利用命名组。到目前为止,我的代码(使用与上面的Python示例相同的数据框和正则表达式)是:
origText = c('Here is some text','We all love TEXT','Where is the TXT or txt textfile','Words and words','Just a few works','See the text','both words and text')
myDF = data.frame(origText)
myRegex = "(?P<textOcc>t[e]?xt)|(?P<wordOcc>word)"
myMatches = grep(myRegex,myDF$origText,perl=TRUE,value=TRUE,ignore.case=TRUE)
myMatches
[1] "Here is some text" "We all love TEXT" "Where is the TXT or txt textfile" "Words and words"
[5] "See the text" "both words and text"
myMatchesRow = grep(myRegex,myDF$origText,perl=TRUE,value=FALSE,ignore.case=TRUE)
myMatchesRow
[1] 1 2 3 4 6 7
Run Code Online (Sandbox Code Playgroud)
正则表达式似乎正在运行,并且正确的行被标识为包含匹配项(即,上面示例中的第5行除外)。但是,我的问题是,是否可以产生与Python产生的输出相似的输出,在Python中提取特定的匹配项,并在使用正则表达式中包含的组名命名的数据帧的新列中列出?
Base R确实捕获了有关名称的信息,但是它没有一个很好的帮助来按名称提取名称。我写了一个包装器,称为regcapturedmatches。您可以将其与
myRegex = "(?<textOcc>t[e]?xt)|(?<wordOcc>word)"
m<-regexpr(myRegex, origText, perl=T, ignore.case=T)
regcapturedmatches(origText,m)
Run Code Online (Sandbox Code Playgroud)
哪个返回
textOcc wordOcc
[1,] "text" ""
[2,] "TEXT" ""
[3,] "TXT" ""
[4,] "" "Word"
[5,] "" ""
[6,] "text" ""
[7,] "" "word"
Run Code Online (Sandbox Code Playgroud)