pandas筛选符合多条件的DataFrame行报KeyError:True如何解决
问题解决:Pandas按code分组筛选符合条件的serial=2行
错误原因
你原来的写法存在两个核心问题:
- 把serial设为全局索引后,
data.new[2]取的是全表所有索引为2的行的new列(多值Series),和data.sold[1]比较得到的布尔序列长度和原表不匹配,直接索引原表就会触发KeyError - 没有按code做组内匹配,你的条件中
sold[1]指的是同code分组下serial=1的sold值,不是全局serial=1的sold值
正确实现方案
首先建议先将serial从索引重置为普通列,方便分组处理:
data = data.reset_index()
方案1:groupby + filter(逻辑直观易读)
自定义分组筛选逻辑,直接匹配你的业务规则:
def match_rule(group): # 跳过不同时包含serial=1、2的分组 if not {1, 2}.issubset(group['serial'].values): return False # 取当前组serial=1的sold值 sold_serial1 = group.loc[group['serial'] == 1, 'sold'].iloc[0] # 取当前组serial=2的行 serial2_row = group.loc[group['serial'] == 2] # 校验两个条件 return (serial2_row['new'].iloc[0] >= sold_serial1) & (serial2_row['new'].iloc[0] < serial2_row['sold'].iloc[0]) # 筛选符合条件的分组,最终只保留serial=2的行 result = data.groupby('code').filter(match_rule).query('serial == 2') print(result)
方案2:transform广播值(写法简洁高效)
通过transform把组内serial=1的sold值广播到所有行,直接筛选:
# 按code分组,将每组serial=1的sold值广播到组内所有行 data['sold_serial1'] = data.groupby('code')['sold'].transform(lambda x: x[data['serial'] == 1].iloc[0]) # 直接按条件过滤 result = data[(data['serial'] == 2) & (data['new'] >= data['sold_serial1']) & (data['new'] < data['sold'])].drop('sold_serial1', axis=1) print(result)
两种方案都可以得到你预期的code为20286、serial为2的结果。
内容的提问来源于stack exchange,提问作者Rabe
相关产品推荐
相关产品推荐

