如何从另一个datafram中删除pandas数据帧

2024-04-26 09:25:01 发布

您现在位置:Python中文网/ 问答频道 /正文

如何从另一个数据帧中移除pandas数据帧,就像集合减法一样:

a=[1,2,3,4,5]
b=[1,5]
a-b=[2,3,4]

现在我们有两个pandas数据框,如何从df1中删除df2:

In [5]: df1=pd.DataFrame([[1,2],[3,4],[5,6]],columns=['a','b'])
In [6]: df1
Out[6]:
   a  b
0  1  2
1  3  4
2  5  6


In [9]: df2=pd.DataFrame([[1,2],[5,6]],columns=['a','b'])
In [10]: df2
Out[10]:
   a  b
0  1  2
1  5  6

那么我们期望df1-df2的结果是:

In [14]: df
Out[14]:
   a  b
0  3  4

怎么做?

谢谢你。


Tags: columns数据indataframepandasdfoutpd
3条回答

您可以使用.duplicated,这样做的好处是具有相当的表现力:

%%timeit
combined = df1.append(df2)
combined[~combined.index.duplicated(keep=False)]

1000 loops, best of 3: 875 µs per loop

供比较:

%timeit df1.loc[pd.merge(df1, df2, on=['a','b'], how='left', indicator=True)['_merge'] == 'left_only']

100 loops, best of 3: 4.57 ms per loop


%timeit pd.concat([df1, df2, df2]).drop_duplicates(keep=False)

1000 loops, best of 3: 987 µs per loop


%timeit df2[df2.apply(lambda x: x.value not in df2.values, axis=1)]

1000 loops, best of 3: 546 µs per loop

总之,使用np.array比较是最快的。不需要那里的.tolist()

解决方案

使用pd.concat后跟drop_duplicates(keep=False)

pd.concat([df1, df2, df2]).drop_duplicates(keep=False)

看起来像

   a  b
1  3  4

解释

pd.concat将两个DataFrame相加,一个接一个。如果有任何重叠,它将被drop_duplicates方法捕获。但是,drop_duplicates默认情况下会留下第一个观察值,并删除所有其他观察值。在这种情况下,我们希望删除所有副本。因此,这个keep=False参数就是这样做的。

对重复的df2的特别注意。如果只有一个df2,则df2中任何不在df1中的行都不会被视为重复行,并将保留。只有一个df2的解决方案仅在df2df1的子集时有效。但是,如果我们两次concat df2,则它保证是重复的,并且随后将被删除。

一种集合逻辑方法。将df1df2的行转换为集合。然后使用set减法定义新的DataFrame

idx1 = set(df1.set_index(['a', 'b']).index)
idx2 = set(df2.set_index(['a', 'b']).index)

pd.DataFrame(list(idx1 - idx2), columns=df1.columns)

   a  b
0  3  4

相关问题 更多 >