【问题标题】:Merge two Dataframes based on two columns基于两列合并两个数据框
【发布时间】:2020-01-09 07:41:30
【问题描述】:

我有两个数据框:df1df_outdf1 看起来像这样

   phone_number1  phone_number2
1    123             123
2    345              0
3    678             678
4    912             912
5    555             666

还有df_out

    phone_number  address   name
1      123         add1     name1
2     777777       add2     name2
3      666         add3     name3
4      555         add4     name4

并且想做这样的事情

    phone_number  address   name    df1_phone_number1    df1_phone_number2
1      123         add1     name1        123                  123
2     777777       add2     name2        None                 None
3      666         add3     name3        None                 666
4      555         add4     name4        555                  None

我试过这段代码,但它不会保存匹配phone_number2的数据

    mergedStuff3 = pd.concat([
            pd.merge(df1, df_out,  how='right', left_on=['phone_number1'], right_on = ['phone_number']),
            pd.merge(df1, df_out,  how='right', left_on=['phone_number2', 'phone_number1'], right_on = ['phone_number', 'phone_number'])

        ])

【问题讨论】:

  • 我会先合并到 df_out, df1['phone_number1'] 然后再合并 df1['phone_number2']

标签: python python-3.x pandas dataframe


【解决方案1】:

我认为您需要Series.whereSeries.isin 的会员资格检查:

m1 = df_out['phone_number'].isin(df1['phone_number1'])
m2 = df_out['phone_number'].isin(df1['phone_number2'])
df_out['df1_phone_number1'] = df_out['phone_number'].where(m1)
df_out['df1_phone_number2'] = df_out['phone_number'].where(m2)
print (df_out)
   phone_number address   name  df1_phone_number1  df1_phone_number2
1           123    add1  name1              123.0              123.0
2        777777    add2  name2                NaN                NaN
3           666    add3  name3                NaN              666.0
4           555    add4  name4              555.0                NaN

或使用numpy.where:

m1 = df_out['phone_number'].isin(df1['phone_number1'])
m2 = df_out['phone_number'].isin(df1['phone_number2'])
df_out['df1_phone_number1'] = np.where(m1, df_out['phone_number'], None)
df_out['df1_phone_number2'] = np.where(m2, df_out['phone_number'], None)
print (df_out)
   phone_number address   name df1_phone_number1 df1_phone_number2
1           123    add1  name1               123               123
2        777777    add2  name2              None              None
3           666    add3  name3              None               666
4           555    add4  name4               555              None

如果有更多的列解决方案应该改变:

for c in df1.columns:
    m = df_out['phone_number'].isin(df1[c])
    df_out[f'df1_{c}'] = np.where(m, df_out['phone_number'], None)

【讨论】:

  • @ansev - yop,但仍然更快,例如 melt + merge+ pivoting
【解决方案2】:

DataFrame.merge之前使用DataFrame.melt,则只需加入DataFrame.join即可。

这适用于 df1 中的 n 列电话号码

df_out.join(df_out.merge(df1.melt(),
                         how = 'inner',
                         left_on ='phone_number',             
                         right_on = 'value')
                  .pivot_table(index = 'phone_number',
                               columns = 'variable',
                               values = 'value'),
            on = 'phone_number')

输出

   phone_number address   name  phone_number1  phone_number2
1           123    add1  name1          123.0          123.0
2        777777    add2  name2            NaN            NaN
3           666    add3  name3            NaN          666.0
4           555    add4  name4          555.0            NaN

【讨论】:

    猜你喜欢
    • 2019-05-01
    • 2018-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多