【问题标题】:Merging dataframes based on index基于索引合并数据框
【发布时间】:2017-08-24 08:46:37
【问题描述】:

如何合并 2 个数据框 df1df2 以获得具有相同索引(以及列中相同值)的 df1df2 行的 df3

df1 = pd.DataFrame({'A': ['A0', 'A2', 'A3', 'A7'],
                        'B': ['B0', 'B2', 'B3', 'B7'],
                        'C': ['C0', 'C2', 'C3', 'C7'],
                        'D': ['D0', 'D2', 'D3', 'D7']},
                         index=[0, 2, 3,7])

测试 1

df2 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A7'],
                    'B': ['B0', 'B1', 'B2', 'B7'],
                    'C': ['C0', 'C1', 'C2', 'C7'],
                    'D': ['D0', 'D1', 'D2', 'D7']},
                     index=[0, 1, 2, 7])

测试 2

df2 = pd.DataFrame({'A': ['A1'],
                    'B': ['B1'],
                    'C': ['C1'],
                    'D': ['D1']},
                     index=[1])

预期输出测试 1

Out[13]: 
    A   B   C   D
0  A0  B0  C0  D0
2  A2  B2  C2  D2
7  A7  B7  C7  D7

预期输出测试 2

Empty DataFrame
Columns: [A, B, C, D]
Index: []

【问题讨论】:

    标签: python pandas dataframe merge


    【解决方案1】:

    只要merge:

    In[111]:
    df1.merge(df2)
    
    Out[111]: 
        A   B   C   D
    0  A0  B0  C0  D0
    

    merge 的默认参数是合并所有列,执行 inner 合并,因此只有在所有值一致的情况下

    查看索引匹配要求,我会在合并之前过滤 df:

    In[131]:
    filtered = df1.loc[df2.index].dropna()
    filtered
    
    Out[131]: 
        A   B   C   D
    1  A1  B1  C1  D1
    

    然后合并

    In[132]:
    filtered.merge(df2)
    Out[132]: 
        A   B   C   D
    0  A0  B0  C0  D0
    

    如果索引根本不匹配,假设df2 的第一行是1 而不是2

    In[133]:
    filtered = df1.loc[df2.index].dropna()
    filtered
    Out[133]: 
        A   B   C   D
    1  A1  B1  C1  D1
    

    那么merge 将返回一个空的df,因为索引行的值不一致:

    In[134]:
    filtered.merge(df2)
    
    Out[132]: 
    Empty DataFrame
    Columns: [A, B, C, D]
    Index: []
    

    更新

    在您的新数据集上,merge 将重置索引,这是默认行为:

    In[152]:
    filtered.merge(df2)
    
    Out[152]: 
        A   B   C   D
    0  A0  B0  C0  D0
    1  A2  B2  C2  D2
    2  A7  B7  C7  D7
    

    所以要保留索引,我们可以使用相等运算符创建一个布尔掩码并调用dropna,这样任何带有NaN 值的行都会被删除,这些行将出现在值不一致的情况下,这应该处理所有情况:

    In[153]:
    filtered[filtered== df2.loc[filtered.index]].dropna()
    
    Out[153]: 
        A   B   C   D
    0  A0  B0  C0  D0
    2  A2  B2  C2  D2
    7  A7  B7  C7  D7
    

    【讨论】:

    • 我已经用不同的测试用例编辑了这个问题...不确定您提供的解决方案是否适用于这种情况..
    • 它似乎给出了正确的行但不保留索引。
    • @cᴏʟᴅsᴘᴇᴇᴅ 索引在列上合并时被忽略,语义上我认为merge 是正确的方法,我将更新以展示如何让它像发布的那样工作
    • @EdChum 这个解决方案的问题是,如果没有共同的指标,合并会发出警告......知道如何解决它吗?我在问题中添加了测试用例跨度>
    • 实际上它给出了一个错误 KeyError: "None of [Int64Index([1], dtype='int64')] are in the [index]"
    【解决方案2】:

    如果您确定这些值相同,您可以这样做:

    df1.loc[df1.index.to_series().isin(df2.index)]
    

    没有必要进行合并。

    【讨论】:

    • 从语义上讲,这只是在索引上匹配,而不是在列或列值上匹配,这不是 OP 的问题所在
    • 嗯,这正是他所要求的。他不想合并来自两个数据帧的数据,他只想根据索引进行过滤。
    猜你喜欢
    • 1970-01-01
    • 2018-06-12
    • 1970-01-01
    • 1970-01-01
    • 2021-04-21
    • 2016-07-23
    • 2022-09-29
    • 1970-01-01
    • 2016-06-27
    相关资源
    最近更新 更多