【问题标题】:how to compare two string variables in pandas?如何比较熊猫中的两个字符串变量?
【发布时间】:2016-06-26 17:41:36
【问题描述】:

我的 Pandas 数据集中有两个字符串列

name1     name2
John Doe  John Doe
AleX T    Franz K

我需要检查name1 是否等于name2。 我现在使用的幼稚方式是使用简单的掩码

mask=df.name1==df.name2

但问题是可能存在错误标记的字符串(以一种不可预测的方式 - 数据太大),从而阻止了精确匹配的发生。

例如,“John Doe”和“John Doe”不匹配。当然,我修剪了小写的字符串,但其他可能性仍然存在。

一个想法是查看name1 是否包含在name2 中。但似乎我不能将str.contains 与另一个变量一起用作参数。还有其他想法吗?

非常感谢!

编辑:使用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

【问题讨论】:

  • 嗨@edchum,这不是你提到的问题的重复。
  • 那么你在追求df['name1'].str.lower() == df['name2'].str.lower()这样的东西吗?
  • 不是真的,因为我相信完全相等会在数据中产生太多的假阴性。检查 name1 是否包含在 name2 的某处似乎更合适
  • 我认为在这种情况下你应该strip空格和lower这种情况,看我的回答
  • 如果您建议使用in 之类的东西,那么您必须使用apply 来执行此操作,例如df.apply(lambda x: x['A'].strip().lower() in x['B'].strip().lower(), axis=1)

标签: python pandas string dataframe


【解决方案1】:

您可以使用 difflib 计算距离

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

编辑:与 Pandas 的集成:

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)

【讨论】:

  • 这是否与 pandas 数据框集成?
【解决方案2】:

我认为您可以将str.lowerstr.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

【讨论】:

  • 我不明白为什么这会给我带来毫无意义的结果。请查看我更新的问题
  • 你知道isin这里发生了什么吗?
  • 对不起,我离线了。
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    您想要的是基于编辑工作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

    这是一个动态规划问题,因此您也可以通过编写自己的代码来挑战自己。不过可能效率不高。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-16
      • 2015-05-22
      • 2014-04-21
      • 2022-11-28
      • 2020-03-23
      • 1970-01-01
      • 2017-03-02
      • 2019-12-28
      相关资源
      最近更新 更多