Поиск текста, содержащегося в любой строке панды DataFrame - PullRequest
0 голосов
/ 07 мая 2019

У меня есть следующее DataFrame

pred[['right_context', 'PERC']]
Out[247]: 
                          right_context      PERC
0  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  0.000197
1                San Pedro xxxxxxxxxxxx  0.572630
2          zxxxxxxxxxxxxxxxxxxxxxxxxxxx  0.572630
3             de San Pedro Este parcela  0.572630
4   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  0.035577

И у меня есть еще одна панда DataFrame с именем _direcciones с реальными адресами:

388427          SAN PEDRO              1
388428     bbbbbbbbbbbbbbbbbbbbbb      1
388429        yyyyyyyyyyyyyyyyyyy      1
[388430 rows x 2 columns]

Мне нужно как-то найти, если какой-то адрес в _direcciones содержится в первом DataFrame. Я сделал следующее:

[True for y in pred.right_context 
   for x in _direcciones.entity_content 
   if re.match(r'^%s\b' %x, y, flags=re.I)]

Но это очень медленно, и, что более важно, я хотел бы добавить к первому DataFrame столбец со значениями True|False, если адрес был найден, но в настоящее время я не могу, потому что приведенный выше код может вернуть любое количество строк, не точно 5, как мне нужно для первого DataFrame.

Примерно так:

pred[['right_context', 'PERC']]
Out[247]: 
                          right_context      PERC    found?
0  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  0.000197       F
1                San Pedro xxxxxxxxxxxx  0.572630       T
2          zxxxxxxxxxxxxxxxxxxxxxxxxxxx  0.572630       F
3             de San Pedro Este parcela  0.572630       T
4   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  0.035577       F

Обновление

Спасибо за ответы, но я сталкиваюсь с той же проблемой, _direcciones настолько велика, что вероятность того, что в pred.right_context существует слово в _direcciones, очень высока. Например:

1033 * пред * 0 URBANA. OBRA NUEVA TERMINADA. Urbana 1 San Pedro número xxxxx Здесь я ищу San Pedro, но оба San Pedro и URBANA находятся в _direcciones, поэтому обе строки будут True. Я не знаю, как подойти к проблеме.

Ответы [ 3 ]

2 голосов
/ 07 мая 2019

Series.str.contains & str.upper

Вы не можете использовать Series.str.contains и объединить столбец в _direcciones как одну строку с | в качествеSeperator.

Также важно отметить, что мы должны привести строку данных pred к верхнему регистру с помощью str.upper

pred['found?'] = pred['right_context'].str.upper()\
                                      .str.contains('|'.join(_direcciones['Address']))

print(pred)
                          right_context      PERC  found?
0  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  0.000197   False
1                San Pedro xxxxxxxxxxxx  0.572630    True
2          zxxxxxxxxxxxxxxxxxxxxxxxxxxx  0.572630   False
3             de San Pedro Este parcela  0.572630    True
4   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  0.035577   False

Только получить T & F

pred['found?'] = pred['right_context'].str.upper()\
                                      .str.contains('|'.join(_direcciones['Address']))\
                                      .astype(str).str[:1]

print(pred)
                          right_context      PERC found?
0  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  0.000197      F
1                San Pedro xxxxxxxxxxxx  0.572630      T
2          zxxxxxxxxxxxxxxxxxxxxxxxxxxx  0.572630      F
3             de San Pedro Este parcela  0.572630      T
4   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  0.035577      F

Выход '|'.join

'|'.join(_direcciones['Address'])

'SAN PEDRO|bbbbbbbbbbbbbbbbbbbbbb|yyyyyyyyyyyyyyyyyyy'
1 голос
/ 07 мая 2019

Попробуйте этот подход, кажется, работает для меня, используя небольшую выборку данных:

from pprint import pprint
import numpy as np
import pandas as pd

def main():
    #Sample Data
    df_right = pd.DataFrame({'right_context':'San Jose, San Pedro, San Pedro Este, Santani, Honolulu'.split(','),
                       'PERC': np.arange(5)})
    directions = pd.DataFrame({'address':'SAN PEDRO, Djiloboji, Torres'.split(','),
                       'value': np.arange(3)})
    # generate found result
    found=(df_right['right_context'].str.contains('San Pedro', case=False)).tolist()
    # Insert into original dataframe
    df_right.insert(2,"found",found)
    pprint(df_right)

if __name__== "__main__":
    main()

Выход:

     right_context  PERC  found
0         San Jose     0  False
1        San Pedro     1   True
2   San Pedro Este     2   True
3          Santani     3  False
4         Honolulu     4  False
1 голос
/ 07 мая 2019

Используйте границы слов со всеми строками, соединенными | с Series.str.contains и параметром case=False:

pat = '|'.join(r"\b{}\b".format(x) for x in _direcciones['entity_content'])
pred['found?'] = pred['right_context'].str.contains(pat, case=False)
print (pred)
                          right_context      PERC  found?
0  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  0.000197   False
1                San Pedro xxxxxxxxxxxx  0.572630    True
2          zxxxxxxxxxxxxxxxxxxxxxxxxxxx  0.572630   False
3             de San Pedro Este parcela  0.572630    True
4   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  0.035577   False

При необходимости добавьте numpy.where:

pat = '|'.join(r"\b{}\b".format(x) for x in _direcciones['entity_content'])
pred['found?'] = np.where(pred['right_context'].str.contains(pat, case=False), 'T', 'F')
print (pred)
                          right_context      PERC found?
0  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  0.000197      F
1                San Pedro xxxxxxxxxxxx  0.572630      T
2          zxxxxxxxxxxxxxxxxxxxxxxxxxxx  0.572630      F
3             de San Pedro Este parcela  0.572630      T
4   xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  0.035577      F
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...