)
Polars实战用泰坦尼克号数据集手把手教你高效数据分析附完整代码数据分析领域正在经历一场效率革命。传统工具如Pandas在处理大规模数据时逐渐显露出性能瓶颈而新一代的Polars凭借其Rust语言底层和并行计算架构正在成为数据科学家和工程师的新宠。本文将带你通过经典的泰坦尼克号数据集从零开始掌握Polars的核心操作技巧体验比传统方法快5-10倍的数据处理速度。1. 环境准备与数据加载在开始之前确保你已经安装了最新版本的Polars。建议使用Python 3.8及以上版本并通过以下命令安装pip install polars泰坦尼克号数据集是机器学习入门的经典案例包含了乘客的舱位等级、姓名、性别、年龄、票价以及是否生还等信息。我们可以直接从网络获取这个数据集import polars as pl # 设置显示选项 pl.Config.set_tbl_rows(10) # 显示10行数据 pl.Config.set_fmt_str_lengths(50) # 字符串显示长度 # 直接从URL加载数据 url https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv df pl.read_csv(url)初次接触数据时快速了解数据结构至关重要。Polars提供了几种直观的查看方式# 查看前几行 print(df.head()) # 查看数据结构 print(df.schema) # 统计概览 print(df.describe())提示与Pandas不同Polars的describe()输出会自动包含null值统计这对数据质量检查非常有用。2. 数据清洗与预处理真实世界的数据往往不够完美。让我们先处理缺失值和异常数据# 检查各列缺失值 null_counts df.null_count() print(null_counts) # 年龄列处理用中位数填充缺失值 median_age df[Age].median() df df.with_columns( pl.col(Age).fill_null(median_age).alias(Age) ) # 票价异常值处理移除为0的票价 df df.filter(pl.col(Fare) 0)数据类型转换也是预处理的重要环节# 转换数据类型 df df.with_columns( pl.col(Survived).cast(pl.Boolean), pl.col(Pclass).cast(pl.UInt8) )对于分类变量我们可以创建虚拟变量dummy variables# 为Embarked列创建虚拟变量 df df.with_columns( pl.col(Embarked).str.to_uppercase().alias(Embarked) ) df df.to_dummies(columns[Embarked, Sex])3. 高效数据操作表达式API实战Polars的核心优势在于其表达式API它允许我们以声明式的方式编写复杂的数据转换。让我们通过几个实际案例来掌握这一强大工具。3.1 基本列操作# 选择特定列 selected df.select([Name, Age, Fare]) print(selected.head()) # 添加计算列 df df.with_columns( (pl.col(Fare) / pl.col(Age)).alias(FarePerYear) ) # 条件赋值 df df.with_columns( pl.when(pl.col(Age) 18) .then(Child) .otherwise(Adult) .alias(AgeGroup) )3.2 字符串处理Polars提供了丰富的字符串操作方法# 提取姓名中的称谓 df df.with_columns( pl.col(Name).str.extract(r ([A-Za-z])\., 1).alias(Title) ) # 常见称谓标准化 title_mapping { Mlle: Miss, Ms: Miss, Mme: Mrs } df df.with_columns( pl.col(Title).replace(title_mapping).alias(Title) )3.3 高级表达式组合表达式可以链式组合实现复杂转换# 多条件复杂表达式 df df.with_columns( pl.col(Fare) .log() .clip(lower_bound0, upper_bound5) .alias(NormalizedFare) ) # 多列交互计算 df df.with_columns( (pl.col(Age) * pl.col(Pclass)).alias(AgeClassScore) )4. 数据分析与聚合有了干净的数据我们可以开始深入分析。Polars的聚合操作特别适合处理大规模数据。4.1 基本统计分析# 按舱位统计生存率 survival_by_class df.group_by(Pclass).agg( pl.col(Survived).mean().alias(SurvivalRate), pl.count().alias(PassengerCount) ) print(survival_by_class)4.2 多维度交叉分析# 按性别和舱位分析生存率 survival_analysis df.group_by([Sex_male, Pclass]).agg( pl.col(Survived).mean().alias(SurvivalRate), pl.col(Age).mean().alias(MeanAge), pl.col(Fare).mean().alias(MeanFare) ) print(survival_analysis.sort(SurvivalRate, descendingTrue))4.3 窗口函数应用窗口函数允许我们在不实际分组的情况下计算分组统计量# 计算每个舱位的年龄排名 df df.with_columns( pl.col(Age).rank(methodaverage).over(Pclass).alias(AgeRankInClass) ) # 计算移动平均 df df.sort(Age).with_columns( pl.col(Fare).rolling_mean(window_size5).alias(FareRollingMean) )5. 性能优化技巧Polars的真正威力在于其性能。下面介绍几种最大化利用其能力的方法。5.1 惰性执行模式惰性模式允许Polars优化整个查询计划# 惰性模式示例 lazy_df ( pl.scan_csv(url) .filter(pl.col(Age) 18) .group_by([Pclass, Sex_male]) .agg( pl.col(Survived).mean().alias(SurvivalRate), pl.col(Fare).mean().alias(MeanFare) ) ) # 查看优化后的查询计划 print(lazy_df.explain()) # 执行查询 results lazy_df.collect() print(results)5.2 并行处理配置Polars默认使用所有CPU核心但我们可以精细控制# 设置并行线程数 pl.Config.set_global_string_cache(True) # 对分类变量优化 pl.Config.set_tbl_cols(20) # 显示更多列 # 强制使用特定数量的线程 import os os.environ[POLARS_MAX_THREADS] 45.3 内存管理技巧处理大数据时内存效率至关重要# 使用更高效的数据类型 df df.with_columns( pl.col(Pclass).cast(pl.UInt8), pl.col(Age).cast(pl.Float32) ) # 流式处理大数据 large_result ( pl.scan_csv(url) .filter(pl.col(Age) 30) .group_by(Pclass) .agg(pl.count().alias(Count)) .collect(streamingTrue) )6. 可视化集成虽然Polars本身不提供可视化功能但它可以无缝集成主流可视化库。6.1 与Matplotlib集成import matplotlib.pyplot as plt # 准备数据 class_survival df.group_by(Pclass).agg( pl.col(Survived).mean().alias(SurvivalRate) ).sort(Pclass) # 绘制柱状图 plt.bar( class_survival[Pclass].to_list(), class_survival[SurvivalRate].to_list() ) plt.xlabel(Passenger Class) plt.ylabel(Survival Rate) plt.title(Survival Rate by Passenger Class) plt.show()6.2 与Plotly交互式可视化import plotly.express as px # 创建交互式散点图 fig px.scatter( df.to_pandas(), # Plotly目前对Polars原生支持有限 xAge, yFare, colorSurvived, hover_data[Name, Pclass] ) fig.show()7. 完整案例分析预测生存因素让我们综合运用所学知识分析哪些因素最影响生存率。# 计算各特征与生存率的相关系数 correlation_analysis df.select([ pl.corr(Survived, Age).alias(AgeCorr), pl.corr(Survived, Fare).alias(FareCorr), pl.corr(Survived, Pclass).alias(ClassCorr), pl.corr(Survived, Sex_male).alias(SexCorr) ]) print(correlation_analysis) # 多因素分析 significant_factors ( df.group_by([Pclass, AgeGroup, Sex_male]) .agg( pl.col(Survived).mean().alias(SurvivalRate), pl.count().alias(Count) ) .sort(SurvivalRate, descendingTrue) ) print(significant_factors)从分析结果可以看出性别、舱位等级和年龄是影响生存率的最显著因素。一等舱的女性乘客生存率最高而三等舱的男性成年乘客生存率最低。8. 进阶技巧与最佳实践在项目中使用Polars时这些技巧能帮你避免常见陷阱避免混用Pandas频繁转换会抵消性能优势尽量全程使用Polars合理使用惰性模式对于复杂多步操作惰性模式能显著提升性能注意字符串处理Polars的字符串操作与Python略有不同需要适应利用并行优势确保操作是可并行的避免顺序依赖# 性能对比示例 import time # Polars处理 start time.time() polars_result df.group_by(Pclass).agg(pl.count()).collect() print(fPolars耗时: {time.time()-start:.4f}秒) # Pandas处理(对比) import pandas as pd pdf pd.read_csv(url) start time.time() pandas_result pdf.groupby(Pclass).size() print(fPandas耗时: {time.time()-start:.4f}秒)在我的测试环境中Polars的处理速度通常比Pandas快3-5倍对于更复杂的操作优势可能达到10倍以上。