代码之家  ›  专栏  ›  技术社区  ›  PeptideWitch

熊猫:用另一个数据帧的多个同时列值过滤一个数据帧

  •  1
  • PeptideWitch  · 技术社区  · 3 年前

    我有一个经过过滤的数据帧,叫做 correct_df 还有一个原始数据帧 example_df .

    example_df = pd.DataFrame({'Test': ['Test_1', 'Test_1', 'Test_1', 'Test_2', 'Test_2', 'Test_2', 'Test_3', 'Test_3', 'Test_3'], 'A': [1, 2, 3, 1, 2, 3, 1, 2, 3]})
    other_df = pd.DataFrame({'Test': ['Test_1', 'Test_1', 'Test_3', 'Test_3'], 'A': [1, 2, 1, 3]})
    

    预期结果:

    我想要 示例_df 其中“Test”和“A”列值都与 正确_df .

    我试过:

    result = example_df.loc[ (example_df['Test'].isin(other_df['Test'])) & (example_df['A'].isin(other_df['A'])) ]
    result
    
        Test    A
    0   Test_1  1
    1   Test_1  2
    2   Test_1  3
    6   Test_3  1
    7   Test_3  2
    8   Test_3  3
    

    但是,由于这两个条件是分开的,结果值只应用于单个列上的条件,而不链接它们,即A,然后也是B,而不是A和B。我如何获得。两列条件的位置?

    1 回复  |  直到 3 年前
        1
  •  2
  •   jezrael    3 年前

    使用 DataFrame.reset_index 为了避免损失指数 DataFrame.merge :

    result = example_df.reset_index().merge(other_df, on=['Test','A'])
    print (result)
       index    Test  A
    0      0  Test_1  1
    1      1  Test_1  2
    2      6  Test_3  1
    3      8  Test_3  3
    

    result = (example_df.reset_index()
                        .merge(other_df, on=['Test','A'])
                        .set_index('index')
                        .rename_axis(None))
    print (result)
         Test  A
    0  Test_1  1
    1  Test_1  2
    6  Test_3  1
    8  Test_3  3
    

    另一个关于 MultiIndex 具有 Index.isin 然后过滤进来 boolean indexing :

    result = example_df[example_df.set_index(['Test','A']).index
                                  .isin(other_df.set_index(['Test','A']).index)]
    print (result)
         Test  A
    0  Test_1  1
    1  Test_1  2
    6  Test_3  1
    8  Test_3  3
    
        2
  •  0
  •   enke    3 年前

    @耶斯雷尔的解决方案绝对适合你的问题。这只是使用numpy获得相同结果的另一种方法(有点复杂)。

    我们可以过滤 example_df 直接使用一个布尔数组,我们可以通过检查 示例_df 存在 other_df .要做到这一点,我们需要 示例_df 一个3D阵列,并使用numpy广播与 其他 .然后使用 all any 将其缩小到1D阵列 msk :

    msk = (example_df.to_numpy()[:, None]==other_df.to_numpy()).all(axis=2).any(axis=1)
    out = example_df[msk]
    

    输出:

         Test  A
    0  Test_1  1
    1  Test_1  2
    6  Test_3  1
    8  Test_3  3