首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将一列df中的字符串值选中为具有多个条件的另一列df。

将一列df中的字符串值选中为具有多个条件的另一列df。
EN

Stack Overflow用户
提问于 2021-03-30 11:15:18
回答 2查看 77关注 0票数 0

我有两个数据帧:

代码语言:javascript
运行
复制
import pandas as pd

first_df = pd.DataFrame({'Full Name': ['Mulligan Nick & Mary', 'Tsang S C', 'Hattie J A C '],
                         'Address': ['270 Claude Road', '13 Sunnyridge Place', '18A Empire Road']})

second_df = pd.DataFrame({'Owner' : ['David James Mulligan', 'Brenda Joy Mulligan ', 'Helen Kwok Hattie'],
                          'Add Match': ['19 Dexter Avenue', 'Claude Road ', 'Building NO 512']})

是否只将Full Name列中的第一个字符串与Owner列中的最后一个字符串匹配。

如果有匹配,那么我想比较AddressAdd match,看看是否有类似的值。如果第一个条件通过,但第二个条件失败,则不会将其添加到新的数据帧中。

使用左联接的结果如下:

代码语言:javascript
运行
复制
new_df = first_df.merge(second_df, how='left', left_on = ['Full Name', 'Address'], right_on = ['Owner', 'Add Match'])
print(new_df.head())

              Full Name              Address Owner Add Match
0  Mulligan Nick & Mary      270 Claude Road   NaN       NaN
1             Tsang S C  13 Sunnyridge Place   NaN       NaN
2         Hattie J A C       18A Empire Road   NaN       NaN

然而,所需的输出看起来更像这样:

代码语言:javascript
运行
复制
new_df

Name                 Address
----                 --------
Brenda Joy Mulligan  Claude Road
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-03-30 14:16:51

受此answer的启发,您可以使用类似的解决方案。

TL;DR

代码语言:javascript
运行
复制
first_df[['last_name', 'start_name']] = first_df['Full Name'].str.split(' ', 1, expand=True)
second_df['last_name'] = second_df['Owner'].str.split(' ').str[-1]
df_final = first_df.merge(second_df, how='inner', left_on=['last_name'], right_on=['last_name'])
address_matches = df_final.apply(lambda x: True if difflib.get_close_matches(x['Address'], [x['Add Match']], n=1, cutoff=0.8) else False, axis=1)
df_final = df_final[address_matches].drop(columns=['last_name', 'start_name', 'Full Name', 'Address']).rename(columns={'Owner':'Name', 'Add Match': 'Address'})

分步

最初,您提取您想要的姓氏密钥。

代码语言:javascript
运行
复制
first_df[['last_name', 'start_name']] = first_df['Full Name'].str.split(' ', 1, expand=True)
second_df['last_name'] = second_df['Owner'].str.split(' ').str[-1]

PS:,我们在这里使用来自熊猫/numpy组合体的内置字符串方法,给出了您的说明。但是,如果它更适合您,您也可以应用下面显示的地址部分的相似方法(例如,difflib.get_close_matches)。

接下来,执行这些数据文件的内部连接,以匹配last_name键。

代码语言:javascript
运行
复制
df_temp = first_df.merge(second_df, how='inner', left_on=['last_name'], right_on=['last_name'])

然后,应用具有所需相似性的difflib.get_close_matches (我使用了cutoff=0.8,因为在此值之上没有返回值)方法来标记哪些行包含匹配,然后只得到所需的行。

代码语言:javascript
运行
复制
matches_mask = df_final.apply(lambda x: True if difflib.get_close_matches(x['Address'], [x['Add Match']], n=1, cutoff=0.8) else False, axis=1)
df_final = df_final[matches_mask].drop(columns=['last_name', 'start_name'])
代码语言:javascript
运行
复制
Full Name               Address             Owner                   Add Match

Mulligan Nick & Mary    270 Claude Road     Brenda Joy Mulligan     Claude Road

最后,为了匹配在问题末尾发布的结果的格式,需要删除或重命名一些列。

代码语言:javascript
运行
复制
df_final.drop(columns=['Full Name', 'Address']).rename(columns={'Owner':'Name', 'Add Match': 'Address'})
代码语言:javascript
运行
复制
Owner                   Add Match

Brenda Joy Mulligan     Claude Road
票数 1
EN

Stack Overflow用户

发布于 2021-03-30 11:51:51

您可以利用Python库中的difflib模块来查找不同列之间的相似之处。例如,可以定义以下函数:

代码语言:javascript
运行
复制
from difflib import SequenceMatcher

def compare_df(left, right, col: str):
    left[f"{col}_match_ratio"] = 0

    for value in left[col]:
        best_ratio = 0
        for other in right[col]:
            result = SequenceMatcher(None, str(value), str(other)).ratio()
            if result > best_ratio:
                best_ratio = result
        left.loc[left[col] == value, f"{col}_match_ratio"] = round(best_ratio, 2)

然后:

您只需确保要比较的列在您称为second_df

  • finally,(first_df,second_df,"Owner")的dfs

  • (first_df,second_df,“Owner”)中具有相同的名称,这将向中添加"Owner_match_ratio“列,从而在所需的最小匹配比(例如,70%)上过滤第二个df,如:new_df = second_df.loc[second_df["Owner_match_ratio"] > 0.7, :]
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66869963

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档