【问题标题】:Pandas merging on different size dataframes based on one columnPandas 基于一列合并不同大小的数据框
【发布时间】:2018-10-05 07:40:57
【问题描述】:

我有 2 种不同大小的数据框。

在 df1 上,我有来自日志的 datetimeusernameemail addressphone numberduration。但是email addressphone number 只是带​​有空字符串的列。

在 df2 上,我拥有数据库中的所有 usernameemail addressphone number

如何根据用户名将 df2 合并到 df1 中? 意思是说 df1 的大小将保持不变,但将填充 email addressphone number 列。当然是来自 df2 的匹配数据

假设 username 是唯一的

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    merge与左连接和参数suffixes一起使用,最后删除原始列email addressphone number(使用_):

    df1 = pd.DataFrame({
            'username':list('abccdd'),
             'email address':[''] * 6,
             'phone number':[''] * 6,
             'duration':[5,3,6,9,2,4],
    })
    print (df1)
      username email address phone number  duration
    0        a                                    5
    1        b                                    3
    2        c                                    6
    3        c                                    9
    4        d                                    2
    5        d                                    4
    
    df2 = pd.DataFrame({
            'username':list('abcd'),
             'email address':['a@a.sk','b@a.sk','c@a.sk','d@a.sk'],
             'phone number':range(4)
    })
    print (df2)
      username email address  phone number
    0        a        a@a.sk             0
    1        b        b@a.sk             1
    2        c        c@a.sk             2
    3        d        d@a.sk             3
    

    df = (df1.merge(df2, on='username', how='left', suffixes=('_',''))
            .drop(['email address_','phone number_'], axis=1)
            .reindex(columns=df1.columns))
    print (df)
      username email address  phone number  duration
    0        a        a@a.sk             0         5
    1        b        b@a.sk             1         3
    2        c        c@a.sk             2         6
    3        c        c@a.sk             2         9
    4        d        d@a.sk             3         2
    5        d        d@a.sk             3         4
    

    另一个解决方案,difference 用于所有未在列表中定义的列名,reindex 用于与df1 相同的排序:

    c = df1.columns.difference(['email address','phone number'])
    df = df1[c].merge(df2, on='username', how='left').reindex(columns=df1.columns)
    
    print (df)
      username email address  phone number  duration
    0        a        a@a.sk             0         5
    1        b        b@a.sk             1         3
    2        c        c@a.sk             2         6
    3        c        c@a.sk             2         9
    4        d        d@a.sk             3         2
    5        d        d@a.sk             3         4
    

    【讨论】:

    • 谢谢!第二个要好得多,我不需要再次重新排列我的列。
    【解决方案2】:

    你可以用这个:

    df = df1[['username', 'date', 'time', 'duration']].merge(df2, left_on='username', right_on='username')
    

    示例: df1

       date  duration email address phone number   time username
    0  2015         5                             14:00       aa
    1  2016        10                             16:00       bb
    

    df2

      email address   phone number username
    0          rrr@         333444       aa
    1           tt@         555533       bb
    

    输出:

      username  date   time  duration email address   phone number
    0       aa  2015  14:00         5          rrr@         333444
    1       bb  2016  16:00        10           tt@         555533
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-28
      • 1970-01-01
      • 1970-01-01
      • 2015-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多