影刀RPA 数据清洗入门:缺失值与异常值处理
📅 2026/7/17 15:49:00
👁️ 阅读次数
📝 编程学习
影刀RPA 数据清洗入门:缺失值与异常值处理
作者:林焱
什么情况用什么
从网页采集或从各系统导出的原始数据,总有各种问题——空值、乱码、格式不统一、明显错误的数据(年龄200岁、金额负数)。直接用这些数据做报表会闹笑话。在影刀RPA里用pandas做数据清洗是自动化流程中必不可少的一步。
适用场景:采集数据后清洗、多源数据合并前标准化、报表生成前数据校验、异常数据筛查。
怎么做
拼多多店群自动化报活动上架!
缺失值处理
importpandasaspdimportnumpyasnp df=pd.read_excel(r"C:\Data\raw_data.xlsx")# 1. 检查缺失值print("缺失值统计:")print(df.isnull().sum())print(f"\n总行数:{len(df)}")print(f"完全空行:{df.isnull().all(axis=1).sum()}")# 2. 删除缺失值# 删除任何列有缺失的行df_drop_any=df.dropna()# 只删除关键字段缺失的行df_drop_key=df.dropna(subset=['订单号','金额'])# 删除全为空的行df_drop_empty=df.dropna(how='all')# 3. 填充缺失值# 用固定值填充df['备注']=df['备注'].fillna('无')# 用均值填充df['年龄']=df['年龄'].fillna(df['年龄'].mean())# 用中位数填充(更抗异常值)df['工资']=df['工资'].fillna(df['工资'].median())# 用前一行/后一行的值填充df['温度']=df['温度'].fillna(method='ffill')# 前向填充df['温度']=df['温度'].fillna(method='bfill')# 后向填充# 用分组均值填充(按部门填平均工资)df['工资']=df.groupby('部门')['工资'].apply(lambdax:x.fillna(x.mean()))异常值检测与处理
defdetect_outliers(df,column,method='iqr'):"""检测异常值"""ifmethod=='iqr':# IQR方法:超出[Q1-1.5*IQR, Q3+1.5*IQR]的为异常Q1=df[column].quantile(0.25)Q3=df[column].quantile(0.75)IQR=Q3-Q1 lower=Q1-1.5*IQR upper=Q3+1.5*IQR outliers=df[(df[column]<lower)|(df[column]>upper)]elifmethod=='zscore':# Z-Score方法:|Z|>3的为异常fromscipyimportstats z_scores=np.abs(stats.zscore(df[column].dropna()))outlier_indices=df[column].dropna().index[z_scores>3]outliers=df.loc[outlier_indices]elifmethod=='range':# 固定范围方法# 需要传入合理范围outliers=df[(df[column]<0)|(df[column]>1000000)]returnoutliers# 检测金额异常amount_outliers=detect_outliers(df,'金额',method='iqr')print(f"金额异常值:{len(amount_outliers)}条")# 处理异常值defhandle_outliers(df,column,method='clip'):"""处理异常值"""Q1=df[column].quantile(0.25)Q3=df[column].quantile(0.75)IQR=Q3-Q1 lower=Q1-1.5*IQR upper=Q3+1.5*IQRifmethod=='clip':# 截断到合理范围df[column]=df[column].clip(lower,upper)elifmethod=='remove':# 删除异常行df=df[(df[column]>=lower)&(df[column]<=upper)]elifmethod=='median':# 用中位数替换df.loc[(df[column]<lower)|(df[column]>upper),column]=df[column].median()returndf df=handle_outliers(df,'金额',method='clip')格式清洗
defclean_data(df):"""数据清洗主函数"""# 1. 去除首尾空格text_cols=df.select_dtypes(include=['object']).columnsforcolintext_cols:df[col]=df[col].astype(str).str.strip()# 替换"nan"字符串为真正的空值df[col]=df[col].replace({'nan':None,'None':None,'':None})# 2. 数字清洗if'金额'indf.columns:df['金额']=df['金额'].astype(str).str.replace(',','')df['金额']=df['金额'].str.replace('¥','').str.replace('¥','')df['金额']=pd.to_numeric(df['金额'],errors='coerce')# 3. 日期清洗if'日期'indf.columns:df['日期']=pd.to_datetime(df['日期'],errors='coerce')# 4. 手机号清洗if'手机号'indf.columns:df['手机号']=df['手机号'].astype(str).str.replace(r'[^0-9]','',regex=True)df['手机号']=df['手机号'].str.extract(r'(1[3-9]\d{9})')# 5. 去除完全重复的行df=df.drop_duplicates()# 6. 重置索引df=df.reset_index(drop=True)returndf# 使用df=pd.read_excel(r"C:\Data\raw_data.xlsx")df_clean=clean_data(df)df_clean.to_excel(r"C:\Data\cleaned_data.xlsx",index=False)影刀RPA完整清洗流程
【读取Excel文件】→ raw_data.xlsx 【执行Python代码】→ 数据清洗 1. 缺失值检查与处理 2. 异常值检测与处理 3. 格式标准化 4.  5. 去重 【写入Excel文件】→ cleaned_data.xlsx 【发送邮件】→ 附带清洗报告清洗报告生成
defgenerate_clean_report(original_df,cleaned_df,output_path):"""生成数据清洗报告"""report=[]report.append("数据清洗报告")report.append("="*50)# 1. 数据量变化report.append(f"\n原始数据:{len(original_df)}行 ×{len(original_df.columns)}列")report.append(f"清洗后:{len(cleaned_df)}行 ×{len(cleaned_df.columns)}列")report.append(f"删除行数:{len(original_df)-len(cleaned_df)}")# 2. 缺失值处理report.append("\n【缺失值处理】")forcolinoriginal_df.columns:null_count=original_df[col].isnull().sum()ifnull_count>0:report.append(f"{col}:{null_count}个空值 ({null_count/len(original_df)*100:.1f}%)")# 3. 重复值dup_count=original_df.duplicated().sum()report.append(f"\n【重复值】删除{dup_count}条完全重复记录")# 4. 异常值report.append("\n【异常值检测】")numeric_cols=original_df.select_dtypes(include=[np.number]).columnsforcolinnumeric_cols:outliers=detect_outliers(original_df,col)iflen(outliers)>0:report.append(f"{col}: 发现{len(outliers)}个异常值")withopen(output_path,'w',encoding='utf-8')asf:f.write('\n'.join(report))returnoutput_path有什么坑
TEMU店群矩阵自动化运营核价报活动
坑1:fillna(method=‘ffill’)已弃用
# 问题:pandas 2.0+中method参数被弃用# df['列'].fillna(method='ffill') # 警告# 解决:用ffill()方法df['列']=df['列'].ffill()# 前向填充df['列']=df['列'].bfill()# 后向填充坑2:用均值填充改变数据分布
# 问题:用全局均值填充空值,导致数据分布变窄# 解决:按分组填充# 不好:全局均值df['工资']=df['工资'].fillna(df['工资'].mean())# 所有人工资一样# 更好:按部门分组填充df['工资']=df.groupby('部门')['工资'].transform(lambdax:x.fillna(x.mean()))坑3:异常值截断导致数据失真
# 问题:直接clip截断异常值,所有大值都变成上限值# 解决:根据业务场景选择处理方式# 如果异常值是真实数据(如VIP客户的大额订单),不应截断# 而是标记出来单独分析df['金额异常']=FalseQ1=df['金额'].quantile(0.25)Q3=df['金额'].quantile(0.75)IQR=Q3-Q1 df.loc[(df['金额']<Q1-1.5*IQR)|(df['金额']>Q3+1.5*IQR),'金额异常']=True坑4:字符串"nan"不是空值
# 问题:从网页采集的数据,空值变成字符串"nan"或"null"# isnull()检测不到# 解决:先替换再检测df=df.replace({'nan':None,'null':None,'None':None,'':None,'N/A':None})# 然后再做缺失值处理坑5:日期列清洗后变成时间戳
# 问题:pd.to_datetime后写入Excel,显示为数字而非日期# 解决:指定dtype或用openpyxl写# 写入时确保日期格式df['日期']=pd.to_datetime(df['日期'])# 用ExcelWriter写入时指定日期格式withpd.ExcelWriter(output_path,engine='openpyxl')aswriter:df.to_excel(writer,index=False,sheet_name='数据')ws=writer.sheets['数据']# 设置日期列格式forcellinws['A'][1:]:# A列是日期cell.number_format='YYYY-MM-DD'
编程学习
技术分享
实战经验