【问题标题】:Join/merge dataframes and preserve the row-order加入/合并数据框并保留行顺序
【发布时间】:2019-07-18 19:02:56
【问题描述】:

我在pythonpandas 工作。

假设我有以下两个数据框df_1df_2 (INPUT)

# df1
    A   B   C
0   2   8   6
1   5   2   5
2   3   4   9
3   5   1   1

# df2
    A   B   C
0   2   7   NaN
1   5   1   NaN
2   3   3   NaN
3   5   0   NaN

我想处理它以加入/合并它们以获得一个看起来像 (预期输出)的新数据框:

    A   B   C
0   2   7   NaN
1   5   1   1
2   3   3   NaN
3   5   0   NaN

所以基本上它是一个右合并/连接,但保留原始右数据帧的顺序。

但是,如果我这样做:

df_2 = df_1.merge(df_2[['A', 'B']], on=['A', 'B'], how='right')

然后我明白了:

    A   B   C
0   5   1   1.0
1   2   7   NaN
2   3   3   NaN
3   5   0   NaN

所以我得到了加入/合并的正确行,但输出数据帧与原始正确数据帧的行顺序不同。

如何进行连接/合并并保留行顺序?

创建原始数据帧的代码如下:

import pandas as pd
import numpy as np

columns = ['A', 'B', 'C']
data_1 = [[2, 5, 3, 5], [8, 2, 4, 1], [6, 5, 9, 1]]
data_1 = np.array(data_1).T
df_1 = pd.DataFrame(data=data_1, columns=columns)

columns = ['A', 'B', 'C']
data_2 = [[2, 5, 3, 5], [7, 1, 3, 0], [np.nan, np.nan, np.nan, np.nan]]
data_2 = np.array(data_2).T
df_2 = pd.DataFrame(data=data_2, columns=columns)

我认为通过使用.join().update() 我可以得到我想要的,但我很惊讶.merge() 也没有做这个非常简单的事情。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    我认为这是错误。

    左连接的可能解决方案:

    df_2 = df_2.merge(df_1, on=['A', 'B'], how='left', suffixes=('_','')).drop('C_', axis=1)
    print (df_2)
         A    B    C
    0  2.0  7.0  NaN
    1  5.0  1.0  1.0
    2  3.0  3.0  NaN
    3  5.0  0.0  NaN
    

    【讨论】:

    • 感谢您的回答(点赞)。是的,它在我看来像是一个错误,或者是一个很大的遗漏。顺便问一下,你如何在下面找到我的答案?
    • 您需要将C 列中的缺失值替换为来自另一个 DaatFrame 的C 列吗?
    • 所以你的意思是我的代码用其他 NA 替换了 NA? (这显然是多余的)
    • 不,我认为 NaNs 应该被非 NaNs 值替换 - 如果需要这个,那么更新是一个很好的解决方案。
    • NAs 不应被任何东西替换,除非与其他数据帧中的行匹配,否则它们应保持为 NAs。这就是我谈论加入/合并的原因。我回答你的问题了吗? (对不起,我不完全理解你的问题)。
    【解决方案2】:

    您可以在两个数据帧之间使用索引

    print(df)
    #    A  B    C
    # 0  5  1  1.0
    # 1  2  7  NaN
    # 2  3  3  NaN
    # 3  5  0  NaN
    
    df = df.set_index('B')
    df = df.reindex(index=df_2['B'])
    df = df.reset_index()
    df = df[['A', 'B', 'C']]
    
    print(df)
    #    A    B    C
    # 0  2  7.0  NaN
    # 1  5  1.0  1.0
    # 2  3  3.0  NaN
    # 3  5  0.0  NaN
    

    Source

    【讨论】:

      【解决方案3】:

      一种快速的方法是:

      df_2=df_2.set_index(['A','B'])
      
      temp = df_1.set_index(['A','B'])
      
      df_2.update(temp)
      
      df_2.reset_index(inplace=True)
      

      正如我在上面与@jezrael 讨论的那样,如果我没有遗漏任何东西,如果您不需要原始数据帧中的两个列C,并且您只需要具有匹配值的列C,那么@987654324 @ 是最快的方法,因为您不必删除不需要的列。

      【讨论】:

        猜你喜欢
        • 2018-11-24
        • 1970-01-01
        • 2019-07-18
        • 2021-09-02
        • 2020-12-10
        • 1970-01-01
        • 1970-01-01
        • 2021-10-17
        • 2018-01-07
        相关资源
        最近更新 更多