Pandas fuzzy merge/match name column, with duplicates

前端 未结 3 1540
离开以前
离开以前 2020-12-16 05:44

I have two dataframes currently, one for donors and one for fundraisers. I\'m trying to find if any fundraisers also gave donations, a

3条回答
  •  独厮守ぢ
    2020-12-16 06:39

    I would use Jaro-Winkler, because it is one of the most performant and accurate approximate string matching algorithms currently available [Cohen, et al.], [Winkler].

    This is how I would do it with Jaro-Winkler from the jellyfish package:

    def get_closest_match(x, list_strings):
    
      best_match = None
      highest_jw = 0
    
      for current_string in list_strings:
        current_score = jellyfish.jaro_winkler(x, current_string)
    
        if(current_score > highest_jw):
          highest_jw = current_score
          best_match = current_string
    
      return best_match
    
    df1 = pandas.DataFrame([[1],[2],[3],[4],[5]], index=['one','two','three','four','five'], columns=['number'])
    df2 = pandas.DataFrame([['a'],['b'],['c'],['d'],['e']], index=['one','too','three','fours','five'], columns=['letter'])
    
    df2.index = df2.index.map(lambda x: get_closest_match(x, df1.index))
    
    df1.join(df2)
    

    Output:

        number  letter
    one     1   a
    two     2   b
    three   3   c
    four    4   d
    five    5   e
    

    Update: Use jaro_winkler from the Levenshtein module for improved performance.

    from jellyfish import jaro_winkler as jf_jw
    from Levenshtein import jaro_winkler as lv_jw
    
    %timeit jf_jw("appel", "apple")
    >> 339 ns ± 1.04 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    
    %timeit lv_jw("appel", "apple")
    >> 193 ns ± 0.675 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    

提交回复
热议问题