Pandas查询语句布尔逻辑应用:筛选重复Name的有效行
解决思路与代码实现
首先,先梳理下你的核心需求:从合并后的DataFrame中,保留**Name出现次数≥2**的行,同时(根据你的尝试)结合价格差异的过滤条件,最终整理成指定的列格式。
先看你之前尝试的问题:
- 方法1里
Name > 1是拿字符串和整数比较,逻辑完全错误,必然报错; - 方法2里
ds[Price_x]没给Price_x加引号,Python会把它当成未定义的变量,所以触发NameError; - 方法3里
ds['Name'].value_counts() > 1返回的是一个以Name为索引的Series,和原DataFrame的行索引不匹配,没法直接做布尔过滤,所以得到空结果。
下面是正确的实现步骤:
1. 先整理列名(让数据更贴合你的期望格式)
首先把合并后带_x的列重命名成目标列名,同时保留需要的字段:
# 重命名重复列名 ds = ds.rename(columns={ 'Date_x': 'Date', 'Invoice_x': 'Invoice', 'Coupon_x': 'Coupon', 'Location_x': 'Location' }) # 只保留你需要的列 ds = ds[['Date', 'Invoice', 'Name', 'Coupon', 'Location', 'Price']]
2. 过滤Name出现次数大于1的行
这里要用groupby + transform来给每一行标记对应Name的出现次数,这样能保证标记和原DataFrame的行完全对齐:
# 给每一行添加对应Name的出现次数 ds['name_count'] = ds.groupby('Name')['Name'].transform('count') # 过滤出Name出现次数>1的行,同时去掉临时添加的name_count列 ds = ds[ds['name_count'] > 1].drop('name_count', axis=1)
3. 结合价格过滤条件(如果需要)
如果确实需要保留Price_x != Price_y的行,注意要给列名加引号(避免变量未定义错误),把两个条件结合起来:
# 假设你合并后的DataFrame有Price_x和Price_y列 ds = ds[ (ds['Price_x'] != ds['Price_y']) & (ds.groupby('Name')['Name'].transform('count') > 1) ]
完整代码示例
# 处理合并后的DataFrame ds # 1. 整理列名 ds = ds.rename(columns={ 'Date_x': 'Date', 'Invoice_x': 'Invoice', 'Coupon_x': 'Coupon', 'Location_x': 'Location' }) ds = ds[['Date', 'Invoice', 'Name', 'Coupon', 'Location', 'Price']] # 2. 过滤Name出现次数>1的行,同时可选加入价格过滤条件 ds_filtered = ds[ (ds.groupby('Name')['Name'].transform('count') > 1) # 如需价格差异过滤,取消下面注释 # & (ds['Price_x'] != ds['Price_y']) ].dropna(subset=['Date', 'Invoice']) # 去掉含缺失值的行(对应Sue Simpson的记录) # 3. 重置索引(可选,让结果更整洁) ds_filtered = ds_filtered.reset_index(drop=True)
运行后就能得到你期望的输出格式啦。
内容的提问来源于stack exchange,提问作者HMLDude
相关产品推荐
相关产品推荐

