You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Artist和Song列合并两个Pandas DataFrame及拼写匹配问题

Fixing Pandas Merge Issues & Handling Spelling Errors

Hey there! Let's work through your two main problems: getting the merge to work correctly without duplicate columns, and handling spelling mismatches between your DataFrames.

1. Fixing the Basic Merge Problem

Your original merge code had a syntax error that caused those Artist_x/Artist_y columns. When you use on='Artist' and 'Song', Python evaluates that as just 'Song' (since non-empty strings are truthy, 'Artist' and 'Song' returns the second string). That means you were only merging on the Song column—so Pandas renames the duplicate Artist columns from each DataFrame to avoid confusion.

Here's the corrected approach to merge on both columns, get your desired column order, and fill mismatched values with 0:

import pandas as pd

# Correct merge: use a list to specify multiple join keys
merged = pd.merge(dfMap, dfBB, on=['Artist', 'Song'], how='outer')

# Reorder columns to match your desired structure
desired_cols = ['Artist', 'Song', 'SongId', 'ArtistId', 'Rank', 'Year']
merged = merged[desired_cols]

# Fill any NaN values (from unmatched rows) with 0
merged = merged.fillna(0)

This will give you exactly the column structure you want, with 0s in Rank/Year for rows from dfMap that don't have a match in dfBB, and 0s in SongId/ArtistId for rows from dfBB that don't match dfMap.

2. Handling Spelling/Formatting Errors with Fuzzy Matching

For cases where artist or song names have minor spelling differences (like "Taylor Swift" vs "Tayler Swift" or "Hello" vs "Hello!"), you'll need fuzzy matching to find similar entries. We'll use rapidfuzz (a maintained, faster alternative to fuzzywuzzy) for this.

Step 1: Preprocess Text

First, standardize the text in both DataFrames to reduce false mismatches (e.g., lowercase, remove special characters, trim spaces):

from rapidfuzz import process, fuzz

def clean_text(text):
    if pd.isna(text):
        return ""
    # Lowercase, trim spaces, remove common special chars
    return text.lower().strip().replace("'", "").replace("-", " ").replace(",", "")

# Apply cleaning to both DataFrames
dfBB['Artist_clean'] = dfBB['Artist'].apply(clean_text)
dfBB['Song_clean'] = dfBB['Song'].apply(clean_text)
dfMap['Artist_clean'] = dfMap['Artist'].apply(clean_text)
dfMap['Song_clean'] = dfMap['Song'].apply(clean_text)

Step 2: Fuzzy Match & Merge

Next, we'll match each row in dfMap to the closest entry in dfBB based on the cleaned artist/song names, using a similarity threshold (adjust this based on how strict you want matches to be):

def get_best_match(row, target_df):
    # Create a combined key for matching (artist + song)
    target_keys = target_df['Artist_clean'] + " | " + target_df['Song_clean']
    current_key = row['Artist_clean'] + " | " + row['Song_clean']
    
    # Find the closest match (token_sort_ratio ignores word order, great for names like "The Beatles" vs "Beatles, The")
    match, score, _ = process.extractOne(current_key, target_keys, scorer=fuzz.token_sort_ratio)
    
    # Only accept matches with a similarity score >= 80 (adjust as needed)
    if score >= 80:
        matched_row = target_df[target_keys == match].iloc[0]
        return pd.Series([matched_row['Rank'], matched_row['Year']])
    else:
        # No good match found, return 0s
        return pd.Series([0, 0])

# Add Rank and Year to dfMap via fuzzy matching
dfMap[['Rank', 'Year']] = dfMap.apply(get_best_match, target_df=dfBB, axis=1)

# Finalize the DataFrame with your desired columns
final_df = dfMap[['Artist', 'Song', 'SongId', 'ArtistId', 'Rank', 'Year']]

Notes on Fuzzy Matching:

  • Adjust the similarity threshold (80 in the example) based on your data: use a higher value (like 90) for stricter matches, or lower (like 70) if you have more variation.
  • If you want to match on artist first then song (instead of combining them), you can modify the function to first find matching artists, then match songs within those artists—this can improve accuracy.
  • For large datasets, this apply-based approach might be slow. You can optimize by using vectorized operations or libraries like fuzzywuzzy-process for bulk matching.

内容的提问来源于stack exchange,提问作者joe borg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:15:41