【问题标题】:Approximate join with pandas与 pandas 的近似连接
【发布时间】:2018-12-14 03:41:53
【问题描述】:

我有 2 个数据框,df1 和 df2。我的两个数据框都有一个名为“zip_code”的列,我想在这些列上加入 df1 和 df2。

问题是,在 df2 中,有时“zip_code”列中的字符串在开头缺少一个“0”。但我希望熊猫能够检测到它们是“相同”的值。

有没有办法在不预处理我的数据的情况下这样做?

【问题讨论】:

  • 您可以用前导零填充字符串,或者将两者都转换为整数,在这种情况下,前导零变得毫无意义(后者不适用于带有破折号的邮政编码,例如01912-001)。

标签: python string pandas join merge


【解决方案1】:

在这种情况下,Series.str.zfill() 可用于预处理。

import pandas as pd
df = pd.DataFrame({'zip5': ['1', '12', '123', '1234', '12345', '123456']})

df.zip5.str.zfill(5)
#0     00001
#1     00012
#2     00123
#3     01234
#4     12345
#5    123456
#Name: zip5, dtype: object

这不会影响任何大于或等于 5 个字符的邮政编码,并且会用前导零填充所有内容,在这种情况下最多为 5 个字符。您可以使用它来更新 df2 中的 zip,然后正常合并。

【讨论】:

    【解决方案2】:

    这会很长,并且假设所有邮政编码在开头附加一个 0 后将具有相同的长度。

    import pandas as pd
    import numpy as np
    
    t1 = pd.DataFrame({'id':[1,2,3,4],
                     'zip_code':['0234','0345','3456','4567']})
    
    t2 = pd.DataFrame({'id2':[5,6,7,8],
                     'zip_code':['234','0345','3456','4567']})
    
    t2['lens'] = t2.zip_code.apply(len)
    
    t2.loc[:,'zip_code'] = np.where(t2.lens<4,'0'+t2['zip_code'].astype(str),t2['zip_code'])
    

    输入 t1:

        id  zip_code
    0   1   0234
    1   2   0345
    2   3   3456
    3   4   4567
    

    输入 t2:

        id2 zip_code
    0   5   234
    1   6   0345
    2   7   3456
    3   8   4567
    

    输出 t2:

        id2 zip_code    lens
    0   5   0234    3
    1   6   0345    4
    2   7   3456    4
    3   8   4567    4
    

    如果您以后不需要它,您可以删除镜头列。现在您可以使用 zip_code 连接两个数据帧 t1 和 t2。

    【讨论】:

      【解决方案3】:

      如果不需要,我认为建议进行预处理。否则,当您合并时,您将有 2 个邮政编码的行,一个以 '0' 开头,另一个不是。

      您可以根据掩码更新df2 中的违规邮政编码。我假设zip_code 系列都被转换为str

      # prefixing with 0 causes a zip_code match with df1
      mask = ('0' + df2['zip_code']).isin(df1['zip_code'].unique())
      
      # apply the prefix for these cases
      df2.loc[mask, 'zip_code'] = '0' + df2.loc[mask, 'zip_code']
      

      然后像往常一样执行合并。

      【讨论】:

        【解决方案4】:

        只要使用DataFrame的join函数就可以了

        import pandas as pd
        
        A = pd.DataFrame(
            {
                'zip_code':[1000,1001,2000,2002],
                'place':['A','A','B','B']
            }
        )
        
        B = pd.DataFrame(
            {
                'Name':['x','y','z'],
                'zip_code':[1001,1000,2000]
        
        })
        B['zip_code'] = [x.lstrip('0') for x in B['zip_code']]
        B.join(A.set_index('zip_code'), on='zip_code')
        

        【讨论】:

        • 我认为这不能回答 OP 关于预先修复缺失 0 的问题。
        • 是的。我错过了一步。它已经过编辑,现在应该可以使用了
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-03
        相关资源
        最近更新 更多