对比列名相同的两个DataFrame时触发ValueError错误
解决DataFrame过滤时的ValueError问题
首先,咱们先搞清楚你遇到的错误原因:你写的df.loc[df['Permit Number'] != df1['Permit Number']]是在尝试逐行对比两个Permit Number列,但Pandas要求对比的两个Series必须有完全一致的索引(标签)和长度,否则就会抛出ValueError: Can only compare identically-labeled Series object。显然你的df和df1的Permit Number列内容、索引都不匹配,这种逐行对比的方式根本不符合你的需求。
你的核心需求是删除df中所有Permit Number值在df1里出现过的行,正确的做法应该是先提取df1中所有的Permit Number值,然后用isin()方法筛选df中不在这个集合里的行,这才是高效且符合逻辑的方式。
完整的正确代码示例
首先先重现你的示例数据(方便测试):
import pandas as pd import numpy as np # 构建你的df df = pd.DataFrame({ 'Permit Number': ['BLD-00045', 'ELE-2019', 'PLM-2018'], 'Sub Permit': [np.nan, 'BLD-00045', 'BLD-00045'] }) # 构建你的df1(不管你是合并得到还是其他方式,只要结构正确就行) df1 = pd.DataFrame({ 'Permit Number': ['BLD-00001', 'ELE-2019', 'PLM-7777'], 'Sub Permit': [np.nan, 'BLD-00045', 'BLD-00045'] })
然后执行过滤操作:
# 筛选出df中Permit Number不在df1中的行 filtered_df = df[~df['Permit Number'].isin(df1['Permit Number'])] print(filtered_df)
运行后你会得到想要的结果:
Permit Number Sub Permit 0 BLD-00045 NaN 2 PLM-2018 BLD-00045
为什么你的原代码不行?
- 你用
set_index('Permit Number', inplace=False)的时候,并没有修改原df和df1,因为inplace=False会返回一个新的DataFrame,原对象保持不变,所以这两行代码相当于白写了。 - 就算你真的把索引改成了Permit Number,直接对比
df['Permit Number'] != df1['Permit Number']也没有意义,因为两个DataFrame的索引值(Permit Number)并不完全重合,Pandas无法对应逐行对比。 - 而
isin()方法是检查每个元素是否存在于目标集合中,不需要索引匹配,完全贴合你的需求:找出所有不在df1的Permit Number里的行。
内容的提问来源于stack exchange,提问作者SpindriftSeltzer
相关产品推荐
相关产品推荐

