修正Pandas代码:筛选df1中IP和ID与df不匹配的完整数据
我来帮你搞定这个问题~
问题出在哪?
你现在用的df1[~df1.isin(df)].dropna(how = 'all')是逐元素检查是否在df的对应列中,而不是判断「IP和ID的组合同时匹配」。比如前3行的IP、ID、Name在df里存在,所以这些列被标记为NaN,但df里没有Installed和Price列,所以这两列保留了,就出现了你看到的半NaN结果,这完全不是你要的「整行IP+ID都不匹配」的筛选逻辑。
两种正确的修改方式
方式一:用merge做反连接(推荐,逻辑清晰)
通过左连接df1和df的IP、ID列,然后筛选出只在df1中存在的行:
import pandas as pd import openpyxl df = pd.DataFrame ({ 'IP':['1.1.1.1','2.2.2.2','3.3.3.3'], 'ID':['101','202','303'], 'Name':['atlas','amida','ubuntu'] }) df1 = pd.DataFrame ({ 'IP':['1.1.1.1','2.2.2.2','3.3.3.3','4.4.4.4','5.5.5.5'], 'ID':['101','202','303','404','505'], 'Name':['atlas','amida','ubuntu','canvas','smash'], 'Installed':['yes','no','yes','no','yes'], 'Price':[100,200,300,400,500] }) # 左连接只匹配IP和ID列,添加_merge标记来源 merged = df1.merge(df[['IP', 'ID']], on=['IP', 'ID'], how='left', indicator=True) # 筛选出仅在df1中存在的行,去掉标记列 result = merged[merged['_merge'] == 'left_only'].drop(columns='_merge') print(result)
方式二:检查IP+ID的组合元组
把df里的IP和ID打包成元组,然后判断df1的对应组合是否不在这个列表里:
import pandas as pd import openpyxl df = pd.DataFrame ({ 'IP':['1.1.1.1','2.2.2.2','3.3.3.3'], 'ID':['101','202','303'], 'Name':['atlas','amida','ubuntu'] }) df1 = pd.DataFrame ({ 'IP':['1.1.1.1','2.2.2.2','3.3.3.3','4.4.4.4','5.5.5.5'], 'ID':['101','202','303','404','505'], 'Name':['atlas','amida','ubuntu','canvas','smash'], 'Installed':['yes','no','yes','no','yes'], 'Price':[100,200,300,400,500] }) # 生成df中IP+ID的组合元组列表 valid_combinations = list(zip(df['IP'], df['ID'])) # 筛选df1中不在组合列表里的行 result = df1[~df1[['IP', 'ID']].apply(tuple, axis=1).isin(valid_combinations)] print(result)
最终输出
两种方法都会得到你想要的正确结果:
IP ID Name Installed Price 3 4.4.4.4 404 canvas no 400 4 5.5.5.5 505 smash yes 500
内容的提问来源于stack exchange,提问作者MMarie
相关产品推荐
相关产品推荐

