根据另一个数据帧的多个列过滤数据帧

时间:2017-08-01 14:24:47

标签: python pandas

我有一个这样的数据框:

    ID1    ID2
0   foo    bar
1   fizz   buzz

另一个像这样:

    ID1    ID2    Count    Code   
0   abc    def      1        A
1   fizz   buzz     5        A
2   fizz1  buzz2    3        C
3   foo    bar      6        Z
4   foo    bar      6        Z

我想要做的是过滤第二个数据帧,其中ID1和ID2匹配第一个数据帧中的一行,每当匹配时我想从第一个数据帧中删除该行以避免重复。这将产生一个如下所示的数据框:

    ID1    ID2    Count    Code   
1   fizz   buzz     5        A
3   foo    bar      6        Z

我知道我可以通过嵌套for循环,逐步遍历所有行,并在我得到匹配时从第一帧手动删除一行但我想知道是否有更多pythonic方法来执行此操作。我没有大熊猫的经验,所以可能有一个更清洁的方法,我不知道。我以前使用的是.isin(),但不得不废弃它。每个ID对最多可以存在于数据帧中N次,我需要过滤后的帧包含一对0到N个实例。

5 个答案:

答案 0 :(得分:5)

mergedrop_duplicates一起使用,如果只有相同的列加入df

df = pd.merge(df1,df2.drop_duplicates())
print (df)
    ID1   ID2  Count Code
0   foo   bar      6    Z
1  fizz  buzz      5    A

如果需要仅在ID列中检查欺骗行为:

df = pd.merge(df1,df2.drop_duplicates(subset=['ID1','ID2']))
print (df)
    ID1   ID2  Count Code
0   foo   bar      6    Z
1  fizz  buzz      5    A

如果有更多列重叠添加参数on

df = pd.merge(df1, df2.drop_duplicates(), on=['ID1','ID2'])

如果不删除欺骗行:

df = pd.merge(df1,df2)
print (df)
    ID1   ID2  Count Code
0   foo   bar      6    Z
1   foo   bar      6    Z
2  fizz  buzz      5    A

答案 1 :(得分:3)

试试这个:

Castle.Core 4.1.1

答案 2 :(得分:2)

或者试试这个?

df.loc[(df.ID1.isin(df1.ID1))&(df.ID2.isin(df1.ID2)),:].drop_duplicates()


Out[224]: 
    ID1   ID2  Count Code
1  fizz  buzz      5    A
3   foo   bar      6    Z

答案 3 :(得分:2)

在元组列表中使用isin

df2[
    pd.Series(
        list(zip(df2.ID1.values, df2.ID2.values))
    ).isin(list(zip(df1.ID1.values, df1.ID2.values)))
]

    ID1   ID2  Count Code
1  fizz  buzz      5    A
3   foo   bar      6    Z
4   foo   bar      6    Z

答案 4 :(得分:0)

Merge几乎是我想要的,但是我没有完成这项工作,因为我有一套奇怪的要求,我需要过滤掉一些重复项,但不是所有重复项。常规合并不起作用,因为它保留所有重复项并且drop_duplicates()不起作用,因为我需要允许一些重复项。我最终使用了我在问题中描述的方法并嵌套了for循环。

temp_frame = pd.DataFrame(columns.df2.columns)
for i in xrange(len(df2)):
    for ii in xrange(len(df1)):
        if df2['ID1'].iloc[i] == df1['ID1'].iloc[ii] and df2['ID2'].iloc[i] == df1['ID2'].iloc[ii]:
            df1.drop(df1.index[ii], inplace=True)
            temp_frame = temp_frame.append(df2.iloc[i], ignore_index=True)
            break
df1 = temp_frame.copy()