基于列值存在性判断为DataFrame添加新列的报错排查
解决方法
报错原因
你遇到的'str' object has no attribute 'isin'错误,是因为在lambda函数里的item['Option 2']是单个字符串值,而isin()是Pandas Series/DataFrame的专属方法,单个字符串没有这个属性。另外代码里的item['Option 1'].values()也完全错误——item是DataFrame的单行数据,item['Option 1']是单个值而非整个列,根本不存在values()方法。
正确实现方案
要基于整个Option 1列判断Option 2的值是否存在,最高效的方式是先提取Option 1列的所有非空值存为集合(集合的成员查找速度远快于列表),再通过多条件判断生成新列。以下提供两种实现方式:
方式1:用np.select实现(推荐,大数量级数据下远快于apply)
import pandas as pd import numpy as np # 先提取Option 1列的所有非空值,转成集合用于快速判断 option1_valid_values = set(full_quote_df['Option 1'].dropna()) # 定义判断条件列表 conditions = [ # 条件1:Supplier与Department相等,且Option 1非空 (full_quote_df['Supplier'] == full_quote_df['Department']) & pd.notna(full_quote_df['Option 1']), # 条件2:Supplier与Department相等,但Option 1为空 (full_quote_df['Supplier'] == full_quote_df['Department']) & pd.isna(full_quote_df['Option 1']), # 条件3:Supplier与Department不等,且Option 2存在于Option 1的有效值中 (full_quote_df['Supplier'] != full_quote_df['Department']) & full_quote_df['Option 2'].isin(option1_valid_values), # 条件4:Supplier与Department不等,且Option 2不存在于Option 1的有效值中 (full_quote_df['Supplier'] != full_quote_df['Department']) & ~full_quote_df['Option 2'].isin(option1_valid_values) ] # 对应条件的结果列表 choices = [ 'Keep Row', 'Do Not Keep Row', 'Keep Row', 'Do Not Keep Row' ] # 生成新列 full_quote_df['Keep Row'] = np.select(conditions, choices, default=None)
方式2:用apply实现(逻辑更直观,小数据量可用)
import pandas as pd # 提前获取Option 1列的非空值集合 option1_valid_values = set(full_quote_df['Option 1'].dropna()) full_quote_df['Keep Row'] = full_quote_df.apply( lambda row: 'Keep Row' if row['Supplier'] == row['Department'] and pd.notna(row['Option 1']) else 'Do Not Keep Row' if row['Supplier'] == row['Department'] and pd.isna(row['Option 1']) else 'Keep Row' if row['Supplier'] != row['Department'] and row['Option 2'] in option1_valid_values else 'Do Not Keep Row', axis=1 )
验证示例数据
将上述代码应用到你提供的示例DataFrame,会得到与预期完全一致的结果:
| Supplier | Department | Option 1 | Option 2 | Keep Row |
|---|---|---|---|---|
| Acme | Acme | Monday | Tuesday | Keep Row |
| Acme | Acme | Wednesday | Keep Row | |
| Acme | HR | Monday | Wednesday | Keep Row |
| Acme | HR | Tuesday | Wednesday | Keep Row |
| Acme | HR | Tuesday | Thursday | Do Not Keep Row |
内容的提问来源于stack exchange,提问作者Stephen Juza
相关产品推荐
相关产品推荐

