title: Python with Pandas: Big dataframe (150000 lines) with misspelled names, best strategy to sort out repeated names?
body: <p>I am working with a relatively big dataframe, 1600000 lines. Each line is an entry of a building code violation. Data includes information from the agency issuing the ticket, building address, building zip code, owner's name, address and zip code, plus violation information, fines data, and some additional columns.</p>
  <div class="s-table-container">
  <table class="s-table">
  <thead>
  <tr>
  <th>ticket_id</th>
  <th>…</th>
  <th>owner_name</th>
  <th>…</th>
  <th>mailing_address_str_name</th>
  <th>zip_code</th>
  <th>…</th>
  </tr>
  </thead>
  <tbody>
  <tr>
  <td>21771</td>
  <td>…</td>
  <td>MORTGAGE, INC., WELLS FARGO HOME</td>
  <td>…</td>
  <td>STATE VIEW BLVD.</td>
  <td>29715</td>
  <td>…</td>
  </tr>
  <tr>
  <td>25534</td>
  <td>…</td>
  <td>MORTGAGE INC., WELLS FARGO HOME</td>
  <td>…</td>
  <td>STATE VIEW BLVD.</td>
  <td>29715</td>
  <td>…</td>
  </tr>
  <tr>
  <td>37303</td>
  <td>…</td>
  <td>BANK, W ELLS FARGO</td>
  <td>…</td>
  <td>STATEVIEW BLVD</td>
  <td>29715</td>
  <td>…</td>
  </tr>
  <tr>
  <td>39080</td>
  <td>…</td>
  <td>MORTGAGE INC, WELLS FARGO</td>
  <td>…</td>
  <td>STATE VIEW BLVD</td>
  <td>29715</td>
  <td>…</td>
  </tr>
  <tr>
  <td>41398</td>
  <td>…</td>
  <td>BANK, WELLS FARGO</td>
  <td>…</td>
  <td>STATE VIEW BLVD.</td>
  <td>29715</td>
  <td>…</td>
  </tr>
  <tr>
  <td>46387</td>
  <td>…</td>
  <td>REGISTRATION SYSTEM  INC, MORTGAGE ELECTRONIC</td>
  <td>…</td>
  <td>STATE VIEW</td>
  <td>29715</td>
  <td>…</td>
  </tr>
  <tr>
  <td>47099</td>
  <td>…</td>
  <td>ASSOCIATION, US BANK NATIONAL</td>
  <td>…</td>
  <td>STATE VIEW BLVD.</td>
  <td>29715</td>
  <td>…</td>
  </tr>
  <tr>
  <td>47446</td>
  <td>…</td>
  <td>ELECTRONIC REGISTRATION SYSTEM, MORTGAGE</td>
  <td>…</td>
  <td>STATE VIEW BLVD</td>
  <td>29715</td>
  <td>…</td>
  </tr>
  <tr>
  <td>170222</td>
  <td>…</td>
  <td>GROUP LLC, INTERSTATE INVESTMENT</td>
  <td>…</td>
  <td>P.O. BOX 264</td>
  <td>29054</td>
  <td>…</td>
  </tr>
  <tr>
  <td>177660</td>
  <td>…</td>
  <td>HOLDINGS LLC, PARAMOUNT LAND</td>
  <td>…</td>
  <td>HAMPTON ST</td>
  <td>29054</td>
  <td>…</td>
  </tr>
  <tr>
  <td>178771</td>
  <td>…</td>
  <td>HOLDINGS LLC, PARAMOUNT LAND</td>
  <td>…</td>
  <td>HAMPTON ST</td>
  <td>29054</td>
  <td>…</td>
  </tr>
  <tr>
  <td>181349</td>
  <td>…</td>
  <td>GROUP LLC, INTERSTATE INVESTMENT</td>
  <td>…</td>
  <td>HAMPTON</td>
  <td>29054</td>
  <td>…</td>
  </tr>
  <tr>
  <td>181288</td>
  <td>…</td>
  <td>GROUP LLC, INTERSTATE INVESTMENT</td>
  <td>…</td>
  <td>HAMPTON ST</td>
  <td>29054</td>
  <td>…</td>
  </tr>
  <tr>
  <td>181597</td>
  <td>…</td>
  <td>PARAMOUNT LAND HOLDING LLC, .</td>
  <td>…</td>
  <td>PO BOX 264</td>
  <td>29054</td>
  <td>…</td>
  </tr>
  <tr>
  <td>21157</td>
  <td>…</td>
  <td>I B PROPERTY HOLDINGS, LLC, .</td>
  <td>…</td>
  <td>PONCE DeLEON BLVD.</td>
  <td>33146</td>
  <td>…</td>
  </tr>
  <tr>
  <td>35992</td>
  <td>…</td>
  <td>PROPERTY TRUST, BAYVIEW FINANCIAL</td>
  <td>…</td>
  <td>PONCE DE LEON BLVD. 4TH FLR</td>
  <td>33146</td>
  <td>…</td>
  </tr>
  <tr>
  <td>36153</td>
  <td>…</td>
  <td>PROPERTY TRUST, BAYVIEW FINANCIAL</td>
  <td>…</td>
  <td>PONCE DE LEON BLVD</td>
  <td>33146</td>
  <td>…</td>
  </tr>
  <tr>
  <td>46970</td>
  <td>…</td>
  <td>TRUST ADELWARE TRUST, BAYVIEW FINANCIAL PROPERTY</td>
  <td>…</td>
  <td>PONCE DE LEON BLVD. 4TH FLR</td>
  <td>33146</td>
  <td>…</td>
  </tr>
  <tr>
  <td>53884</td>
  <td>…</td>
  <td>IB PROPERTY HOLDINGS, LLC, .4425</td>
  <td>…</td>
  <td>PONCE DeLEON BLVD.</td>
  <td>33146</td>
  <td>…</td>
  </tr>
  <tr>
  <td>61911</td>
  <td>…</td>
  <td>LLC, IB PROPERTY HOLDING</td>
  <td>…</td>
  <td>PONCE  DE  LEON  BLVD.</td>
  <td>33146</td>
  <td>…</td>
  </tr>
  </tbody>
  </table>
  </div>
  <p>The column I want to analyze is owner's name. It has a lot of variations for the same name. I do not have the correct spelling, and I don't need it. I need to figure out how many tickets have been issued to a given owner.</p>
  <p>The code I wrote works well but takes AGES (3 hrs to clean up the dataframe).</p>
  <p>First thing I separate owners addresses by zip codes (there are some 3000+ zip codes), assuming zip code is much less prone to error than &quot;owners name&quot;. I use:</p>
  <p><code>groups = trandf01.groupby('zip_code', sort=False) </code></p>
  <p>And I get a nice set of 3000+ zip codes with something between 1 and 7000 tickets per code. For each group I then proceed to scan it row by row with a basic algorithm. I do a double loop:</p>
  <pre><code>import numpy as np
  from fuzzywuzzy import fuzz
  
  trandf01 = pd.read_csv('data.csv')
  groups = trandf01.groupby('zip_code', sort=False)
  keys = groups.groups.keys()
  
  df2 = pd.DataFrame()
  for k in keys:
      df=groups.get_group(k)
      if len(df.index)&gt;2:
          df.reset_index(inplace=True)
          for i in range(len(df.index)):
              aa=df.iat[i,4]
              for j in range(i+1,len(df.index)):
                  bb=df.iat[j,4]
                  ratio=fuzz.token_set_ratio(aa,bb)
                  if ratio &gt; 74:
                      df.iat[j,4]=aa
      df2=pd.concat([df2,df])
  df2.to_excel(&quot;TextCorrectedNEW.xlsx&quot;)
  </code></pre>
  <p>Each name is compared with the names that follow it. If I get a match (<code> fuzz.token_set_ratio(aa,bb) &gt; 74</code>), I replace the new one with the first one. While it may not give an optimal solution (best &quot;matcher&quot; overall), it works quite well, but slow. Speed is n^2 with n the number of entries for each zip code.</p>
  <p>There is some other way that is faster?</p>
  <p>Thank you.</p>