【问题标题】:Python:merge data frame with different rowsPython:合并具有不同行的数据框
【发布时间】:2017-06-14 10:29:37
【问题描述】:

我需要合并两个不同行且没有公共键的数据框:

df1:

name | age | loc

Bob | 20 | USA

df2:

food | car | sports

Sushi | Toyota | soccer

meat | Ford | baseball

我想要的结果:

name | age | loc | food | car | sports

Bob | 20 | USA | Sushi | Toyota | soccer

Bob | 20 | USA | Meat | Ford | baseball

我的代码如下:

pd.merge(df1,df2,how='right',left_index=True,right_index=True)

当 df2 超过两行时效果很好,但当 df2 只有一行时不正确。

对这个问题有什么想法吗?

【问题讨论】:

    标签: python dataframe merge


    【解决方案1】:

    通过df2的索引使用reindex_axis

    df1 = df1.reindex_axis(df2.index, method='ffill')
    print (df1)
      name  age  loc
    0  Bob   20  USA
    1  Bob   20  USA
    
    df = pd.merge(df1,df2,how='right',left_index=True,right_index=True)
    print (df)
      name  age  loc   food     car    sports
    0  Bob   20  USA  Sushi  Toyota    soccer
    1  Bob   20  USA   meat    Ford  baseball
    

    如果df1df2 中没有NaN 数据,您可以将fillna 与方法ffill (.ffill) 一起使用:

    #default outer join
    df = pd.concat([df1,df2], axis=1).ffill()
    print (df)
      name   age  loc   food     car    sports
    0  Bob  20.0  USA  Sushi  Toyota    soccer
    1  Bob  20.0  USA   meat    Ford  baseball
    

    df = pd.merge(df1,df2,how='right',left_index=True,right_index=True).ffill()
    print (df)
      name   age  loc   food     car    sports
    0  Bob  20.0  USA  Sushi  Toyota    soccer
    1  Bob  20.0  USA   meat    Ford  baseball
    

    【讨论】:

    • 嗨,@jezrael,谢谢你的帮助。当 df2 的行数大于 1 时,您的想法很棒,但当 df2 只有一行时,它不起作用。
    • 而解决方案df = pd.concat([df1,df2], axis=1).ffill() 不起作用?
    • 它会产生一个包含两行的新数据框,即使我原来的 df1 和 df2 都是一行。
    • 嗯,那什么是逻辑?因为如果将合并与left_index=True,right_index=True 一起使用,则意味着按索引连接 - 如果两者都是 1 行,那么两个索引都是 0 并且输出有一行带有 0 索引。同样适用于concat。也许帮助docs
    • 但如果与一个 df 与一行(索引为 0)合并,第二个与 2 行(索引为 0,1)合并,那么如果使用how='inner'(内连接)则只得到第一行,因为在两个数据帧中都匹配 0 索引。但是如果使用左连接或右连接或外连接,则得到 1 或 2 行,但第二行是 NaNs,因为没有匹配。
    【解决方案2】:

    另一种解决方案...基于 concat。

    x = range(0,5)
    y = range(5,10)
    z = range(10,15)
    a = range(10,5,-1)
    b = range(15,10,-1)
    v = range(0,1)
    w = range(2,3)
    
    A = pd.DataFrame(dict(x=x,y=y,z=z))
    B = pd.DataFrame(dict(a=a,b=b))
    C = pd.DataFrame(dict(v=v,w=w))
    
    pd.concat([A,B])
    >>> pd.concat([A,B],axis = 1)
       x  y   z   a   b
    0  0  5  10  10  15
    1  1  6  11   9  14
    2  2  7  12   8  13
    3  3  8  13   7  12
    4  4  9  14   6  11
    

    @Edit:基于 cmets.. 这个解决方案没有回答问题.. 因为在问题中行数不同。这是另一个解决方案 该解决方案基于数据框 D

    n_mult = B.shape[0]
    D = C.append([C]*(n_mult-1)).reset_index()[['v','w']]
    pd.concat([D,B],axis = 1)
    

    【讨论】:

    • 谢谢@zwep,当 df 多行时你的想法很好,但是当 df2 只有一行时就不行了。
    • 嗨@zwep,谢谢你的想法。我已经用 reset_index 解决了这个问题。还是谢谢你们。
    猜你喜欢
    • 1970-01-01
    • 2016-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-23
    相关资源
    最近更新 更多