
分组统计告诉你每类花了多少但有时候你想更细——“吃饭里超过50的有几笔”“周末花了多少”“备注含’聚餐’的有哪些”小额中额大额各几笔这些全是筛选的问题。拿到数据90%的时间你不是全量分析而是先捞出关心的部分再处理。今天把最常用的8 个筛选场景整理成手册每个直接给代码和解释。用的还是账单数据先放这里做对照importpandasaspdimportnumpyasnp data{日期:[2024-01-05,2024-01-06,2024-01-07,2024-01-08,2024-01-09],类别:[餐饮,交通,餐饮,购物,餐饮],金额:[35.5,12.0,128.0,256.0,68.0],备注:[午餐,地铁,聚餐,衣服,晚饭]}dfpd.DataFrame(data)场景1按数值大小筛选找出金额大于100的消费resultdf[df[金额]100]方括号里的df[金额] 100返回一列 True/False布尔索引Pandas 自动留下 True 的行。比较运算符!都能用。后面所有高级筛选本质上都是在构造不同的布尔条件。场景2多个条件叠加且同时满足用金额大于100 并且 类别是餐饮。resultdf[(df[金额]100)(df[类别]餐饮)]或满足一个就行用|金额大于200 或者 类别是交通。resultdf[(df[金额]200)|(df[类别]交通)]非取反用~类别不是餐饮。resultdf[~(df[类别]餐饮)]⚠️ 每个条件都要用括号包起来否则运算符优先级会让结果全错。也不要用and/or整列逐元素运算要用/|。场景3从列表里挑类别是餐饮、交通、购物中的任意一个用isin()比写一堆|优雅resultdf[df[类别].isin([餐饮,交通,购物])]不在列表里前面加~resultdf[~df[类别].isin([餐饮,交通])]筛选类别、地区、状态这类离散值时特别好用。场景4按文本模糊查找Pandas 的str系列方法干这个。备注里包含餐字resultdf[df[备注].str.contains(餐)]开头结尾匹配df[df[备注].str.startswith(午)]# 以午开头df[df[备注].str.endswith(餐)]# 以餐结尾⚠️ 数据里有 NaN 时str.contains会返回 NaN 导致多出奇怪的行加naFalse就安全了df[df[备注].str.contains(聚餐,naFalse)]场景5按日期范围筛选先把日期列转成 datetimedf[日期]pd.to_datetime(df[日期])直接比较resultdf[(df[日期]2024-01-05)(df[日期]2024-01-07)]把日期设为索引后切片更优雅df_datedf.set_index(日期)print(df_date[2024-01])# 整个1月print(df_date[2024-01-05:2024-01-08])# 一段时间按星期筛选周六5周日6df[是周末]df[日期].dt.dayofweek5weekend_spenddf[df[是周末]][金额].sum()转成 datetime 后.dt.year.dt.month.dt.day.dt.dayofweek这些属性随便用。场景6用 loc 既筛选行又选列只看满足条件行的其中几列resultdf.loc[df[金额]100,[类别,金额]]格式是df.loc[行条件, 列条件]。loc 最大的好处是可以赋值比如给大额消费加标记列df.loc[df[金额]100,大额消费]是df.loc[df[金额]100,大额消费]否这个在数据清洗和特征工程里经常用。iloc按位置数字选日常 95% 场景用 loc 就够了。场景7分箱归类——把连续数据分成档想看消费档次分布小额/中额/大额各多少笔用pd.cut()bins[0,50,200,float(inf)]labels[小额(0-50),中额(50-200),大额(200)]df[消费档次]pd.cut(df[金额],binsbins,labelslabels)分箱完再 groupby分布就出来了resultdf.groupby(消费档次).agg(笔数(金额,count),总金额(金额,sum))n 个边界分成 n-1 个区间默认左开右闭rightFalse可改float(inf)接住最大值以上。场景8实战——拿完整账单回答4个问题先造一份31天的模拟数据np.random.seed(42)datespd.date_range(2024-01-01,2024-01-31,freqD)categories[餐饮,交通,购物,娱乐,居住,医疗]bills[]fordindates:for_inrange(np.random.randint(1,5)):catnp.random.choice(categories)ifcat居住:amountround(np.random.uniform(800,2500),2)elifcat医疗:amountround(np.random.uniform(50,500),2)elifcat购物:amountround(np.random.uniform(30,800),2)else:amountround(np.random.uniform(10,200),2)bills.append({日期:d,类别:cat,金额:amount})dfpd.DataFrame(bills)df[日期]pd.to_datetime(df[日期])四个问题全用今天讲的筛选技巧# Q1这个月吃饭花了多少food_totaldf[df[类别]餐饮][金额].sum()# Q2单笔超过200的有几笔big_countlen(df[df[金额]200])# Q3周末消费占比多少df[是周末]df[日期].dt.dayofweek5weekend_ratiodf[df[是周末]][金额].sum()/df[金额].sum()*100# Q4大额消费(100)集中在哪些类别bigdf[df[金额]100]resultbig.groupby(类别)[金额].agg([count,sum]).sort_values(sum,ascendingFalse)布尔索引、条件组合、日期属性、筛选后分组——组合起来就能回答绝大多数业务问题。真实运行效果把上面 8 个场景在同一份账单数据上实际跑一遍输出是这样的可以看到数值筛选只留下 128.0、256.0 两行 条件精确命中餐饮大额isin 一次捞回三类str.contains 按备注模糊匹配日期切片连续取出 5 到 8 号31 天 85 笔的实战里餐饮共花 2120.08、周末占比 24.2%大额消费按类别汇总居住最多。新手常见坑多条件忘了加括号→ 每个条件用括号包起来用 and/or 而不是 /|→ 整列运算要用位运算符筛选后索引乱了→ 用.reset_index(dropTrue)重置一张表总结8个场景场景核心写法按数值大小df[df[列] 值]多条件组合(条件1) (条件2)列表匹配df[df[列].isin([...])]文本模糊搜索df[列].str.contains(关键词)日期范围(df[日期] start) (df[日期] end)选行又选列df.loc[行条件, 列列表]连续数据分档pd.cut(数据, bins, labels)筛选后分析先筛选再 groupby下一篇讲结果导出——分析完的数据怎么导出成规整的 Excel 报表、多 Sheet 管理、透视表生成。梅雅达编程工作室 · Python数据实战系列第9篇筛选说到底就是构造条件条件会写了几万条数据里捞想要的那几条就是一行代码的事。