我有两个Pandas数据框;我们称一个old_df
和另一个new_df
。我想突出显示new_df
中不存在的old_df
中的行。例如:
import pandas as pd
old_df = pd.DataFrame({'m':[1,2,3,4,5,6],
'n':['a','b','c','d','e','f']})
new_df = pd.DataFrame({'m':[2,5,7,8],
'n':['b','e','g','h']})
这些数据框如下:
m n
0 1 a
1 2 b
2 3 c
3 4 d
4 5 e
5 6 f
和
m n
0 2 b
1 5 e
2 7 g
3 8 h
我想为new_df
生成一个掩码,以指示该行是否已经存在于old_df
中,例如:
0 True
1 True
2 False
3 False
我已经能够将列作为字符串连接为单个字符串值,以产生两个Pandas系列,然后在两个系列上使用.isin()
,如下所示:
msk = pd.Series(new_df['m'].astype(str) + new_df['n']).isin(pd.Series(old_df['m'].astype(str) + old_df['n']))
print(msk)
产生:
0 True
1 True
2 False
3 False
dtype: bool
这是正确的结果,但过于丑陋以致无法给出最佳答案。我以为.isin()
也可以在数据帧上工作,但我无法使它工作。
有什么建议吗?
答案 0 :(得分:2)
如果新数据框中没有重复的数据,则可以将它们串联起来并检查是否重复:
(pd.concat([d.assign(is_old=n) for d,n in zip((old_df,new_df), ('old','new'))])
.assign(from_old=lambda x: x.duplicated(['m','n']))
.query('is_old=="new"')
)
输出:
m n is_old from_old
0 2 b new True
1 5 e new True
2 7 g new False
3 8 h new False
或者您可以将merge
与indicator=True
一起使用:
(old_df.merge(new_df, on=['m','n'], how='right', indicator=True)
.assign(from_old=lambda x: x['_merge']=='both')
)
输出:
m n _merge from_old
0 2 b both True
1 5 e both True
2 7 g right_only False
3 8 h right_only False
答案 1 :(得分:1)
您可以进行merge
并比较index
:
new_df["status"] = new_df.index.isin(new_df.merge(old_df,on=["m","n"]).index)
print (new_df)
m n status
0 2 b True
1 5 e True
2 7 g False
3 8 h False
答案 2 :(得分:1)
您可以这样做:
mask = []
for index, row in new_df.iterrows():
mask.append((old_df == np.array(row)).all(1).any())
print(mask)
答案 3 :(得分:1)
set
创建一个set
并检查收容措施
s = set(zip(*map(old_df.get, new_df)))
mask = [t in s for t in zip(*map(new_df.get, new_df))]
new_df.assign(status=mask)
m n status
0 2 b True
1 5 e True
2 7 g False
3 8 h False
s
是old_df
中所有元组形式的所有行的集合。我们注意确保这些元组中的项目顺序与new_df
print(s)
{(5, 'e'), (3, 'c'), (4, 'd'), (2, 'b'), (6, 'f'), (1, 'a')}
mask
是一个列表理解,它检查new_df
中的每一行(作为元组),并查看它是否存在于我们的s
print(mask)
[True, True, False, False]