我有两个熊猫数据框。可以说第一个是master
ID COL1 COL2
1 A AA
2 B BB
3 C CC
4 D DD
另外一个source
ID COL1 COL2
1 A ZZ
2 B BB
3 YY CC
5 G GG
6 H HH
显然,长度可以不同,并且差异可以超过一列。但是,结构将相同。我想在source
中找到新记录,或者与master
中可用的记录不同。也就是说,我正在寻找的输出是一个数据帧:
ID COL1 COL2
1 A ZZ
3 YY CC
5 G GG
6 H HH
我尝试了以下解决方案:
但是这些似乎都不对我有用。基本上,这是在尝试找出新功能。
答案 0 :(得分:2)
您可以创建遮罩并使用boolean indexing
:
# set index
source = source.set_index('ID')
master = master.set_index('ID')
# find any record across rows where source is not in master
mask = (~source.isin(master)).any(1)
# boolean indexing
source[mask]
COL1 COL2
ID
1 A ZZ
3 YY CC
5 G GG
6 H HH
答案 1 :(得分:1)
将merge
与indicator=True
和outer join
一起使用,然后按df2.columns
过滤并仅获取列:
#specified columns in list
cols = ['COL1','COL2']
#all columns without ID
#cols = df.columns.difference(['ID'])
df = (df1.merge(df2, on=cols, how='outer', indicator=True, suffixes=('_',''))
.query("_merge == 'right_only'")[df2.columns])
print (df)
ID COL1 COL2
4 1.0 A ZZ
5 3.0 YY CC
6 5.0 G GG
7 6.0 H HH
答案 2 :(得分:1)
有几种方法可以解决此问题,具体取决于您处理内存分配的方式以及打算使用大型数据集还是仅出于学术/培训目的。
这些只是两个主意,但可能还有更多主意,仅是为了提供一个见解。
解决方案1 :(考虑到ID是唯一的而不是索引)
list = source['ID'].tolist() #get a list of all the ids in source
results = pd.DataFrame(columns = source.columns.tolist()) #Creates an empty df with same columns
for id in list:
if(~((source[id]['COL1'] == master[id]['COL1']) & (source[id]['COL2'] == master[id]['COL2']))):
#Here we evaluate the cases where everything is equal and execute on negation of said statement (by using ~, which equates to NOT)
results.append(source[id])
解决方案2:
results = source.merge(master, how = 'outer', on= source.columns.tolist()) #assuming both dfs have same columns
final_results = results.drop_duplicates(Keep = False) #this will drop all rows that are duplicated.