资讯动态

零基础Python数据分析与挖掘:从环境搭建到模型部署全流程

发布时间:2026/10/16 15:19:06 来源:尧图企业网站定制
简介这份资源面向零基础或希望系统补齐数据分析技能的读者围绕Python数据分析与挖掘的完整链路展开从语法入门一路延伸到建模实践。内容先帮助初学者熟悉变量、数据类型、控制结构、函数与模块等基础语法再重点讲解numpy的多维数组与矩阵运算以及pandas的DataFrame数据清洗、合并、切片与排序操作。机器学习部分覆盖线性回归、决策树、KNN、SVM、朴素贝叶斯与K-means聚类等经典模型并穿插缺失值处理、异常值检测、标准化归一化、交叉验证与网格搜索等预处理和调优环节。资源以zip压缩包形式提供整体约106.92MB配套PPT文档与源码实例便于边看边练、加深理解。目前已有1490人学习下载适合学术研究或职业发展中需要打牢数据分析与挖掘基础的学习者。1. 从零开始学Python数据分析与挖掘为什么你装了Anaconda还是跑不通第一个案例很多人学 Python 数据分析与挖掘第一步就卡在环境上。装完 Anaconda打开 Jupyter Notebook照着教程敲了import pandas as pd结果报错ModuleNotFoundError——明明刚装完怎么就没有更常见的是教程里用pd.read_csv(data.csv)读文件你复制粘贴后报FileNotFoundError然后开始怀疑自己是不是不适合学编程。这不是你的问题是绝大多数教程跳过了“环境隔离”和“路径认知”这两个最基础的环节。Python 数据分析与挖掘的入门门槛从来不是算法有多难而是你连数据都读不进来。这篇文章面向的是完全零基础、但愿意动手敲命令的从业者目标很明确让你在本地跑通一条从数据读取、清洗、分析到简单建模的完整链路并且知道每一步为什么这么做、参数怎么调、报错怎么查。我不会只给你代码我会告诉你代码背后的逻辑以及我踩过的那些坑。2. 环境搭建与工具选型为什么我劝你先别碰 PyCharm2.1 Anaconda 还是 Miniconda一个被低估的选择新手最常听到的建议是“装 Anaconda省事”。Anaconda 确实省事它预装了 numpy、pandas、matplotlib、scikit-learn 等几百个包装完就能用。但它的代价是安装包 3GB 起步装完占 5GB 以上而且 base 环境里包版本混乱你后面想装一个新包conda 解析依赖能跑十分钟。我的建议是如果你硬盘空间充足、网络下载速度稳定Anaconda 没问题但如果你用的是轻薄本或者公司配的办公机Miniconda 更合适。Miniconda 只包含 conda 和 Python安装包 50MB 左右你需要什么包再自己装。多花五分钟装包换来的是干净的环境和更快的依赖解析。安装完成后第一件事不是急着敲代码而是配置国内镜像源。默认的 conda 源在国外下载速度可能只有几十 KB/s。配置清华源或阿里源后速度能到几 MB/s。命令如下# 配置 conda 国内镜像源以清华源为例 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda config --set show_channel_urls yes # 验证配置是否生效 conda config --show channels逻辑说明conda config --add channels把镜像源加到频道列表最前面conda 会优先从这些地址下载。show_channel_urls yes让你在安装时能看到包的实际来源地址方便排查问题。参数方面如果你需要安装 R 语言相关的包可以额外添加r频道如果只用 Python上面两个就够了。2.2 虚拟环境别在 base 环境里装包我见过太多人把所有包都装在 base 环境里结果某天需要用一个旧版本的 pandas降级后把其他项目搞崩了。虚拟环境就是解决这个问题的每个项目一个独立环境互不干扰。创建虚拟环境的命令# 创建一个名为 data_analysis 的虚拟环境指定 Python 3.10 conda create -n data_analysis python3.10 # 激活环境 conda activate data_analysis # 安装数据分析核心包 conda install pandas numpy matplotlib scikit-learn jupyter # 查看当前环境已安装的包 conda list逻辑说明-n data_analysis指定环境名称python3.10指定 Python 版本。为什么选 3.10因为 3.10 是目前兼容性最好的版本主流数据分析库都支持而 3.12 在某些旧版 scikit-learn 上会有兼容问题。安装完成后conda list可以确认包是否装好。如果你后续需要安装不在 conda 源里的包可以用pip install但尽量优先用 conda因为 conda 能更好地处理二进制依赖。2.3 Jupyter Notebook 的启动与路径问题Jupyter Notebook 是数据分析最常用的交互式工具但新手最容易在“文件路径”上翻车。你从终端启动 Jupyter 时它的工作目录是你当前所在的目录。如果你在C:\Users\你的用户名下启动那 Jupyter 就只能看到这个目录下的文件。正确的做法是先切换到你的项目目录再启动 Jupyter。# 切换到项目目录Windows 示例 cd D:\projects\data_analysis # 启动 Jupyter Notebook jupyter notebook逻辑说明cd命令切换当前工作目录Jupyter 启动后会以这个目录为根目录。如果你在 Jupyter 里用pd.read_csv(data.csv)它会在当前目录下找data.csv。如果文件在子目录里要写成pd.read_csv(./data/data.csv)。参数方面jupyter notebook --port 8889可以指定端口避免和已运行的服务冲突--no-browser可以不自动打开浏览器适合远程服务器场景。提示如果你在 Jupyter 里不确定当前目录是什么运行import os; os.getcwd()就能看到。这个习惯能帮你省下大量找文件的时间。3. 数据读取与清洗80%的时间花在这里但没人告诉你为什么3.1 pandas 读取 CSV 的五个关键参数pd.read_csv()是数据分析里用得最多的函数但很多人只会写pd.read_csv(file.csv)遇到编码错误、分隔符不对、列名混乱时就束手无策。下面这五个参数能解决 90% 的读取问题。import pandas as pd # 读取 CSV 文件的典型配置 df pd.read_csv( sales_data.csv, # 文件路径 encodingutf-8, # 编码格式中文文件常用 gbk 或 utf-8-sig sep,, # 分隔符默认逗号TSV 文件用 \t header0, # 第几行作为列名0 表示第一行 names[date, product, price, quantity], # 自定义列名 usecols[date, product, price], # 只读取需要的列 dtype{price: float, quantity: int}, # 指定列的数据类型 na_values[, NA, null, None] # 哪些值视为缺失 ) # 查看前五行 print(df.head()) # 查看数据基本信息 print(df.info())逻辑说明encoding是最容易出错的参数。Windows 上导出的 CSV 默认是gbk而 Mac 和 Linux 通常是utf-8。如果报UnicodeDecodeError先试gbk再试utf-8-sig带 BOM 的 UTF-8。usecols能显著减少内存占用尤其是文件有几十列但你只需要几列时。dtype指定类型可以避免 pandas 自动推断导致的精度问题比如价格列被推断成字符串。na_values让你自定义哪些值算缺失默认只识别空字符串和NaN。3.2 缺失值与异常值先诊断再处理拿到数据后不要急着dropna()或fillna()。先看看缺失的分布是随机缺失还是集中在某些列异常值是录入错误还是真实的极端值# 查看每列的缺失数量 missing_count df.isnull().sum() print(missing_count) # 查看缺失比例 missing_ratio df.isnull().sum() / len(df) print(missing_ratio[missing_ratio 0]) # 用中位数填充数值型缺失 df[price].fillna(df[price].median(), inplaceTrue) # 用众数填充分类型缺失 df[product].fillna(df[product].mode()[0], inplaceTrue) # 删除缺失超过 50% 的列 threshold len(df) * 0.5 df df.dropna(axis1, threshthreshold) # 用 IQR 方法识别异常值 Q1 df[price].quantile(0.25) Q3 df[price].quantile(0.75) IQR Q3 - Q1 lower_bound Q1 - 1.5 * IQR upper_bound Q3 1.5 * IQR # 标记异常值而不是直接删除 df[price_outlier] ((df[price] lower_bound) | (df[price] upper_bound)) print(f异常值数量: {df[price_outlier].sum()})逻辑说明isnull().sum()返回每列的缺失数量missing_ratio帮你判断哪些列缺失严重。填充策略上数值型用中位数而不是均值因为中位数对异常值不敏感分类型用众数。dropna(axis1, threshthreshold)表示按列删除保留至少有threshold个非缺失值的列。IQR 方法中1.5是经验系数也可以设为3来只识别极端异常值。标记而不是直接删除是因为异常值可能包含重要信息比如大额订单。3.3 数据类型转换与字符串处理从 CSV 读进来的数据pandas 会自动推断类型但经常推断错。比如日期列被当成字符串数字列里混了逗号或货币符号。这时候需要手动转换。# 日期列转换 df[date] pd.to_datetime(df[date], format%Y-%m-%d, errorscoerce) # 提取日期特征 df[year] df[date].dt.year df[month] df[date].dt.month df[day_of_week] df[date].dt.dayofweek # 清洗价格列去掉货币符号和逗号 df[price] df[price].astype(str).str.replace(¥, ).str.replace(,, ) df[price] pd.to_numeric(df[price], errorscoerce) # 字符串去空格和统一大小写 df[product] df[product].str.strip().str.lower() # 查看转换后的类型 print(df.dtypes)逻辑说明pd.to_datetime的errorscoerce参数很关键它会把无法解析的日期变成NaT而不是直接报错。dt访问器可以提取年、月、日、星期等特征这些在后续分析中很有用。str.replace链式调用可以连续替换多个字符。pd.to_numeric的errorscoerce同样把无法转换的值变成NaN方便后续处理。str.strip()去空格str.lower()统一小写能避免“Apple”和“apple”被当成两个不同的产品。4. 从描述统计到可视化让数据开口说话4.1 描述性统计的四个层次拿到清洗后的数据第一步是看描述性统计。但df.describe()只给了数值列的基本统计你需要更细的视角。# 基础描述统计 print(df.describe()) # 分类型列的频次统计 print(df[product].value_counts().head(10)) # 分组统计每个产品的平均价格和总销量 group_stats df.groupby(product).agg({ price: [mean, median, std], quantity: [sum, count] }).round(2) print(group_stats) # 交叉表月份和产品的销量分布 cross_tab pd.crosstab(df[month], df[product], valuesdf[quantity], aggfuncsum) print(cross_tab)逻辑说明describe()默认只统计数值列包括计数、均值、标准差、最小值、四分位数和最大值。value_counts()看分类型列的分布head(10)只看前 10 个。groupby().agg()是分组聚合的核心字典的键是列名值是要应用的统计函数列表。round(2)保留两位小数。pd.crosstab做交叉表values指定要聚合的列aggfunc指定聚合函数不指定values时默认统计频次。4.2 matplotlib 中文显示与常用图表matplotlib 默认不支持中文直接画图会显示方框。需要配置字体。import matplotlib.pyplot as plt import matplotlib # 配置中文字体Windows 用 SimHeiMac 用 Arial Unicode MS matplotlib.rcParams[font.sans-serif] [SimHei] matplotlib.rcParams[axes.unicode_minus] False # 解决负号显示问题 # 创建画布设置大小 fig, axes plt.subplots(2, 2, figsize(12, 10)) # 柱状图各产品总销量 product_sales df.groupby(product)[quantity].sum().sort_values(ascendingFalse) axes[0, 0].bar(product_sales.index, product_sales.values, colorsteelblue) axes[0, 0].set_title(各产品总销量) axes[0, 0].tick_params(axisx, rotation45) # 折线图每月销量趋势 monthly_sales df.groupby(month)[quantity].sum() axes[0, 1].plot(monthly_sales.index, monthly_sales.values, markero, colorcoral) axes[0, 1].set_title(每月销量趋势) axes[0, 1].set_xlabel(月份) axes[0, 1].set_ylabel(销量) # 直方图价格分布 axes[1, 0].hist(df[price].dropna(), bins30, colorseagreen, edgecolorwhite) axes[1, 0].set_title(价格分布) axes[1, 0].set_xlabel(价格) # 箱线图各产品价格分布 df.boxplot(columnprice, byproduct, axaxes[1, 1]) axes[1, 1].set_title(各产品价格分布) axes[1, 1].set_xlabel(产品) plt.tight_layout() plt.savefig(analysis_charts.png, dpi150, bbox_inchestight) plt.show()逻辑说明rcParams[font.sans-serif]设置默认字体Windows 用SimHeiMac 用Arial Unicode MSLinux 可以用WenQuanYi Micro Hei。axes.unicode_minus False解决负号显示为方框的问题。subplots(2, 2)创建 2x2 的子图网格figsize控制整体大小。bar画柱状图plot画折线图hist画直方图boxplot画箱线图。tight_layout()自动调整子图间距savefig保存图片dpi150控制分辨率bbox_inchestight去掉多余白边。4.3 用 seaborn 快速出图seaborn 基于 matplotlib但默认样式更好看而且一行代码就能画出复杂图表。import seaborn as sns # 设置 seaborn 样式 sns.set_style(whitegrid) sns.set_palette(husl) # 散点图价格与销量的关系 plt.figure(figsize(8, 6)) sns.scatterplot(datadf, xprice, yquantity, hueproduct, alpha0.6) plt.title(价格与销量关系) plt.show() # 热力图相关性矩阵 plt.figure(figsize(8, 6)) corr_matrix df[[price, quantity, month]].corr() sns.heatmap(corr_matrix, annotTrue, cmapcoolwarm, center0, fmt.2f) plt.title(相关性热力图) plt.show() # 分布图按产品分组的销量分布 plt.figure(figsize(10, 6)) sns.violinplot(datadf, xproduct, yquantity, palettemuted) plt.title(各产品销量分布) plt.xticks(rotation45) plt.show()逻辑说明set_style设置整体风格whitegrid带网格线适合看数值。set_palette设置配色方案。scatterplot的hue参数按产品着色alpha控制透明度。corr()计算相关系数矩阵heatmap的annotTrue显示数值cmapcoolwarm用冷暖色center0让 0 对应中间色fmt.2f保留两位小数。violinplot结合了箱线图和核密度图能看出分布的形态。5. 避坑与排查那些教程不会告诉你的报错5.1 SettingWithCopyWarning不是错误但别忽略现象你对 DataFrame 的切片赋值时控制台出现SettingWithCopyWarning提示你可能在修改一个副本而不是原始数据。原因pandas 无法确定切片返回的是视图还是副本。如果你写df[df[price] 100][quantity] 0pandas 不知道你是想修改原始 df 还是临时切片。解决用.loc明确指定行列或者先用.copy()创建副本。# 错误写法 df[df[price] 100][quantity] 0 # 正确写法一用 loc df.loc[df[price] 100, quantity] 0 # 正确写法二先 copy 再修改 subset df[df[price] 100].copy() subset[quantity] 05.2 内存溢出数据太大怎么办现象读取一个几百 MB 的 CSV 时程序卡死或报MemoryError。原因pandas 默认把整个文件读进内存而且会自动推断数据类型可能把整数存成 int64、浮点数存成 float64内存占用是文件大小的 5 到 10 倍。解决分块读取、指定数据类型、只读需要的列。# 分块读取每次处理 10000 行 chunk_size 10000 chunks [] for chunk in pd.read_csv(large_file.csv, chunksizechunk_size, usecols[date, price]): # 对每个块做处理 chunk[price] chunk[price].astype(float32) chunks.append(chunk) df pd.concat(chunks, ignore_indexTrue)逻辑说明chunksize指定每次读取的行数返回一个迭代器。usecols只读需要的列。astype(float32)把 float64 降为 float32内存减半。pd.concat把处理后的块合并。如果数据量实在太大考虑用dask或polars替代 pandas。5.3 中文乱码从读取到保存的全链路现象读取 CSV 时中文变成乱码或者保存图片时中文显示为方框。原因编码不一致。文件可能是 GBK 编码但 pandas 默认用 UTF-8 读取matplotlib 默认字体不支持中文。解决读取时指定encodinggbk或encodingutf-8-sig保存 CSV 时指定encodingutf-8-sig这样 Excel 打开不会乱码matplotlib 配置中文字体。# 读取时指定编码 df pd.read_csv(chinese_data.csv, encodinggbk) # 保存时指定编码 df.to_csv(output.csv, encodingutf-8-sig, indexFalse) # matplotlib 中文字体配置 matplotlib.rcParams[font.sans-serif] [SimHei] matplotlib.rcParams[axes.unicode_minus] False5.4 日期解析失败格式不统一是常态现象pd.to_datetime报错ValueError: Unknown string format。原因日期列里混了多种格式比如2024-01-01、2024/01/01、01-01-2024甚至有空字符串。解决用errorscoerce把无法解析的变成NaT然后用format参数指定格式或者用dateutil自动推断。# 方法一强制转换无法解析的变 NaT df[date] pd.to_datetime(df[date], errorscoerce) # 方法二指定格式 df[date] pd.to_datetime(df[date], format%Y-%m-%d, errorscoerce) # 方法三多格式尝试 def parse_date(x): for fmt in [%Y-%m-%d, %Y/%m/%d, %d-%m-%Y]: try: return pd.to_datetime(x, formatfmt) except: continue return pd.NaT df[date] df[date].apply(parse_date)5.5 Jupyter 内核崩溃不是代码问题是环境问题现象Jupyter Notebook 运行一段时间后内核突然崩溃重启后之前的变量全没了。原因内存不足、包版本冲突、或者某个库的 C 扩展崩溃。解决先看终端有没有报错信息用conda list检查包版本是否兼容减少一次性加载的数据量定期保存 Notebook用%who查看当前变量占用内存。# 查看当前变量 %who # 查看变量内存占用 import sys def sizeof_fmt(num): for unit in [B, KB, MB, GB]: if num 1024: return f{num:.1f} {unit} num / 1024 for var in dir(): if not var.startswith(_): obj eval(var) if hasattr(obj, __sizeof__): print(f{var}: {sizeof_fmt(sys.getsizeof(obj))})6. 从分析到挖掘用 scikit-learn 跑通第一个预测模型6.1 特征工程把原始数据变成模型能吃的格式分析和挖掘的分界线在于是否用模型做预测。而模型效果的上限由特征工程决定。原始数据里的日期、分类型文本都需要转换成数值。from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler, LabelEncoder from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_absolute_error, r2_score # 构造特征和标签 # 假设我们要预测 quantity销量 features df[[price, month, day_of_week]].copy() target df[quantity] # 处理缺失值 features features.fillna(features.median()) # 标准化数值特征 scaler StandardScaler() features_scaled scaler.fit_transform(features) # 划分训练集和测试集 X_train, X_test, y_train, y_test train_test_split( features_scaled, target, test_size0.2, random_state42 ) # 训练随机森林模型 model RandomForestRegressor( n_estimators100, # 树的数量 max_depth10, # 最大深度 min_samples_split5, # 节点分裂最小样本数 random_state42 ) model.fit(X_train, y_train) # 预测 y_pred model.predict(X_test) # 评估 mae mean_absolute_error(y_test, y_pred) r2 r2_score(y_test, y_pred) print(fMAE: {mae:.2f}) print(fR2: {r2:.2f})逻辑说明train_test_split的test_size0.2表示 20% 做测试集random_state42保证每次划分结果一致。StandardScaler把特征标准化到均值为 0、方差为 1这对基于距离的模型很重要对随机森林影响不大但也没坏处。RandomForestRegressor的n_estimators是树的数量越多越稳定但计算越慢max_depth控制树的深度防止过拟合min_samples_split是节点分裂所需的最小样本数。MAE是平均绝对误差越小越好R2是决定系数越接近 1 越好。6.2 模型调参GridSearchCV 的实用配置手动调参效率低用GridSearchCV自动搜索最优参数组合。from sklearn.model_selection import GridSearchCV # 定义参数网格 param_grid { n_estimators: [50, 100, 200], max_depth: [5, 10, 15, None], min_samples_split: [2, 5, 10] } # 创建模型 rf RandomForestRegressor(random_state42) # 网格搜索5 折交叉验证 grid_search GridSearchCV( estimatorrf, param_gridparam_grid, cv5, # 5 折交叉验证 scoringneg_mean_absolute_error, # 评估指标 n_jobs-1, # 使用所有 CPU 核心 verbose1 # 输出搜索进度 ) grid_search.fit(X_train, y_train) # 最优参数和最优得分 print(f最优参数: {grid_search.best_params_}) print(f最优得分: {grid_search.best_score_:.2f}) # 用最优模型预测 best_model grid_search.best_estimator_ y_pred_best best_model.predict(X_test) print(f测试集 MAE: {mean_absolute_error(y_test, y_pred_best):.2f})逻辑说明param_grid定义要搜索的参数组合GridSearchCV会遍历所有组合。cv5表示 5 折交叉验证把训练集分成 5 份轮流用 4 份训练、1 份验证。scoringneg_mean_absolute_error是因为 sklearn 的评分函数默认越大越好而 MAE 越小越好所以用负值。n_jobs-1使用所有 CPU 核心并行计算。verbose1输出搜索进度方便观察。best_estimator_是搜索到的最优模型可以直接用来预测。6.3 特征重要性模型告诉你什么最重要随机森林可以输出特征重要性帮你理解哪些特征对预测贡献最大。import numpy as np # 获取特征重要性 importances best_model.feature_importances_ feature_names features.columns # 排序 indices np.argsort(importances)[::-1] # 打印 print(特征重要性排序:) for i in indices: print(f{feature_names[i]}: {importances[i]:.4f}) # 可视化 plt.figure(figsize(8, 5)) plt.barh(range(len(indices)), importances[indices], colorsteelblue) plt.yticks(range(len(indices)), [feature_names[i] for i in indices]) plt.xlabel(重要性) plt.title(特征重要性) plt.gca().invert_yaxis() plt.tight_layout() plt.show()逻辑说明feature_importances_返回每个特征的重要性分数总和为 1。np.argsort返回排序后的索引[::-1]降序排列。barh画水平柱状图invert_yaxis()让最重要的特征显示在最上面。如果某个特征重要性接近 0可以考虑去掉它简化模型。6.4 模型保存与加载别每次重新训练训练好的模型可以保存到磁盘下次直接加载使用不用重新训练。import joblib # 保存模型 joblib.dump(best_model, sales_model.pkl) # 加载模型 loaded_model joblib.load(sales_model.pkl) # 用加载的模型预测 new_data np.array([[50.0, 6, 3]]) # 价格 506 月周三 new_data_scaled scaler.transform(new_data) prediction loaded_model.predict(new_data_scaled) print(f预测销量: {prediction[0]:.2f})逻辑说明joblib.dump把模型序列化到文件joblib.load反序列化。注意保存模型时也要保存scaler因为新数据需要用同样的标准化参数。new_data的格式要和训练数据一致列的顺序不能变。scaler.transform而不是fit_transform因为要用训练时的均值和方差。注意模型文件可能很大尤其是随机森林有几百棵树时。如果要在生产环境部署考虑用pickle或onnx格式或者用 Flask/FastAPI 包装成 API 服务。7. 一个被低估的提速技巧用 polars 替代 pandas 做大数据预处理学完前面的内容你已经能跑通一条完整的数据分析与挖掘链路。但当你处理几百万行甚至上千万行的数据时pandas 会变得很慢甚至内存溢出。这时候我一般会切换到 polars。polars 是一个用 Rust 写的 DataFrame 库API 和 pandas 很像但底层是多线程和惰性执行的。同样的分组聚合操作polars 通常比 pandas 快 5 到 10 倍内存占用也更低。下面是一个对比示例。import polars as pl import pandas as pd import time # 用 pandas 读取和聚合 start time.time() df_pd pd.read_csv(large_sales.csv) result_pd df_pd.groupby(product)[quantity].sum().sort_values(ascendingFalse) print(fpandas 耗时: {time.time() - start:.2f} 秒) # 用 polars 读取和聚合 start time.time() df_pl pl.read_csv(large_sales.csv) result_pl ( df_pl .group_by(product) .agg(pl.col(quantity).sum()) .sort(quantity, descendingTrue) ) print(fpolars 耗时: {time.time() - start:.2f} 秒) # polars 的惰性执行先规划再执行 start time.time() result_lazy ( pl.scan_csv(large_sales.csv) # 惰性读取不立即加载 .filter(pl.col(quantity) 0) # 过滤 .group_by(product) .agg([ pl.col(quantity).sum().alias(total_quantity), pl.col(price).mean().alias(avg_price) ]) .sort(total_quantity, descendingTrue) .collect() # 执行 ) print(fpolars 惰性执行耗时: {time.time() - start:.2f} 秒)逻辑说明pl.read_csv是立即执行pl.scan_csv是惰性执行它只记录操作计划直到调用.collect()才真正执行。惰性执行的好处是 polars 可以优化整个查询计划比如把过滤条件下推到读取阶段减少实际读取的数据量。group_by和agg的用法和 pandas 类似但 polars 的表达式系统更灵活可以在agg里同时做多个聚合。alias给结果列重命名。参数方面scan_csv支持n_rows限制读取行数has_header指定是否有表头separator指定分隔符。如果你需要把 polars 的结果转回 pandas用.to_pandas()即可。我自己的习惯是数据量小于 100 万行时用 pandas代码熟悉、生态完善超过 100 万行或者需要频繁做复杂聚合时切到 polars。两者不是替代关系而是互补。你不需要重新学一套 API大部分操作只是换了个名字。最后说一个我踩过的坑polars 的group_by默认不保证顺序如果你需要按某个列排序一定要显式调用.sort()。另外polars 的字符串类型默认是Utf8和 pandas 的object不完全一样转换时注意类型匹配。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑