在真实的数据分析与商业智能(BI)场景中,原始数据往往是“脏”且混乱的。俗话说:“Garbage in, Garbage out(垃圾进,垃圾出)”。没有高质量的数据清洗,后续的任何统计与建模都毫无意义。
清洗完成之后,为了抓住关键业务问题,我们通常需要对数据进行特定规则的排序,以及按业务维度进行分类汇总(GroupBy)。
本文将带你系统掌握 Pandas 中最核心的三大硬核操作:
- 数据清洗:缺失值、重复值、异常值与格式统一;
- 数据排序:单列/多列、升序/降序灵活排序;
- 数据分组与聚合:GroupBy 机制与
agg()多维聚合。
一、 数据清洗(Data Cleaning)
数据清洗是指发现并纠正数据中可识别的错误,包括处理缺失值、剔除重复项、修正异常值以及规范数据格式,以保证数据的一致性和准确性。
原始脏数据 ──> [检测与过滤] ──> [补齐与修正] ──> [统一规范] ──> 高质量数据1. 缺失值(NaN / None)处理
现实数据因网络波动、用户未填写等原因,常出现空值:
| 方法 | 功能描述 | 核心场景 / 示例 |
|---|---|---|
df.isnull()/isna() | 检查是否为缺失值 | df.isnull().sum()统计每列缺失值个数 |
df.dropna() | 删除含有缺失值的行或列 | df.dropna(axis=0)(默认按行删除) |
df.fillna(value) | 用指定固定值填充缺失值 | df['销量'].fillna(0) |
df.ffill() | 前向填充(用上一行的有效值填补) | 适用于时间序列或断点补全 |
df.bfill() | 后向填充(用下一行的有效值填补) | 适用于回溯补全 |
# 示例:填充数值列,删除关键字段为空的行df['销售额']=df['销售额'].fillna(0)df=df.dropna(subset=['客户ID'])# 核心主键为空则直接剔除2. 重复值(Duplicates)处理
数据重复录入会严重干扰统计指标的真实性:
| 方法 | 核心作用 |
|---|---|
df.duplicated() | 标记是否存在重复行(返回 True/False 的 Series) |
df.drop_duplicates() | 剔除重复行,保留唯一记录 |
# 查看重复行数print(f"重复数据量:{df.duplicated().sum()}")# 根据特定列(如订单号)去重,保留首次出现的记录df=df.drop_duplicates(subset=['订单编号'],keep='first')3. 异常值修正与格式统一
异常值修正:例如退货或系统失误导致出现了不合理的负数金额,可通过.abs()统一转为绝对值:
df['销售数量']=df['销售数量'].abs()格式规范化:例如日期字段中的分隔符不一致(既有2025/06/01又有2025-06-01),可用字符串向量化操作.str.replace()统一:
df['订单日期']=df['订单日期'].str.replace('/','-')二、 数据排序(Data Sorting)
通过排序,我们可以迅速定位“头部 Top 客户”、“滞销产品”或“最近订单”。Pandas 提供sort_values()方法,支持单列及多列的升/降序控制。
1. 单列排序
ascending=True:升序(默认)ascending=False:降序
# 按照'销售数量'从大到小降序排列df_sorted=df.sort_values('销售数量',ascending=False)2. 多列排序(业务复合排序)
在多列排序中,遵循**“主从优先级”**原则:先按第一列排序;只有在第一列取值相同时,才会根据第二列的值进行次级排序。
# 场景一:多列统一降序# 先按'销售数量'从大到小排,数量一样的,再按'订单日期'从新到旧排df.sort_values(['销售数量','订单日期'],ascending=False)# 场景二:多列定制不同的升降序(通过传入布尔列表)# '销售数量'升序(True),相同数量时'订单日期'降序(False)df.sort_values(['销售数量','订单日期'],ascending=[True,False])三、 数据分组与聚合(GroupBy)
分组操作的核心逻辑是经典的Split - Apply - Combine(拆分 - 应用 - 合并):
- Split:根据给定的维度(如产品类别),将原表数据拆分成多个独立的“子组”;
- Apply:对每一个子组分别执行统计函数(如求和、均值、极值);
- Combine:将各个子组的计算结果拼接还原成一个结构化结果。
原始数据 ──> [ 按类别拆分组 ] ──> [ 各组单独求 sum/mean ] ──> [ 组装为报表 ]1. 单列基础聚合计算
直接对提取的单列调用聚合函数:
# 按'产品类别'分组,分别统计'销售额'的不同指标df.groupby('产品类别')['销售额'].sum()# 总销售额df.groupby('产品类别')['销售额'].mean()# 平均销售额df.groupby('产品类别')['销售额'].max()# 最大销售额df.groupby('产品类别')['销售额'].min()# 最小销售额df.groupby('产品类别')['销售额'].count()# 订单笔数2. 进阶一:单列多指标聚合(agg 传入列表)
如果希望一次性得出单列的多个汇总指标:
# 一次性查看各产品类别的销售额:总和、最大值、最小值df.groupby('产品类别')['销售额'].agg(['sum','max','min'])3. 进阶二:不同列定制不同指标(agg 传入字典)
在企业报表制作中,最常见的是对不同字段使用不同的统计逻辑,此时可向.agg()传入字典映射:
# 语法格式:{ '目标列名': '统计函数' }agg_result=df.groupby('产品类别').agg({'销售数量':'sum',# 销售数量求总和'销售额':'sum',# 销售金额求总和'单价':'mean'# 单价求平均值})四、 综合业务实战
将“清洗 ➔ 排序 ➔ 分组”串联在完整的真实数据处理流水线中:
importpandasaspd# 1. 模拟含脏数据的销售记录raw_data={'订单日期':['2025/06/01','2025-06-01','2025-06-02','2025/06/02','2025-06-02'],'产品类别':['食品','食品','服装','电子产品','服装'],'销售数量':[-5,5,2,None,6],# 存在负数和缺失值'单价':[29,29,199,399,199]}df=pd.DataFrame(raw_data)# ------------ Step 1: 数据清洗 ------------# ① 规范化日期格式df['订单日期']=df['订单日期'].str.replace('/','-')# ② 缺失值填充df['销售数量']=df['销售数量'].fillna(1)# ③ 异常负值修正为绝对值df['销售数量']=df['销售数量'].abs()# ④ 计算衍生列:销售额df['销售额']=df['销售数量']*df['单价']# ------------ Step 2: 数据排序 ------------# 按照'销售额'降序排序df_sorted=df.sort_values(by='销售额',ascending=False)print("=== 排序后的明细数据 ===")print(df_sorted)# ------------ Step 3: 分组汇总 ------------# 按'产品类别'聚合产出业务看板report=df.groupby('产品类别').agg({'销售数量':'sum','销售额':'sum','单价':'mean'}).reset_index()print("\n=== 分类汇总报表 ===")print(report)📌 五、 核心知识点全景速查表
| 分类模块 | 常用 API / 语法 | 功能描述与核心规则 | 典型代码示例 |
|---|---|---|---|
| 缺失值处理 | isnull()/isna() | 检查缺失值,返回布尔值掩码 | df.isnull().sum() |
dropna() | 删除含有空值的行或列(可指定subset作用列) | df.dropna(subset=['姓名']) | |
fillna(value) | 用标量常数或特定统计值填补空缺 | df['成绩'].fillna(0) | |
ffill()/bfill() | 前向填补 / 后向填补(按相邻非空有效值填充) | df['电量'].ffill() | |
| 重复值处理 | duplicated() | 标记数据是否重复(返回布尔序列) | df.duplicated(subset=['订单号']) |
drop_duplicates() | 删除重复数据行,保留唯一值(默认keep='first') | df.drop_duplicates() | |
| 异常与规范 | abs() | 取绝对值,纠正常见的人为输入负数异常 | df['数量'] = df['数量'].abs() |
str.replace() | 文本/字符串列的统一替换与规范化 | df['日期'].str.replace('/', '-') | |
| 数据排序 | sort_values() | 按一列或多列进行排序;ascending决定升序或降序 | df.sort_values('销量', ascending=False) |
| 多列复合排序 | 第一列优先,同值时根据第二列次级排序 | df.sort_values(['A', 'B'], ascending=[True, False]) | |
| 分组与聚合 | groupby() | 按照某特征将数据拆分成子组(Split) | grouped = df.groupby('部门') |
| 组内聚合计算 | 单列单一指标(.sum(),.mean(),.max()等) | df.groupby('部门')['薪资'].mean() | |
agg(list) | 单列多个指标聚合统计 | df.groupby('部门')['薪资'].agg(['min', 'max']) | |
agg(dict) | 多列分别定制不同维度的聚合计算 | df.groupby('部门').agg({'薪资':'mean', '年龄':'min'}) |