2016-03-11 3 views
4

У меня есть две строки столбцы в моем панды набореКак сравнить две строковые переменные в пандах?

name1  name2 
John Doe John Doe 
AleX T Franz K 

и мне нужно, чтобы проверить, равен ли name1name2. Наивный способ я использую сейчас с помощью простой маски

mask=df.name1==df.name2

Но проблема в том, что там может быть неверной маркировкой строки (таким образом, что не является предсказуемым - данные слишком большие), которые препятствуют точной совпадение.

Например, «John Doe» и «John Doe» не совпадают. Конечно, я обрезал, опустил свои струны, но другие возможности остаются.

Одна из идей заключается в том, будет ли name1 содержать в name2. Но, похоже, я не могу использовать str.contains с другой переменной в качестве аргумента. Любые другие идеи?

Большое спасибо!

EDIT: использование isin дает нечувствительные результаты. Пример

test = pd.DataFrame({'A': ["john doe", " john doe", 'John'], 'B': [' john doe', 'eddie murphy', 'batman']}) 

test 
Out[6]: 
      A    B 
0 john doe  john doe 
1 john doe eddie murphy 
2  John  batman 

test['A'].isin(test['B']) 
Out[7]: 
0 False 
1  True 
2 False 
Name: A, dtype: bool 
+0

Привет @edchum это а не дубликат вопроса, который вы упомянули. –

+1

Итак, вы после чего-то вроде 'df ['name1']. Str.lower() == df ['name2']. Str.lower()'? – EdChum

+0

не очень, потому что я считаю, что идеальное равенство порождает слишком много ложных негативов в данных. проверка того, содержится ли имя1 где-то в имени2, кажется более подходящим –

ответ

4

Я думаю, что вы можете использовать str.lower и str.replace с произвольным пробельных s/+:

test = pd.DataFrame({'A': ["john doe", " john doe", 'John'], 
        'B': [' john doe', 'eddie murphy', 'batman']}) 

print test['A'].str.lower().str.replace('s/+',"") == 
     test['B'].str.strip().str.replace('s/+',"") 


0  True 
1 False 
2 False 
dtype: bool 
+0

Я не понимаю, почему это дает мне нечувствительные результаты. см. мой обновленный вопрос –

+0

у вас есть идеи, что происходит с 'isin' здесь? –

+1

Извините, я был в автономном режиме. – jezrael

1

То, что вы хотите, это строка расстояние на основе редактирования усилий distance(s1, s2), который является тем, что мы называем edit distance of strings. После того, как вы определяете эту функцию в пространстве имен вы можете сделать:

df['distance_s'] = df.apply(lambda r: distance(r['name1'], r['name2'])) 
filtered = df[df['distance_s'] < eps] # you define eps 

От поиска Google, следующий придумал:

https://pypi.python.org/pypi/editdistance

Это динамическая задача программирования, так что вы можете бросить вызов себе написав свой собственный тоже. Однако это может быть не так эффективно.

1

Вы можете использовать difflib вычислить расстояние,

import difflib as dfl 
dfl.SequenceMatcher(None,'John Doe', 'John doe').ratio() 

редактирования: интеграция с панды:

import pandas as pd 
import difflib as dfl 
df = pd.DataFrame({'A': ["john doe", " john doe", 'John'], 'B': [' john doe', 'eddie murphy', 'batman']}) 
df['VAR1'] = df.apply(lambda x : dfl.SequenceMatcher(None, x['A'], x['B']).ratio(),axis=1) 
+0

ли это интегрируется с рамками данных pandas? –

+1

решение отредактировано – steboc

2

strip пространства и lower случае:

In [414]: 
test['A'].str.strip().str.lower() == test['B'].str.strip().str.lower() 

Out[414]: 
0  True 
1 False 
2 False 
dtype: bool 
Смежные вопросы