在我的一个小项目中,我遇到了以下问题.我有一个很大的数据集,其中一些字符串值意外地没有正确写入.我的目标是编写一个函数,确保在循环中查找所有看起来非常相似的名称(0.75),并且将获得相同的名称.在下面的示例中,我描述了数据的一个子集,其中"Bob Fisherman"、"Bob Felony"和"Bob Haris"是正确的名称.我希望将拼错的名字更改为上面的名称,如果它们匹配的话

以下是数据帧的一个子集:

columns = ["Name", "Type","Amount", "Year"]
data = [("Bob fisherman", "Income", 150, 2022), ("Bob fisherman","Income", 100, 2021), ("Bob Felony", "Income", 100, 2021), ("Bob Felany", "Expense", 50, 2022), ("Bob Haris", "Expense", 100, 2022), ("Bob Disherman", "Expense", 100, 2021)]
data = spark.createDataFrame(data).toDF(*columns)

所以最终我想要这样的东西:

Name Type Amount Year
Bob Fisherman Income 150 2022
Bob Fisherman Income 100 2021
Bob Felony Income 100 2021
Bob Felany Income 50 2022
Bob Haris Income 100 2022
Bob Felony Income 100 2021
Bob Fisherman Income 100 2022

在本例中,它只涉及Bob.但是在总的样本中,我有更多的名字,所以使用预先指定的列表不会很不幸地减少它.

我试着从下面的问题中获得一些灵感,但似乎没有奏效: Replace similar strings in a column with the same string

推荐答案

带有以下玩具数据帧:

import pandas as pd

df = pd.DataFrame(
    [
        ("Bob Fisherman", "Income", 150, 2022),
        ("Bob Heris", "Income", 100, 2021),
        ("Bob Felony", "Income", 100, 2021),
        ("Bob Felany", "Expense", 50, 2022),
        ("Bob Haris", "Expense", 100, 2022),
        ("Bob Disherman", "Expense", 100, 2021),
    ],
    columns=["Name", "Type", "Amount", "Year"],
)
print(df)
# Output
            Name     Type  Amount  Year
0  Bob Fisherman   Income     150  2022
1      Bob Heris   Income     100  2021
2     Bob Felony   Income     100  2021
3     Bob Felany  Expense      50  2022
4      Bob Haris  Expense     100  2022
5  Bob Disherman  Expense     100  2021

以下是使用来自Python标准库difflib模块的SequenceMatcher个类的帮助来完成此操作的一种方法:

from difflib import SequenceMatcher

def similar(a, b):
    """Get similarity ratio between a and b.

    Args:
        a: value.
        b: other value.

    Returns:
        Similatity ratio.

    """
    return SequenceMatcher(None, a, b).ratio()


def replace_similar_values(df, col, value):
    """Main helper function.

    Args:
        df: target dataframe.
        col: target column.
        value: value to use for replacement.

    Returns:
        Modified dataframe.

    """
    df = df.assign(
        Match=df[col].map(
            lambda x: max(
                [similar(x, value)],
                key=lambda x: x if x != 1 else 0,
            )
        )
    )
    df["Name"] = df.apply(lambda x: value if x["Match"] >= 0.8 else x["Name"], axis=1)
    df = df.drop(columns="Match")
    return df

然后:

correct_names = ["Bob Fisherman", "Bob Felony", "Bob Haris"]

for correct_name in correct_names:
    df = replace_similar_values(df, "Name", correct_name)

print(df)
# Output
            Name     Type  Amount  Year
0  Bob Fisherman   Income     150  2022
1      Bob Haris   Income     100  2021
2     Bob Felony   Income     100  2021
3     Bob Felony  Expense      50  2022
4      Bob Haris  Expense     100  2022
5  Bob Fisherman  Expense     100  2021

Python相关问答推荐

如何记录脚本输出

"使用odbc_connect(raw)连接字符串登录失败;可用于pyodbc"

导入...从...混乱

如何根据一列的值有条件地 Select 前N个组,然后按两列分组?

pandas在第1列的id,第2列的标题,第3列的值,第3列的值?

删除marplotlib条形图上的底边

AES—256—CBC加密在Python和PHP中返回不同的结果,HELPPP

在Admin中显示从ManyToMany通过模型的筛选结果

ModuleNotFoundError:没有模块名为x时try 运行我的代码''

Flask运行时无法在Python中打印到控制台

pandas fill和bfill基于另一列中的条件

如何在Python中将超链接添加到PDF中每个页面的顶部?

如何使用大量常量优化代码?

高效生成累积式三角矩阵

使用Scikit的ValueError-了解

Python:在cmd中添加参数时的语法

为什么这个正则表达式没有捕获最后一次输入?

Django REST框架+Django Channel->;[Errno 111]连接调用失败(';127.0.0.1';,6379)

如果init被重载,如何输入提示一个基于init的函数的返回类型

在动态创建带有图像的按钮时遇到问题