删除python 3中另一个data.frame中的data.frame行的确切行和频率

时间:2017-10-13 13:50:10

标签: python python-3.x pandas dataframe

考虑在python 3中使用pandas创建的以下两个data.frame:

a1 = pd.DataFrame(({'A': [1, 2, 3, 4, 5, 2, 4, 2], 'B': ['a', 'b', 'c', 'd', 'e', 'b', 'd', 'b']}))
a2 = pd.DataFrame(({'A': [1, 2, 3, 2], 'B': ['a', 'b', 'c', 'b']}))

我想删除a2中a1的确切行,以便结果应为:

A B
4 d
5 e
4 d
2 b

请注意,在最终结果中保留了a1中包含2 b的一行(基本上只有一行会被a2中的一行取消)。在pandas或python 3中的任何其他库中是否有任何内置函数来获得此结果?

2 个答案:

答案 0 :(得分:1)

使用listremove

的定义
l1=a1.values.tolist()
l2=a2.values.tolist()
for x in l2:
    l1.remove(x)

pd.DataFrame(l1,columns=a1.columns)

Out[173]: 
   A  B
0  4  d
1  5  e
2  4  d
3  2  b

时间

巴拉斯' S 第一

start_time = timeit.default_timer()
a1['count'] = a1.groupby(['A','B']).cumcount()
a2['count'] = a2.groupby(['A','B']).cumcount()
df = (pd.merge(a1,a2, indicator=True, how='left')
        .query("_merge != 'both'")
        .drop(['_merge','count'], 1))
print(timeit.default_timer() - start_time)
0.012827654755454887

第二

start_time = timeit.default_timer()
a1['count'] = a1.groupby(['A','B']).cumcount()
a2['count'] = a2.groupby(['A','B']).cumcount()
i = a1.index.difference(a1.merge(a2,on=['A','B','count']).index)
df = a1.loc[i].drop('count',1)
print(timeit.default_timer() - start_time)
0.05914717068662867

第三

start_time = timeit.default_timer()
a1['count'] = a1.groupby(['A','B']).cumcount()
a2['count'] = a2.groupby(['A','B']).cumcount()
df =pd.DataFrame(pd.Index(a1).difference(pd.Index(a2)).tolist(),columns=a2.columns).drop(['count'],1)
print(timeit.default_timer() - start_time)
0.006586597486375467

矿:

start_time = timeit.default_timer()
l1=a1.values.tolist()
l2=a2.values.tolist()
for x in l2:
    l1.remove(x)
pd.DataFrame(l1,columns=a1.columns)
print(timeit.default_timer() - start_time)
0.0028012795203835594

数据输入100次样本。

a1=pd.concat([a1]*100,axis=0)
a2=pd.concat([a2]*100,axis=0)

答案 1 :(得分:1)

让我们使用groupby cumcount:

a1['count'] = a1.groupby(['A','B']).cumcount()
a2['count'] = a2.groupby(['A','B']).cumcount()

选项1 - 合并和查询

df = (pd.merge(a1,a2, indicator=True, how='left')
        .query("_merge != 'both'")
        .drop(['_merge','count'], 1))

选项2 - 合并后的指数差异即

i = a1.index.difference(a1.merge(a2,on=['A','B','count']).index)
df = a1.loc[i].drop('count',1)

选项3 - 完成@ John Zwinck的方法

df =pd.DataFrame(pd.Index(a1).difference(pd.Index(a2)).tolist(),columns=a2.columns).drop(['count'],1)

输出:

  A  B
3  4  d
4  5  e
6  4  d
7  2  b