Извлечь совпадающие позиции в строку - PullRequest
0 голосов
/ 04 января 2019

Я могу легко извлечь начальную / конечную позиции строк в тексте, используя re.finditer, что приводит к кортежу начальных / конечных позиций совпадений.

s1 = 'the quick quick brown fox jumps over the lazy dog'
s2 = 'Pack my box with five dozen liquor jugs'
s3 = 'How razorback jumping frogs can level six piqued gymnasts'

r1 = '(quick|fox|dog)'
r2 = '(box|five|jugs)'
r3 = '(frogs|six)'

t = [(s1,r1), (s2,r2), (s3,r3)]


for e in t:
    print([(f.start(), f.end()) for f in re.finditer(e[1],e[0])])

[(4, 9), (10, 15), (22, 25), (46, 49)]
[(8, 11), (17, 21), (35, 39)]
[(22, 27), (38, 41)]

У меня есть DataFrame с текстом в одном столбце и регулярным выражением в другом

s = pd.DataFrame(data={'re':[r1,r2,r3], 'text':[s1,s2,s3]})

    re              text
0   (quick|fox|dog) the quick quick brown fox jumps over the lazy dog
1   (box|five|jugs) Pack my box with five dozen liquor jugs
2   (frogs|six)     How razorback jumping frogs can level six piqu...

Я хотел бы извлечь ту же информацию о положении в объект Series, используя методы pandas.str, но метод finditer отсутствует (в пандах 0.23).

Есть ли способ сделать это, не прибегая к циклу for-each?

1 Ответ

0 голосов
/ 04 января 2019

Расширяя комментарии @ user3483203, вы можете сделать следующее, используя список :

import re
import pandas as pd

s1 = 'the quick quick brown fox jumps over the lazy dog'
s2 = 'Pack my box with five dozen liquor jugs'
s3 = 'How razorback jumping frogs can level six piqued gymnasts'

r1 = '(quick|fox|dog)'
r2 = '(box|five|jugs)'
r3 = '(frogs|six)'

t = [(s1,r1), (s2,r2), (s3,r3)]

s = pd.DataFrame(data={'re':[r1,r2,r3], 'text':[s1,s2,s3]})

result = pd.Series([[(f.start(), f.end()) for f in re.finditer(p, s)] for p, s in zip(s.re, s.text)])
print(result)

выход

0    [(4, 9), (10, 15), (22, 25), (46, 49)]
1             [(8, 11), (17, 21), (35, 39)]
2                      [(22, 27), (38, 41)]
dtype: object

Другой альтернативой будет использование apply , но я считаю, что это может быть медленнее:

def finditer(p, s):
    return [(f.start(), f.end()) for f in re.finditer(p, s)]


result = s[['re', 'text']].apply(lambda x: finditer(x[0], x[1]), axis=1)
print(result)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...