Pandas 数据处理实战:从数据清洗到分析建模的完整流程 📅 2026/7/13 15:58:07 1. 从脏数据到干净数据电商销售数据的清洗实战刚拿到手的电商销售数据往往像一团乱麻——缺失值、异常值、重复记录、格式混乱等问题比比皆是。我最近处理过一个典型数据集原始CSV文件打开后是这样的import pandas as pd raw_data pd.read_csv(ecommerce_sales.csv) print(raw_data.head(3)) # 输出示例 # Order ID Customer ID Order Date ... Quantity UnitPrice TotalPrice # 0 1001.0 CUST001 2023/5/1 ... 2.0 $29.9 $59.8 # 1 NaN NaN NaN ... NaN NaN NaN # 2 1002.0 CUST002 5/3/2023 ... 1.0 19.9 NaN数据清洗四部曲是我的标准处理流程处理缺失值先用isnull().sum()统计每列缺失情况。对于关键字段如订单ID缺失的行直接删除数值型字段用中位数填充分类字段用众数或Unknown标记。# 删除关键字段缺失的行 clean_data raw_data.dropna(subset[Order ID, Customer ID]).copy() # 填充数值型缺失值 clean_data[Quantity] clean_data[Quantity].fillna( clean_data[Quantity].median())统一数据格式日期列经常是重灾区需要用pd.to_datetime统一格式。价格字段中的货币符号也需要去除并转为数值类型。# 统一日期格式 clean_data[Order Date] pd.to_datetime( clean_data[Order Date], errorscoerce) # 处理价格字段 clean_data[UnitPrice] clean_data[UnitPrice].str.replace($, ).astype(float)处理异常值通过描述统计和箱线图发现异常比如数量为负数或单价过高的记录。我常用query()方法过滤clean_data clean_data.query(Quantity 0 and UnitPrice 1000)去重处理最后用drop_duplicates()去除完全重复的记录对于业务关键字段组合重复的记录需要根据业务规则处理。# 按订单ID去重保留最后一条记录 clean_data clean_data.drop_duplicates( subset[Order ID], keeplast)处理后的数据质量显著提升可以进入下一阶段。记得用to_csv()保存清洗结果并记录所有处理步骤——这是数据工程师的好习惯。2. 探索性分析发现数据中的黄金清洗后的数据就像未经雕琢的玉石探索性分析(EDA)就是我们的雕刻刀。我习惯从三个维度入手维度一基础统计特征# 快速获取数值型字段统计 print(clean_data.describe()) # 分类字段分布 print(clean_data[Product Category].value_counts(normalizeTrue))维度二时间趋势分析# 按周统计销售额趋势 weekly_sales clean_data.set_index(Order Date)[TotalPrice].resample(W).sum() weekly_sales.plot(titleWeekly Sales Trend);维度三多维交叉分析# 使用pivot_table分析各品类在各地区的销售表现 pd.pivot_table(clean_data, valuesTotalPrice, indexProduct Category, columnsRegion, aggfunc[sum, count])最近一个项目中通过EDA我发现周末的客单价比工作日高35%某品类在华东地区销量异常偏低后来发现是物流问题20%的用户贡献了80%的销售额这些发现直接影响后续的运营策略。记住好的EDA不仅要发现已知模式更要揭示未知问题。3. 特征工程为模型注入灵魂特征工程是建模成功的关键。对于电商数据我通常会构造以下几类特征时间特征clean_data[Order_DayOfWeek] clean_data[Order Date].dt.dayofweek clean_data[Is_Weekend] clean_data[Order_DayOfWeek] 5用户行为特征# 计算用户购买频次 user_stats clean_data.groupby(Customer ID).agg( Purchase_Freq(Order ID, count), Avg_Spend(TotalPrice, mean) ) clean_data clean_data.merge(user_stats, onCustomer ID)产品关联特征# 计算品类平均价格 category_avg clean_data.groupby(Product Category)[UnitPrice].mean() clean_data[Price_Ratio] clean_data[UnitPrice] / clean_data[Product Category].map(category_avg)高阶特征# 使用rolling计算移动平均 clean_data[7D_Avg_Spend] clean_data.groupby(Customer ID)[TotalPrice].transform( lambda x: x.rolling(7, min_periods1).mean())特征构造后一定要做标准化/归一化处理from sklearn.preprocessing import MinMaxScaler scaler MinMaxScaler() clean_data[[Avg_Spend, Price_Ratio]] scaler.fit_transform( clean_data[[Avg_Spend, Price_Ratio]])好的特征应该像好调料——能让模型的味道更鲜美。我曾通过构造用户价值分位数特征将RF模型的AUC提升了0.15。4. 建模准备数据分割与验证策略进入建模前还需要做好三件事数据分割时间序列数据要特别注意避免未来信息泄露# 按时间划分训练测试集 train clean_data[clean_data[Order Date] 2023-06-01] test clean_data[clean_data[Order Date] 2023-06-01]分类编码对于树模型用OrdinalEncoder线性模型用OneHotEncoderfrom sklearn.preprocessing import OrdinalEncoder encoder OrdinalEncoder() train[[Product Category]] encoder.fit_transform(train[[Product Category]]) test[[Product Category]] encoder.transform(test[[Product Category]])评估指标根据业务目标选择合适指标分类问题AUC、F1、Precision/Recall回归问题MAE、RMSE、R²排序问题NDCG、MAP最后用pd.get_dummies()处理分类变量确保训练集和测试集特征维度一致# 确保测试集包含训练集所有类别 final_train pd.get_dummies(train, columns[Region]) final_test pd.get_dummies(test, columns[Region]) final_test final_test.reindex(columnsfinal_train.columns, fill_value0)记住数据准备的质量决定模型效果的上限。花在数据上的时间最终都会在模型效果上回报给你。