pandas 如何通过比较里面字符串的相似性来合并csv的两个表

disho6za  于 2023-05-05  发布在  其他
关注(0)|答案(1)|浏览(175)

我想通过使用fuzzy-wuzzy包中的levenshtein比较字符串的相似性来将两个DF合并为一个。我需要删除字符串之间的符号或空格。如果DF 1与DF 2中的任何数据都不匹配,则它将保留在表中,反之亦然。我做了一件简单的事情,就像这样:

from fuzzywuzzy import fuzz

# Define the two input DataFrames
df1 = pd.DataFrame({
    'name': ['John', 'Anna', 'Mike', 'Samantha'],
    'age': [25, 32, 18, 45]
})
df2 = pd.DataFrame({
    'username': ['j0hn_d03', 'anna_jones', 'mike_smith', 'sam_567'],
    'age': [28, 30, 20, 43]
})

# Remove symbols and spaces in the name and username columns
df1['name'] = df1['name'].str.replace(r'\W', '').str.lower()
df2['username'] = df2['username'].str.replace(r'\W', '').str.lower()

# Create an empty DataFrame to store the merged results
merged_df = pd.DataFrame(columns=['name', 'age', 'username', 'match_ratio'])

# Loop over the rows of the first DataFrame and compare them to the second DataFrame
for i, row1 in df1.iterrows():
    best_match = None
    best_ratio = 0
    for j, row2 in df2.iterrows():
        ratio = fuzz.ratio(row1['name'], row2['username'])
        if ratio > best_ratio:
            best_ratio = ratio
            best_match = row2
    if best_match is not None:
        merged_df = merged_df.append({
            'name': row1['name'],
            'age': row1['age'],
            'username': best_match['username'],
            'match_ratio': best_ratio
        }, ignore_index=True)
    else:
        merged_df = merged_df.append({
            'name': row1['name'],
            'age': row1['age'],
            'username': None,
            'match_ratio': 0
        }, ignore_index=True)

# Loop over the rows of the second DataFrame and add the non-matching rows to the merged DataFrame
for i, row2 in df2.iterrows():
    if not merged_df['username'].str.contains(row2['username']).any():
        merged_df = merged_df.append({
            'name': None,
            'age': row2['age'],
            'username': row2['username'],
            'match_ratio': 0
        }, ignore_index=True)

# Convert the match_ratio column to integers and sort the merged DataFrame by age
merged_df['match_ratio'] = merged_df['match_ratio'].astype(int)
merged_df = merged_df.sort_values(by='age').reset_index(drop=True)

但是我有1000个不同的名字,所以我不能手动检查错误,我也有其他的特征来帮助分类。有没有可能使用机器学习来提高准确性,或者使用其他方法来让数据更容易被Python理解,从而进行区分?
编辑:我的意思是,在我的“名字”一栏中有很多约翰,其中一些代表不同的人,但有些是相同的,只是不同的条目有不同的特点。姓名:“约翰”,年龄:25,bag_colour:“黑”,另一个,用户名:'j0hn_d01',年龄:25,bag_colour:'Blue'。在这种情况下,在我合并的csv中应该有两个John,因为同一个学生有两个行李是不合逻辑的。所以Python应该基于所有特征的组合,而不是仅仅一列。

qco9c6ql

qco9c6ql1#

我会做一个完整的外部合并,然后使用lambda更干净地检查每一行。

df3 = pd.merge(df1.assign(key=1), df2.assign(key=1), on='key').drop('key', axis=1)
df3['match_ratio'] = df3.apply(lambda x: fuzz.ratio(x['name'], x['username']), axis=1)

print(df3)
        name  age_x    username  age_y  match_ratio
0       John     25    j0hn_d03     28           33
1       John     25  anna_jones     30           29
2       John     25  mike_smith     20           14
3       John     25     sam_567     43            0
4       Anna     32    j0hn_d03     28           17
5       Anna     32  anna_jones     30           43
6       Anna     32  mike_smith     20            0
7       Anna     32     sam_567     43           18
8       Mike     18    j0hn_d03     28            0
9       Mike     18  anna_jones     30           14
10      Mike     18  mike_smith     20           43
11      Mike     18     sam_567     43            0
12  Samantha     45    j0hn_d03     28           12
13  Samantha     45  anna_jones     30           33
14  Samantha     45  mike_smith     20           33
15  Samantha     45     sam_567     43           27

从这里,您可以根据需要,根据match_ratio、age或任何其他条件删除或保留行

相关问题