Pandas:筛选仅单一类别含'a'的行并生成统计列
Pandas数据筛选与标注解决方案
这里给你一套简洁高效的代码,完美实现你需要的行筛选、类别标注和占比计算需求:
import pandas as pd # 1. 定义类别与原始数据 colors = ['green', 'red'] animals = ['cat', 'dog'] largedf = pd.DataFrame({ 'arow': ['row1', 'row2', 'row3', 'row4'], 'green': ['a', 'b', 'b', 'a'], 'red': ['a', 'b', 'b', 'a'], 'cat': ['b', 'a', 'b', 'a'], 'dog': ['b', 'a', 'b', 'a'] }) # 2. 计算每个类别下每行的'a'出现次数 largedf['colors_a_count'] = largedf[colors].eq('a').sum(axis=1) largedf['animals_a_count'] = largedf[animals].eq('a').sum(axis=1) # 3. 筛选符合条件的行:'a'仅存在于单个类别中 filter_mask = ( (largedf['colors_a_count'] > 0) & (largedf['animals_a_count'] == 0) | (largedf['animals_a_count'] > 0) & (largedf['colors_a_count'] == 0) ) shorterdf = largedf[filter_mask].copy() # 4. 添加category标注列 shorterdf['category'] = shorterdf.apply( lambda row: 'colors' if row['colors_a_count'] > 0 else 'animals', axis=1 ) # 5. 添加percent占比列 def calc_percent(row): category_cols = colors if row['category'] == 'colors' else animals return row[f"{row['category']}_a_count"] / len(category_cols) shorterdf['percent'] = shorterdf.apply(calc_percent, axis=1) # 6. 清理辅助列并调整列顺序 shorterdf = shorterdf.drop(['colors_a_count', 'animals_a_count'], axis=1) shorterdf = shorterdf[['arow', 'cat', 'dog', 'green', 'red', 'category', 'percent']] # 查看结果 print(shorterdf)
运行后输出完全匹配你的期望:
arow cat dog green red category percent 0 row1 b b b a colors 0.5 1 row2 a a b b animals 1.0
关键步骤逻辑拆解
- 计算类别内'a'次数:用
eq('a')把每个单元格转换成布尔值,再按行求和,快速定位每行在对应类别里的'a'数量,为后续筛选打基础。 - 筛选条件设计:精准锁定「仅一个类别有'a'」的行——要么
colors有a且animals无a,要么animals有a且colors无a,直接排除了全'b'(两个类别计数均为0)和全'a'(两个类别计数均>0)的无效行。 - 类别标注:通过简单的条件判断,根据哪个类别存在'a'来标记对应的category,逻辑清晰易懂。
- 占比计算:用该类别内'a'的数量除以类别总列数(比如colors有2列,row1的0.5就是1/2),完全贴合你对占比的定义。
内容的提问来源于stack exchange,提问作者Liquidity
相关产品推荐
相关产品推荐

