公司动态
Python数据分析实战:numpy、pandas、matplotlib完整项目工作流
如果你正在学习Python数据分析或者工作中需要处理数据那么numpy、pandas和matplotlib这三个库你一定绕不开。但很多初学者会遇到这样的困境看了很多教程每个库都学了一点但真正面对一个实际数据集时却不知道如何将它们结合起来完成一个完整的数据分析项目。本文将通过一个真实的数据分析案例手把手教你如何用这三个库完成从数据清洗、分析到可视化的全过程。不同于其他教程只讲零散知识点我会用一个完整的项目串联所有关键技能点让你真正掌握数据分析的完整工作流。1. 环境准备与工具安装在开始之前我们需要确保环境配置正确。推荐使用Anaconda它已经包含了我们需要的所有库。# 如果你还没有安装Anaconda可以从官网下载安装 # 安装完成后创建新的环境可选 conda create -n>import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns print(fnumpy版本: {np.__version__}) print(fpandas版本: {pd.__version__}) print(fmatplotlib版本: {plt.__version__})2. 理解三个库的分工与合作很多初学者会混淆这三个库的职责范围其实它们各有专长numpy负责数值计算处理多维数组和矩阵运算pandas负责数据处理和分析处理表格型数据类似Excelmatplotlib负责数据可视化将数据转化为图表它们的关系就像是一个数据分析流水线numpy提供基础计算能力pandas在此基础上构建了更便捷的数据操作接口matplotlib则将分析结果可视化。3. numpy基础高效的数值计算让我们从一个实际例子开始。假设我们要分析不同地区的气候数据对苹果产量的影响。3.1 从Python列表到numpy数组# 传统Python方法计算点积 def python_dot_product(region, weights): result 0 for x, w in zip(region, weights): result x * w return result # 五个地区的气候数据温度、降雨量、湿度 kanto [73, 67, 43] johto [91, 88, 64] hoenn [87, 134, 58] sinnoh [102, 43, 37] unova [69, 96, 70] # 权重温度、降雨量、湿度对苹果产量的影响系数 weights [0.3, 0.2, 0.5] # 计算Kanto地区的苹果产量 kanto_yield python_dot_product(kanto, weights) print(fKanto地区苹果产量: {kanto_yield} 吨/公顷)现在用numpy实现同样的功能# 将列表转换为numpy数组 kanto_np np.array([73, 67, 43]) weights_np np.array([0.3, 0.2, 0.5]) # 使用numpy计算点积 kanto_yield_np np.dot(kanto_np, weights_np) print(fnumpy计算产量: {kanto_yield_np} 吨/公顷) # 更简洁的写法使用运算符 kanto_yield_simple kanto_np weights_np print(f使用运算符: {kanto_yield_simple} 吨/公顷)3.2 numpy的性能优势当数据量很大时numpy的性能优势更加明显import time # 创建大规模数据 arr1 list(range(1000000)) arr2 list(range(1000000, 2000000)) # Python循环方式 start_time time.time() result_python 0 for x1, x2 in zip(arr1, arr2): result_python x1 * x2 python_time time.time() - start_time # numpy方式 arr1_np np.array(arr1) arr2_np np.array(arr2) start_time time.time() result_numpy np.dot(arr1_np, arr2_np) numpy_time time.time() - start_time print(fPython循环耗时: {python_time:.4f}秒) print(fnumpy点积耗时: {numpy_time:.4f}秒) print(f速度提升: {python_time/numpy_time:.1f}倍)3.3 多维数组操作# 创建二维数组矩阵表示所有地区的数据 climate_data np.array([ [73, 67, 43], # Kanto [91, 88, 64], # Johto [87, 134, 58], # Hoenn [102, 43, 37], # Sinnoh [69, 96, 70] # Unova ]) print(气候数据矩阵形状:, climate_data.shape) print(气候数据:\n, climate_data) # 矩阵乘法计算所有地区的产量 all_yields climate_data weights_np print(所有地区产量:, all_yields)4. pandas实战表格数据处理numpy适合数值计算但实际数据分析中我们更需要pandas来处理表格数据。4.1 读取和查看数据# 创建示例数据模拟销售数据 data { 日期: pd.date_range(2023-01-01, periods100, freqD), 产品类别: np.random.choice([电子产品, 服装, 食品, 家居], 100), 销售额: np.random.normal(1000, 200, 100), 销售量: np.random.randint(1, 50, 100), 利润率: np.random.uniform(0.1, 0.4, 100) } sales_df pd.DataFrame(data) sales_df[利润] sales_df[销售额] * sales_df[利润率] print(数据前5行:) print(sales_df.head()) print(\n数据基本信息:) print(sales_df.info()) print(\n数值列统计描述:) print(sales_df.describe())4.2 数据筛选和查询# 筛选电子产品的销售记录 electronics_sales sales_df[sales_df[产品类别] 电子产品] print(电子产品销售记录数量:, len(electronics_sales)) # 多条件筛选销售额大于1200且利润率高于0.3的记录 high_value_sales sales_df[(sales_df[销售额] 1200) (sales_df[利润率] 0.3)] print(高价值销售记录:, len(high_value_sales)) # 按日期排序 sales_sorted sales_df.sort_values(日期, ascendingTrue) print(按日期排序后的前3行:) print(sales_sorted.head(3))4.3 数据分组和聚合# 按产品类别分组统计 category_stats sales_df.groupby(产品类别).agg({ 销售额: [sum, mean, std], 销售量: sum, 利润率: mean }).round(2) print(按产品类别的统计信息:) print(category_stats) # 按月统计销售额 sales_df[月份] sales_df[日期].dt.month monthly_sales sales_df.groupby(月份)[销售额].sum() print(\n月度销售额统计:) print(monthly_sales)5. matplotlib数据可视化数据分析的结果最终需要通过可视化来呈现。5.1 基础图表绘制# 设置中文字体解决中文显示问题 plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False # 创建画布和子图 fig, axes plt.subplots(2, 2, figsize(15, 10)) fig.suptitle(销售数据分析可视化, fontsize16) # 1. 折线图销售额趋势 axes[0, 0].plot(sales_df[日期], sales_df[销售额], markero, linewidth1, markersize3) axes[0, 0].set_title(每日销售额趋势) axes[0, 0].set_xlabel(日期) axes[0, 0].set_ylabel(销售额) axes[0, 0].tick_params(axisx, rotation45) # 2. 柱状图各产品类别销售额 category_sales sales_df.groupby(产品类别)[销售额].sum() axes[0, 1].bar(category_sales.index, category_sales.values, color[#ff9999, #66b3ff, #99ff99, #ffcc99]) axes[0, 1].set_title(各产品类别总销售额) axes[0, 1].set_ylabel(销售额) # 3. 箱线图各产品类别销售额分布 category_data [sales_df[sales_df[产品类别] cat][销售额] for cat in sales_df[产品类别].unique()] axes[1, 0].boxplot(category_data, labelssales_df[产品类别].unique()) axes[1, 0].set_title(各产品类别销售额分布) axes[1, 0].set_ylabel(销售额) # 4. 散点图销售额与利润率关系 scatter axes[1, 1].scatter(sales_df[销售额], sales_df[利润率], csales_df[销售量], cmapviridis, alpha0.6) axes[1, 1].set_title(销售额 vs 利润率颜色表示销售量) axes[1, 1].set_xlabel(销售额) axes[1, 1].set_ylabel(利润率) plt.colorbar(scatter, axaxes[1, 1], label销售量) plt.tight_layout() plt.show()5.2 使用seaborn增强可视化seaborn基于matplotlib提供了更美观的样式和更高级的图表类型。# 设置seaborn样式 sns.set_style(whitegrid) plt.figure(figsize(12, 8)) # 1. 分类散点图 plt.subplot(2, 2, 1) sns.stripplot(x产品类别, y销售额, datasales_df, jitterTrue) plt.title(各产品类别销售额分布) plt.xticks(rotation45) # 2. 密度图 plt.subplot(2, 2, 2) sns.kdeplot(datasales_df, x销售额, hue产品类别, fillTrue) plt.title(销售额密度分布) # 3. 热力图相关性分析 plt.subplot(2, 2, 3) numeric_df sales_df.select_dtypes(include[np.number]) correlation_matrix numeric_df.corr() sns.heatmap(correlation_matrix, annotTrue, cmapcoolwarm, center0) plt.title(数值变量相关性热力图) # 4. 配对图部分变量 plt.subplot(2, 2, 4) sns.pairplot(sales_df[[销售额, 销售量, 利润率, 产品类别]], hue产品类别) plt.suptitle(变量间关系配对图, y1.02) plt.tight_layout() plt.show()6. 完整项目实战电商数据分析现在我们将三个库结合起来完成一个完整的电商数据分析项目。6.1 数据准备和清洗# 模拟电商数据集 np.random.seed(42) # 保证结果可重现 n_customers 1000 data { 客户ID: range(1, n_customers 1), 年龄: np.random.randint(18, 70, n_customers), 性别: np.random.choice([男, 女], n_customers), 城市: np.random.choice([北京, 上海, 广州, 深圳, 杭州], n_customers), 注册日期: pd.date_range(2020-01-01, periodsn_customers, freqD), 总订单数: np.random.poisson(5, n_customers), 总消费金额: np.random.exponential(500, n_customers), 最近购买日期: pd.to_datetime(2023-06-01) - pd.to_timedelta(np.random.randint(1, 365, n_customers), unitD) } ecommerce_df pd.DataFrame(data) # 数据清洗处理异常值 ecommerce_df ecommerce_df[ecommerce_df[总消费金额] 0] # 删除消费金额为0的记录 ecommerce_df ecommerce_df[ecommerce_df[年龄] 65] # 过滤异常年龄 print(清洗后数据形状:, ecommerce_df.shape) print(数据前5行:) print(ecommerce_df.head())6.2 客户细分分析# 创建客户价值细分 def segment_customer(row): if row[总消费金额] 1000 and row[总订单数] 8: return 高价值客户 elif row[总消费金额] 500 and row[总订单数] 4: return 中价值客户 else: return 低价值客户 ecommerce_df[客户细分] ecommerce_df.apply(segment_customer, axis1) # 计算RFM指标 current_date pd.to_datetime(2023-06-01) ecommerce_df[最近购买天数] (current_date - ecommerce_df[最近购买日期]).dt.days ecommerce_df[R_分位数] pd.qcut(ecommerce_df[最近购买天数], 4, labelsFalse) ecommerce_df[F_分位数] pd.qcut(ecommerce_df[总订单数], 4, labelsFalse) ecommerce_df[M_分位数] pd.qcut(ecommerce_df[总消费金额], 4, labelsFalse) print(客户细分分布:) print(ecommerce_df[客户细分].value_counts())6.3 综合可视化分析# 创建综合仪表板 fig plt.figure(figsize(18, 12)) # 1. 客户价值分布 plt.subplot(2, 3, 1) segment_counts ecommerce_df[客户细分].value_counts() plt.pie(segment_counts.values, labelssegment_counts.index, autopct%1.1f%%, startangle90) plt.title(客户价值分布) # 2. 各城市客户消费能力 plt.subplot(2, 3, 2) city_stats ecommerce_df.groupby(城市).agg({ 总消费金额: mean, 客户ID: count }).rename(columns{客户ID: 客户数量}) cities city_stats.index x_pos np.arange(len(cities)) ax1 plt.gca() ax2 ax1.twinx() ax1.bar(x_pos, city_stats[客户数量], alpha0.7, label客户数量) ax2.plot(x_pos, city_stats[总消费金额], colorred, markero, linewidth2, label平均消费金额) ax1.set_xlabel(城市) ax1.set_ylabel(客户数量) ax2.set_ylabel(平均消费金额) ax1.set_xticks(x_pos) ax1.set_xticklabels(cities) ax1.legend(locupper left) ax2.legend(locupper right) plt.title(各城市客户分布和消费能力) # 3. 年龄分布直方图 plt.subplot(2, 3, 3) plt.hist(ecommerce_df[年龄], bins15, edgecolorblack, alpha0.7) plt.xlabel(年龄) plt.ylabel(客户数量) plt.title(客户年龄分布) # 4. 消费金额 vs 订单数散点图 plt.subplot(2, 3, 4) scatter plt.scatter(ecommerce_df[总订单数], ecommerce_df[总消费金额], cecommerce_df[年龄], cmapviridis, alpha0.6) plt.colorbar(scatter, label年龄) plt.xlabel(总订单数) plt.ylabel(总消费金额) plt.title(消费行为分析) # 5. 注册时间趋势 plt.subplot(2, 3, 5) monthly_registrations ecommerce_df.set_index(注册日期).resample(M).size() plt.plot(monthly_registrations.index, monthly_registrations.values, markero) plt.xlabel(日期) plt.ylabel(注册客户数) plt.title(月度客户注册趋势) plt.xticks(rotation45) # 6. RFM分位数热力图 plt.subplot(2, 3, 6) rfm_pivot ecommerce_df.pivot_table(indexR_分位数, columnsF_分位数, valuesM_分位数, aggfuncmean) sns.heatmap(rfm_pivot, annotTrue, cmapYlOrRd, cbar_kws{label: M分位数平均值}) plt.title(RFM分位数热力图) plt.xlabel(F分位数频率) plt.ylabel(R分位数新近度) plt.tight_layout() plt.show()7. 高级技巧和最佳实践7.1 性能优化技巧# 避免循环使用向量化操作 # 不好的做法 def slow_calculation(df): results [] for i in range(len(df)): if df.loc[i, 总消费金额] 1000: results.append(高消费) else: results.append(普通消费) return results # 好的做法使用numpy.where def fast_calculation(df): return np.where(df[总消费金额] 1000, 高消费, 普通消费) # 测试性能差异 import time start_time time.time() slow_result slow_calculation(ecommerce_df) slow_time time.time() - start_time start_time time.time() fast_result fast_calculation(ecommerce_df) fast_time time.time() - start_time print(f循环方法耗时: {slow_time:.4f}秒) print(f向量化方法耗时: {fast_time:.4f}秒) print(f性能提升: {slow_time/fast_time:.1f}倍)7.2 内存使用优化# 查看数据框内存使用 def memory_usage(df): return df.memory_usage(deepTrue).sum() / 1024**2 # 转换为MB print(f原始数据内存使用: {memory_usage(ecommerce_df):.2f} MB) # 优化数据类型 def optimize_dtypes(df): result df.copy() # 整数列优化 int_cols result.select_dtypes(include[int64]).columns for col in int_cols: result[col] pd.to_numeric(result[col], downcastinteger) # 浮点数列优化 float_cols result.select_dtypes(include[float64]).columns for col in float_cols: result[col] pd.to_numeric(result[col], downcastfloat) # 对象列优化分类数据 obj_cols result.select_dtypes(include[object]).columns for col in obj_cols: if result[col].nunique() / len(result[col]) 0.5: # 唯一值比例小于50% result[col] result[col].astype(category) return result optimized_df optimize_dtypes(ecommerce_df) print(f优化后内存使用: {memory_usage(optimized_df):.2f} MB) print(f内存减少: {(1 - memory_usage(optimized_df)/memory_usage(ecommerce_df))*100:.1f}%)8. 常见问题排查数据分析过程中经常会遇到各种问题这里总结一些常见问题的解决方法问题现象可能原因解决方案图表显示乱码缺少中文字体支持设置plt.rcParams[font.sans-serif]内存不足错误数据量太大或数据类型不合理使用optimize_dtypes函数优化数据类型计算速度慢使用Python循环而不是向量化操作尽量使用numpy/pandas内置函数数据读取失败文件路径错误或格式不支持检查文件路径使用正确的读取函数图表显示不全画布大小设置不合理调整figsize参数使用tight_layout()9. 项目总结和学习建议通过这个完整的项目你应该已经掌握了numpy、pandas和matplotlib的核心用法。这三个库的组合为Python数据分析提供了强大的能力numpy提供了高效的数值计算基础特别是对于大规模数值数据pandas让表格数据的处理变得简单直观类似Excel但更强大matplotlib和seaborn让数据可视化变得专业而美观下一步学习建议实战练习找一些真实的数据集如Kaggle上的数据集进行练习深入学习了解每个库的更多高级功能如pandas的时间序列分析、matplotlib的动画功能等扩展技能学习scikit-learn进行机器学习或者plotly进行交互式可视化项目实践尝试完成一个完整的数据分析项目从数据获取到报告撰写记住数据分析最重要的是解决实际问题的思维工具只是实现手段。多实践、多思考你就能真正掌握数据分析这项宝贵技能。