Pandas 1.5.3 解析 Excel 数据实战:5 种常见数据清洗与转换场景代码示例
2026/7/9 17:30:06 网站建设 项目流程

Pandas 1.5.3 实战:Excel 数据清洗与转换的 5 个高阶场景

1. 缺失值处理的智能策略

数据清洗中最常见的挑战莫过于缺失值处理。Pandas 1.5.3 提供了比以往更强大的工具链来处理这个难题。让我们从一个真实的销售数据集开始:

import pandas as pd sales_data = pd.read_excel('sales_records.xlsx', engine='openpyxl') print(sales_data.isna().sum())

缺失值诊断矩阵可以帮助我们快速定位问题:

列名缺失数量缺失比例数据类型
customer_id122.3%int64
product_name00%object
unit_price458.7%float64
quantity71.4%int64

对于不同场景,我们有多种处理方案:

  • 时间序列填充:使用前后时间点的平均值
sales_data['unit_price'] = sales_data['unit_price'].interpolate(method='time')
  • 分组填充:按产品类别填充中位数
sales_data['unit_price'] = sales_data.groupby('product_category')['unit_price']\ .transform(lambda x: x.fillna(x.median()))
  • 标记异常值:创建新列标识填充记录
sales_data['price_imputed'] = sales_data['unit_price'].isna().astype(int) sales_data['unit_price'] = sales_data['unit_price'].fillna(sales_data['unit_price'].median())

提示:在金融领域,建议保留原始缺失状态并创建新列存储填充值,这对后续模型训练至关重要。

2. 类型转换与内存优化

Pandas 的数据类型系统远比表面看起来复杂。观察这个内存使用案例:

# 转换前内存使用 original_mem = sales_data.memory_usage(deep=True).sum() # 优化类型 sales_data['customer_id'] = pd.to_numeric(sales_data['customer_id'], downcast='integer') sales_data['unit_price'] = pd.to_numeric(sales_data['unit_price'], downcast='float') sales_data['order_date'] = pd.to_datetime(sales_data['order_date']) # 转换后内存使用 optimized_mem = sales_data.memory_usage(deep=True).sum() print(f"内存节省: {(original_mem - optimized_mem)/original_mem:.1%}")

分类数据的黄金法则

  • 基数小于总行数10% → 使用category类型
  • 高频字符串字段 → 优先考虑category
  • 参与数值计算的字段 → 保持数值类型
# 智能类型转换函数 def auto_convert(df, col): if df[col].dtype == 'object': if df[col].nunique() / len(df) < 0.1: return df[col].astype('category') return df[col] for col in sales_data.columns: sales_data[col] = auto_convert(sales_data, col)

3. 多表合并的进阶技巧

真实业务中我们常需要合并多个数据源。假设我们有:

  • 销售记录表
  • 客户信息表
  • 产品目录表

合并策略对比表

合并类型适用场景代码示例内存消耗
内连接只保留匹配记录pd.merge(sales, clients)
左连接保留所有左表记录pd.merge(sales, clients, how='left')
外连接保留所有记录pd.merge(sales, clients, how='outer')
索引连接大数据集合并sales.join(clients.set_index('id'), on='client_id')最低

对于大型数据集,可以使用merge的优化参数:

merged_data = pd.merge( sales_data, client_info, on='client_id', validate='many_to_one', # 确保关系正确性 indicator=True, # 跟踪记录来源 suffixes=('_sales', '_client') )

性能优化技巧

  • 合并前对连接键排序可提升30%速度
  • 使用pd.concat()代替merge处理相同结构的表
  • 大数据集考虑dask.dataframe

4. 条件筛选的工程实践

复杂条件筛选是业务分析的核心。Pandas 1.5.3 优化了布尔索引的性能:

# 基础筛选 q3_sales = sales_data[ (sales_data['order_date'].dt.quarter == 3) & (sales_data['region'].isin(['West', 'East'])) & (sales_data['quantity'] > 10) ] # 使用query方法(更易读) high_value = sales_data.query( "unit_price > 100 and loyalty_status == 'Gold' and product_category != 'Clearance'" )

动态条件构建技巧

conditions = [] if include_east_region: conditions.append(df['region'] == 'East') if min_price: conditions.append(df['unit_price'] >= min_price) final_condition = pd.concat(conditions, axis=1).all(axis=1) filtered_data = sales_data[final_condition]

对于时间序列数据,可以使用between_timeat_time

# 获取每天上午的交易 morning_sales = sales_data.set_index('order_date')\ .between_time('09:00', '12:00')\ .reset_index()

5. 分组聚合的深度应用

分组聚合远不止groupby().sum()那么简单。看这个多维度分析案例:

# 多级分组与自定义聚合 results = (sales_data .groupby(['region', pd.Grouper(key='order_date', freq='M')]) .agg({ 'quantity': ['sum', 'mean'], 'unit_price': lambda x: (x * sales_data.loc[x.index, 'quantity']).sum(), 'client_id': pd.Series.nunique }) .rename(columns={ '<lambda>': 'revenue', 'client_id': 'unique_clients' }) )

分组优化技巧

  • 使用pd.Grouper进行时间分组
  • 大数据集考虑method='hash'参数
  • 避免在分组后立即计算,使用.pipe()延迟执行

透视表高级用法

pivot = pd.pivot_table( sales_data, values='unit_price', index=['region', 'sales_rep'], columns=pd.cut(sales_data['order_date'].dt.month, bins=[0,3,6,9,12]), aggfunc=['mean', 'count'], margins=True, fill_value=0 )

对于超大数据集,可以使用eval()进行链式操作优化:

sales_data = sales_data.eval(""" total = unit_price * quantity discount_amount = total * discount_rate / 100 net_value = total - discount_amount """)

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询