是否还在为脏数据导致的分析卡壳而加班到深夜?是否还在手动删除重复值、填补空值耗费数小时?是否因为数据格式混乱导致报表统计出错被领导质疑?
真相是:效率高手与普通职员的根本差距,不在于熬夜的时长,而在于是否掌握核心工具的高效用法。今天,我们不谈复杂的机器学习,只聚焦于你每天都在用的 Pandas—— 这 8 个技巧,能让你从 2 小时的手动清洗压缩到 5 分钟,脏数据秒变可用。
如果你也曾因为报表里莫名其妙的空值、乱码,导致对不上账被领导叫去谈话;如果你也对着几千行数据手动按 Delete 键按到手指痛……
点个赞吧,当做咱们“苦命打工人”相认的暗号。今天这篇,我保证帮你把失去的时间抢回来。
1. 缺失值处理:别再直接 dropna ()
import pandas as pd# 加载用户调研数据,空值比有效数据还多df = pd.read_csv('user_survey.csv')# 方案1:按业务逻辑填充,比如用中位数填充数值型,用"未知"填充类别型df['年龄'] = df['年龄'].fillna(df['年龄'].median())df['职业'] = df['职业'].fillna('未知')# 方案2:只删除关键列空值,保留其他数据df = df.dropna(subset=['用户ID', '手机号'])# 这破数据,之前直接dropna()丢了30%样本,被领导骂惨了代码讲解:
- fillna() 比直接 dropna() 更灵活,数值型字段用中位数填充避免均值受极端值影响,类别型用 “未知” 标记比丢失数据更有分析价值。
- dropna(subset=[]) 指定只删除关键列的空值,比如用户 ID 和手机号是必填项,其他字段空值可以保留后续分析。
注意事项:
- 不要全局使用 dropna(),除非你能确定空值完全无业务价值。
- 时间序列数据可以直接用 .ffill() 或 .bfill() 按前后值填充,比填 method 参数更简洁,适合连续数据场景。
# 电商订单数据,用户重复提交导致大量重复订单df = pd.read_csv('orders.csv')# 正确姿势:按订单号去重,保留最早的那条df = df.drop_duplicates(subset=['订单号'], keep='first')# 踩过的坑:之前没指定subset,把不同用户的相似订单误删了代码讲解:
- drop_duplicates(subset=[]) 指定去重的判断依据,比如订单号是唯一标识,只需要按这个列去重。
- keep='first' 保留第一次出现的记录,适合用户重复提交的场景;如果要保留最新记录用 keep='last'。
注意事项:
- 去重前要确认重复值的产生原因:是用户误操作还是系统 bug?不同原因可能需要不同处理逻辑。
- 可以用 df.duplicated(subset=['订单号']).sum() 先查看重复数量,再决定是否去重。
# 报表数据,日期是字符串格式,金额带"元"字df = pd.read_csv('sales_report.csv')# 日期转换:自动识别多种格式,失败的标记为NaTdf['下单日期'] = pd.to_datetime(df['下单日期'], errors='coerce')# 金额转换:先去掉"元"字,再转数值,失败的标记为NaNdf['金额'] = pd.to_numeric(df['金额'].str.replace('元', ''), errors='coerce')# 之前用astype()硬转,遇到非数值直接报错,白干1小时代码讲解:
- pd.to_datetime() 比 astype('datetime64[ns]') 更智能,能自动识别多种日期格式,errors='coerce' 把转换失败的标记为 NaT 方便后续处理。
- pd.to_numeric() 配合 str.replace() 先清理字符串再转数值,比直接 astype(float) 容错性更高。
注意事项:
- 转换前一定要用 df.dtypes 查看当前数据类型,避免无效转换。
- 对于混合类型的列,先清理特殊字符再转换,比如金额中的 “¥”、“$” 等符号。
说真的,这年头系统导出的数据真是五花八门。金额里带“元”字的我都忍了,最离谱的是,我上次收到的表里,日期列里竟然混进去了两行表情包! 直接导致整列代码报错。
你们平时收到的表格里,遇到过什么反人类的数据格式?在评论区吐槽一下,我看看谁碰到的最奇葩!
4. 字符串处理:正则表达式是清理神器
# 用户数据,手机号格式混乱,有空格、横杠、括号df = pd.read_csv('users.csv')# 一招清理所有非数字字符,统一为纯数字手机号df['手机号'] = df['手机号'].str.replace(r'\D', '', regex=True)# 清理姓名前后空格,之前因为空格导致匹配不到用户df['姓名'] = df['姓名'].str.strip()# 这破数据,手机号格式能有十几种,服了代码讲解:
- str.replace(r'\D', '', regex=True) 用正则匹配所有非数字字符,一次性清理掉空格、横杠、括号等特殊符号。
- str.strip() 清理字符串前后的空格,避免因为输入时的空格导致数据匹配失败。
注意事项:
- Pandas 的 str 方法需要列是字符串类型,转换前可以用 df['手机号'] = df['手机号'].astype(str) 确保类型正确。
- 正则表达式要测试后再用,避免误删有效字符,比如不要把手机号中的 “86” 前缀也删掉。
# 销售数据,存在异常高值(比如测试数据或刷单)df = pd.read_csv('sales_data.csv')# 用百分位数法过滤异常值,直接掐头去尾保留中间90%的数据q1 = df['销售额'].quantile(0.05)q3 = df['销售额'].quantile(0.95)df = df[(df['销售额'] >= q1) & (df['销售额'] <= q3)]# 之前用固定阈值比如>10000就删,结果把真实的大订单误删了代码讲解:
- 百分位数法比固定阈值更科学,能根据数据分布自动调整过滤范围,避免误删有效数据。
- quantile(0.05) 和 quantile(0.95) 保留中间 90% 的数据,适合大多数业务场景;如果需要更严格可以用 0.01 和 0.99。
注意事项:
- 异常值处理前要先分析原因:是真实业务还是数据错误?真实的大订单不应该被过滤。
- 可以用箱线图可视化查看异常值分布:import seaborn as sns; sns.boxplot(x=df['销售额'])
# 用户地址数据,格式是"北京市朝阳区XX街道",需要拆分成省市区df = pd.read_csv('user_address.csv')# 拆分地址为省、市、区三列df[['省', '市', '区']] = df['地址'].str.split(' ', expand=True, n=2)# 合并多列为完整地址,处理空值df['完整地址'] = df[['省', '市', '区']].apply(lambda x: ' '.join(x.dropna()), axis=1)# 之前手动拆分花了2小时,现在一行代码搞定,爽代码讲解:
- str.split(expand=True, n=2) 把字符串拆分成多列,n=2 指定最多拆分 2 次,避免区后面的街道也被拆分。
- apply(lambda x: ' '.join(x.dropna()), axis=1) 按行合并多列,自动跳过空值,比 str.cat() 更灵活。
注意事项:
- 拆分前要确认字符串的分隔符一致,比如有的用空格有的用 “省”" 市 ",需要先统一格式。
- 拆分后的列可能有空值,需要用 fillna() 处理或者删除无效行。
以上这 6 招,对付 90% 的脏数据已经绰绰有余了。但是!
每次我发这种代码,评论区有人会质疑,说:“处理这几千行数据,我用 Excel 的筛选和替换也能做,还学 Python 干啥。”
对于这种观点,你们怎么看?几十万行数据的时候,Excel 不卡吗?你是坚定站 Python,还是觉得 Excel 够用就行?在评论区报个坐标,咱们聊聊!
7. 脏乱表头清洗:别让系统导出的列名逼疯你
# 系统导出的列名经常带空格、换行符、甚至乱码df.columns = df.columns.str.strip().str.replace('\n', '').str.replace(' ', '_')# 统一改为大写,防止大小写混乱导致合并失败df.columns = df.columns.str.upper()# 这谁设计的导出格式,列名能有这么多奇葩符号,醉了代码讲解:
- df.columns 直接操作列名,用 str.strip() 清理前后空格,str.replace('\n', '') 去掉换行符,str.replace(' ', '_') 把空格换成下划线,统一列名格式。
- str.upper() 把所有列名改成大写,避免因为大小写不一致导致后续数据合并、筛选时出错。
注意事项:
- 处理列名前要先查看当前列名:print(df.columns),确保修改符合预期。
- 如果列名有特殊字符比如中文括号、全角符号,可以用 str.replace(r'[()()]', '', regex=True) 批量清理。
- 处理混合类型数据时,可以用 df.map(lambda x: x.strip() if isinstance(x, str) else x)(注意:Pandas 2.1.0+ 已用 map 替代了 applymap)
*注:严格来说,标准化属于特征工程范畴,但在实际数据清洗流程中,我们通常把它作为交给算法模型前的最后一步处理。*
# 多维度数据,销售额和订单数量量级差异大,无法直接比较df = pd.read_csv('multi_dim_data.csv')# 标准化处理:(值-均值)/标准差,让均值为0,标准差为1from sklearn.preprocessing import StandardScalerscaler = StandardScaler()df[['销售额', '订单数量']] = scaler.fit_transform(df[['销售额', '订单数量']])# 或者手动标准化,不需要导入sklearndf['销售额_标准化'] = (df['销售额'] - df['销售额'].mean()) / df['销售额'].std()# 之前直接用原始数据做分析,结果被量级大的销售额主导了,白忙活代码讲解:
- StandardScaler() 适合需要进行机器学习建模或多维度比较的场景,让不同量级的特征具有可比性。
- 手动标准化的公式更透明,适合不需要复杂预处理的场景,避免依赖第三方库。
注意事项:
- 标准化只适合数值型字段,不要对类别型或日期型字段使用。
- 标准化后的数据是无量纲的,适合用于聚类、回归等模型,不适合直接用于业务报表。
职场上有个残酷的真相:你加班熬夜做出来的表,和一个用 5 分钟代码跑出来的人做出来的表,在老板眼里可能没区别。
效率的差距,本质上是工具的差距。
这 8 段代码,不建议死记硬背。但强烈建议你点个【收藏】!
把它当成你的“线上急救箱”,下次老板急要数据、或者遇到乱码表格卡住时,翻出来抄两行,5 分钟搞定,剩下的时间,拿去摸鱼喝咖啡不香吗?
觉得有道理,别忘了点赞关注,以后遇到数据难题,知道去哪里找答案!
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.