在数据分析和处理的实际项目中经常遇到Excel、CSV等格式的原始数据需要清洗、转换和分析。传统的手工处理方式效率低下且容易出错而pandas作为Python生态中最强大的数据处理库能够帮助我们高效完成这些任务。本文将系统讲解pandas从零基础到实战应用的全套技能包含完整的环境搭建、核心概念解析、常用操作示例和实际项目案例无论是数据分析初学者还是有经验的开发者都能从中获益。1. pandas核心概念与优势1.1 什么是pandaspandas是基于Python编程语言构建的开源数据操作和数据分析软件库。它提供了专门用于处理表格数据集的数据结构和简化的Python API能够高效执行数据加载、对齐、合并和转换等操作。pandas的名称源自panel data面板数据这是一种包含多个时间段观察结果的数据集类型。该库专注于处理现实世界中的多样化数据结构支持表格、矩阵和时间序列等结构化数据格式。1.2 pandas的核心数据结构pandas主要围绕两种核心数据结构构建Series一维数组可以存储任何数据类型整数、字符串、浮点数、Python对象等。每个Series都有一个索引用于标识数据元素。DataFrame二维表格型数据结构可以看作是由多个Series组成的字典。DataFrame具有行索引和列索引类似于Excel表格或SQL数据库表。1.3 pandas的主要优势pandas在数据科学领域广受欢迎主要得益于以下优势处理缺失数据能力强内置NaNNot a Number处理机制可以轻松处理包含缺失值的数据集灵活的数据操作支持数据的增删改查、重塑、透视等复杂操作强大的I/O功能可以读写CSV、Excel、SQL、JSON等多种格式的数据高效的数据对齐自动将数据与其标签对齐简化计算过程丰富的时间序列功能专门为时间序列分析提供了强大的工具集与Python生态系统完美集成可以与NumPy、Matplotlib、Scikit-learn等库无缝协作2. 环境准备与安装配置2.1 Python环境要求在安装pandas之前需要确保系统已安装Python环境。推荐使用Python 3.7及以上版本这些版本对pandas有更好的支持。检查Python版本的方法python --version # 或 python3 --version2.2 pandas安装方法使用pip安装推荐pip install pandas使用conda安装conda install pandas安装完整的数据科学套件# 安装pandas及其常用依赖 pip install pandas numpy matplotlib jupyter2.3 验证安装安装完成后可以通过以下代码验证pandas是否安装成功import pandas as pd print(fpandas版本: {pd.__version__}) # 创建一个简单的DataFrame测试 data {姓名: [张三, 李四, 王五], 年龄: [25, 30, 35]} df pd.DataFrame(data) print(df)2.4 Jupyter Notebook环境配置对于数据分析工作推荐使用Jupyter Notebook作为开发环境# 安装Jupyter pip install jupyter # 启动Jupyter Notebook jupyter notebook在Jupyter中创建新的Python笔记本就可以开始pandas的学习和实践了。3. pandas核心数据结构详解3.1 Series数据结构Series是pandas中最基本的一维数据结构类似于带标签的数组。创建Series的多种方式import pandas as pd import numpy as np # 从列表创建Series s1 pd.Series([1, 3, 5, np.nan, 6, 8]) print(从列表创建:) print(s1) # 从字典创建Series字典的键成为索引 s2 pd.Series({a: 1, b: 2, c: 3}) print(\n从字典创建:) print(s2) # 指定索引创建Series s3 pd.Series([10, 20, 30], index[x, y, z]) print(\n指定索引创建:) print(s3) # 使用标量值创建Series s4 pd.Series(5, index[0, 1, 2, 3]) print(\n使用标量创建:) print(s4)Series的基本操作# 创建示例Series s pd.Series([10, 20, 30, 40], index[a, b, c, d]) # 访问数据 print(第一个元素:, s[0]) print(通过索引访问:, s[a]) print(前三个元素:\n, s[:3]) # Series运算 print(所有元素加5:\n, s 5) print(元素平方:\n, s ** 2) # 统计信息 print(描述性统计:) print(s.describe()) print(平均值:, s.mean()) print(标准差:, s.std())3.2 DataFrame数据结构DataFrame是pandas中最常用的二维表格数据结构。创建DataFrame的多种方式# 从字典创建DataFrame data { 姓名: [张三, 李四, 王五, 赵六], 年龄: [28, 32, 25, 40], 城市: [北京, 上海, 广州, 深圳], 薪资: [15000, 18000, 12000, 25000] } df pd.DataFrame(data) print(从字典创建DataFrame:) print(df) # 从列表的列表创建指定列名 data_list [ [张三, 28, 北京, 15000], [李四, 32, 上海, 18000], [王五, 25, 广州, 12000], [赵六, 40, 深圳, 25000] ] df2 pd.DataFrame(data_list, columns[姓名, 年龄, 城市, 薪资]) print(\n从列表创建DataFrame:) print(df2) # 从NumPy数组创建 import numpy as np array_data np.random.randn(5, 3) df3 pd.DataFrame(array_data, columns[A, B, C]) print(\n从NumPy数组创建:) print(df3)DataFrame的基本属性和方法# 查看DataFrame的基本信息 print(DataFrame形状:, df.shape) print(行数:, len(df)) print(列名:, df.columns.tolist()) print(索引:, df.index.tolist()) # 查看数据类型 print(\n数据类型:) print(df.dtypes) # 查看前几行和后几行 print(\n前2行:) print(df.head(2)) print(\n后2行:) print(df.tail(2)) # 快速统计信息 print(\n描述性统计:) print(df.describe()) # 转置 print(\n转置后的DataFrame:) print(df.T)4. 数据读取与导出实战4.1 读取CSV文件CSV是最常用的数据交换格式pandas提供了强大的CSV读取功能。# 读取CSV文件的基本用法 df_csv pd.read_csv(data.csv) # 替换为实际文件路径 print(CSV数据前5行:) print(df_csv.head()) # 读取CSV时的常用参数 df_csv_advanced pd.read_csv( data.csv, encodingutf-8, # 指定编码 sep,, # 分隔符 header0, # 表头行 index_col0, # 指定索引列 na_values[NULL, NA] # 指定缺失值标识 ) # 读取大型CSV文件的分块处理 chunk_size 1000 # 每次读取1000行 chunks [] for chunk in pd.read_csv(large_data.csv, chunksizechunk_size): # 对每个数据块进行处理 processed_chunk chunk[chunk[年龄] 25] # 示例过滤条件 chunks.append(processed_chunk) # 合并处理后的数据块 large_df pd.concat(chunks, ignore_indexTrue)4.2 读取Excel文件对于Excel格式的数据pandas同样提供了良好的支持。# 读取Excel文件 df_excel pd.read_excel(data.xlsx, sheet_nameSheet1) # 读取Excel时的高级参数 df_excel_advanced pd.read_excel( data.xlsx, sheet_name0, # 工作表索引或名称 header0, # 表头行 usecolsA:D, # 指定读取的列范围 skiprows1, # 跳过前1行 nrows1000 # 只读取前1000行 ) # 读取多个工作表 excel_file pd.ExcelFile(data.xlsx) sheet_names excel_file.sheet_names print(工作表名称:, sheet_names) # 读取所有工作表到字典 all_sheets {} for sheet in sheet_names: all_sheets[sheet] pd.read_excel(data.xlsx, sheet_namesheet)4.3 读取数据库数据pandas可以方便地从SQL数据库读取数据。import sqlite3 # 创建SQLite连接示例 conn sqlite3.connect(example.db) # 从数据库读取数据 df_sql pd.read_sql(SELECT * FROM users WHERE age 25, conn) # 使用参数化查询 query SELECT * FROM products WHERE price ? AND category ? df_params pd.read_sql(query, conn, params[100, electronics]) # 读取整个表 df_table pd.read_sql_table(products, conn) # 关闭连接 conn.close()4.4 数据导出操作将处理后的数据导出为各种格式。# 导出为CSV df.to_csv(output.csv, indexFalse, encodingutf-8-sig) # 导出为Excel df.to_excel(output.xlsx, sheet_name处理结果, indexFalse) # 导出为JSON df.to_json(output.json, orientrecords, force_asciiFalse) # 导出到数据库 conn sqlite3.connect(output.db) df.to_sql(processed_data, conn, if_existsreplace, indexFalse) conn.close()5. 数据清洗与预处理5.1 处理缺失值缺失值是实际数据中常见的问题pandas提供了多种处理方式。# 创建包含缺失值的示例数据 data { 姓名: [张三, 李四, 王五, 赵六, None], 年龄: [25, 32, None, 40, 28], 薪资: [15000, None, 12000, 25000, 18000], 部门: [技术部, 销售部, None, 技术部, 销售部] } df pd.DataFrame(data) print(原始数据:) print(df) # 检测缺失值 print(\n缺失值统计:) print(df.isnull().sum()) print(\n缺失值位置:) print(df.isnull()) # 删除缺失值 df_dropna df.dropna() # 删除包含缺失值的行 print(\n删除缺失值后的数据:) print(df_dropna) # 填充缺失值 df_filled df.fillna({ 年龄: df[年龄].mean(), # 用平均值填充年龄 薪资: df[薪资].median(), # 用中位数填充薪资 部门: 未知部门, # 用固定值填充部门 姓名: 未知姓名 }) print(\n填充缺失值后的数据:) print(df_filled) # 向前填充或向后填充 df_ffill df.fillna(methodffill) # 用前一个有效值填充 print(\n向前填充后的数据:) print(df_ffill)5.2 数据去重处理重复数据是数据清洗的重要环节。# 创建包含重复数据的示例 data { 姓名: [张三, 李四, 张三, 王五, 李四], 年龄: [25, 32, 25, 40, 32], 城市: [北京, 上海, 北京, 广州, 上海] } df pd.DataFrame(data) print(原始数据:) print(df) # 检测重复行 print(\n重复行:) print(df.duplicated()) print(\n重复行统计:) print(df.duplicated().sum()) # 删除重复行 df_dedup df.drop_duplicates() print(\n去重后的数据:) print(df_dedup) # 基于特定列去重 df_dedup_col df.drop_duplicates(subset[姓名]) print(\n基于姓名去重:) print(df_dedup_col) # 保留最后出现的重复项 df_keep_last df.drop_duplicates(keeplast) print(\n保留最后出现的重复项:) print(df_keep_last)5.3 数据类型转换正确的数据类型对于数据分析至关重要。# 创建混合类型数据 data { 年龄: [25, 32, 40, 28], # 字符串格式的数字 薪资: [15000.0, 18000.5, 12000.0, 25000.0], 入职日期: [2020-01-15, 2019-03-20, 2021-06-10, 2018-11-05], 是否全职: [是, 否, 是, 是] } df pd.DataFrame(data) print(原始数据类型:) print(df.dtypes) # 数据类型转换 df[年龄] df[年龄].astype(int) # 转换为整数 df[薪资] df[薪资].astype(int) # 转换为整数会截断小数 df[入职日期] pd.to_datetime(df[入职日期]) # 转换为日期时间 df[是否全职] df[是否全职].map({是: True, 否: False}) # 映射转换 print(\n转换后的数据类型:) print(df.dtypes) print(\n转换后的数据:) print(df) # 使用pd.to_numeric进行安全转换 df_safe pd.DataFrame({数值: [1, 2, 3.5, 4.0, 无效值]}) df_safe[数值] pd.to_numeric(df_safe[数值], errorscoerce) # 无效值转为NaN print(\n安全数值转换:) print(df_safe)5.4 字符串数据处理pandas提供了强大的字符串操作方法。# 创建字符串数据示例 data { 姓名: [张三, 李四, 王五, 赵六], 邮箱: [zhangsanemail.com, lisitest.com, wangwuexample.com, zhaoliusample.org], 电话: [138-0011-0011, 139-0022-0022, 137-0033-0033, 136-0044-0044] } df pd.DataFrame(data) print(原始数据:) print(df) # 字符串操作 df[姓名大写] df[姓名].str.upper() df[邮箱域名] df[邮箱].str.split().str[1] df[电话简写] df[电话].str.replace(-, ) df[姓名长度] df[姓名].str.len() print(\n字符串处理后的数据:) print(df) # 字符串匹配和过滤 contains_com df[邮箱].str.contains(com) print(\n包含com的邮箱:) print(df[contains_com]) # 字符串切片 df[姓名姓氏] df[姓名].str[0] # 取第一个字符作为姓氏 print(\n提取姓氏后的数据:) print(df)6. 数据筛选与排序6.1 数据筛选操作基于条件筛选数据是数据分析中的常见需求。# 创建示例数据 data { 姓名: [张三, 李四, 王五, 赵六, 钱七, 孙八], 年龄: [25, 32, 28, 40, 22, 35], 部门: [技术部, 销售部, 技术部, 人事部, 销售部, 技术部], 薪资: [15000, 18000, 16000, 22000, 12000, 19000], 城市: [北京, 上海, 广州, 北京, 深圳, 上海] } df pd.DataFrame(data) print(原始数据:) print(df) # 基本筛选薪资大于15000的员工 high_salary df[df[薪资] 15000] print(\n薪资大于15000的员工:) print(high_salary) # 多条件筛选技术部且薪资大于15000 tech_high_salary df[(df[部门] 技术部) (df[薪资] 15000)] print(\n技术部且薪资大于15000的员工:) print(tech_high_salary) # 使用query方法筛选 query_result df.query(年龄 30 and 城市 in [北京, 上海]) print(\n年龄≥30且在北京或上海的员工:) print(query_result) # 使用isin方法筛选 cities [北京, 上海] city_filter df[df[城市].isin(cities)] print(\n在北京或上海的员工:) print(city_filter) # 使用loc进行标签筛选 filtered_loc df.loc[(df[年龄] 25) (df[薪资] 20000), [姓名, 部门, 薪资]] print(\n年龄25且薪资20000的员工选择特定列:) print(filtered_loc)6.2 数据排序操作排序可以帮助我们更好地理解数据分布。# 单列排序 sorted_by_salary df.sort_values(薪资) print(按薪资升序排序:) print(sorted_by_salary) # 降序排序 sorted_desc df.sort_values(薪资, ascendingFalse) print(\n按薪资降序排序:) print(sorted_desc) # 多列排序 multi_sorted df.sort_values([部门, 薪资], ascending[True, False]) print(\n先按部门升序再按薪资降序排序:) print(multi_sorted) # 按索引排序 df_sorted_index df.sort_index(ascendingFalse) print(\n按索引降序排序:) print(df_sorted_index) # 使用key参数进行自定义排序 # 例如按姓名长度排序 df_name_length df.copy() df_name_length[姓名长度] df_name_length[姓名].str.len() sorted_by_length df_name_length.sort_values(姓名长度) print(\n按姓名长度排序:) print(sorted_by_length)6.3 数据采样和随机选择# 随机采样 random_sample df.sample(n3) # 随机选择3行 print(随机选择3行数据:) print(random_sample) # 按比例采样 frac_sample df.sample(frac0.5) # 随机选择50%的数据 print(\n随机选择50%的数据:) print(frac_sample) # 不放回采样 without_replacement df.sample(n2, replaceFalse) print(\n不放回采样2行:) print(without_replacement) # 放回采样 with_replacement df.sample(n10, replaceTrue) # 可能包含重复行 print(\n放回采样10行:) print(with_replacement) # 分层采样需要手动实现 def stratified_sample(df, column, fractions): samples [] for value, frac in fractions.items(): subset df[df[column] value] sample subset.sample(fracfrac) samples.append(sample) return pd.concat(samples) # 按部门分层采样 stratified stratified_sample(df, 部门, {技术部: 0.5, 销售部: 0.5, 人事部: 1.0}) print(\n分层采样结果:) print(stratified)7. 数据聚合与分组分析7.1 基本分组操作分组分析是pandas最强大的功能之一。# 按部门分组 grouped df.groupby(部门) print(分组对象:, grouped) # 查看分组结果 for name, group in grouped: print(f\n{name}部门:) print(group) # 分组后聚合计算 department_stats grouped.agg({ 薪资: [mean, max, min, std], 年龄: [mean, count] }) print(\n各部门统计信息:) print(department_stats) # 单列分组统计 salary_by_dept grouped[薪资].mean() print(\n各部门平均薪资:) print(salary_by_dept)7.2 多列分组和高级聚合# 按部门和城市分组 multi_grouped df.groupby([部门, 城市]) # 多级分组统计 multi_stats multi_grouped.agg({ 薪资: [mean, count], 年龄: median }) print(按部门和城市分组的统计信息:) print(multi_stats) # 使用自定义聚合函数 def salary_range(series): return series.max() - series.min() custom_agg df.groupby(部门).agg({ 薪资: [(平均薪资, mean), (薪资范围, salary_range)], 年龄: [(平均年龄, mean), (人数, count)] }) print(\n自定义聚合统计:) print(custom_agg)7.3 数据透视表透视表是数据分析中常用的工具。# 创建透视表 pivot_table df.pivot_table( values薪资, index部门, columns城市, aggfuncmean, fill_value0 ) print(部门-城市薪资透视表:) print(pivot_table) # 多值透视表 multi_pivot df.pivot_table( values[薪资, 年龄], index部门, aggfunc{薪资: [mean, max], 年龄: mean} ) print(\n多值透视表:) print(multi_pivot) # 添加边际汇总 pivot_with_margins df.pivot_table( values薪资, index部门, columns城市, aggfuncmean, marginsTrue, margins_name总计 ) print(\n带总计的透视表:) print(pivot_with_margins)8. 数据合并与连接8.1 数据合并操作# 创建两个示例DataFrame df1 pd.DataFrame({ 员工ID: [1, 2, 3, 4], 姓名: [张三, 李四, 王五, 赵六], 部门: [技术部, 销售部, 技术部, 人事部] }) df2 pd.DataFrame({ 员工ID: [1, 2, 5, 6], 薪资: [15000, 18000, 20000, 12000], 入职年份: [2020, 2019, 2021, 2022] }) print(DataFrame 1:) print(df1) print(\nDataFrame 2:) print(df2) # 内连接 inner_join pd.merge(df1, df2, on员工ID, howinner) print(\n内连接结果:) print(inner_join) # 左连接 left_join pd.merge(df1, df2, on员工ID, howleft) print(\n左连接结果:) print(left_join) # 外连接 outer_join pd.merge(df1, df2, on员工ID, howouter) print(\n外连接结果:) print(outer_join)8.2 数据连接操作# 使用concat连接数据 df3 pd.DataFrame({ 员工ID: [7, 8], 姓名: [钱七, 孙八], 部门: [销售部, 技术部] }) # 纵向连接 vertical_concat pd.concat([df1, df3], ignore_indexTrue) print(纵向连接结果:) print(vertical_concat) # 横向连接 df4 pd.DataFrame({ 员工ID: [1, 2, 3, 4], 项目: [项目A, 项目B, 项目A, 项目C] }) horizontal_concat pd.concat([df1, df4[[项目]]], axis1) print(\n横向连接结果:) print(horizontal_concat)9. 时间序列数据处理9.1 时间序列基础# 创建时间序列数据 dates pd.date_range(2023-01-01, periods6, freqD) time_series_data { 日期: dates, 销售额: [1000, 1200, 800, 1500, 2000, 1800], 产品: [A, B, A, C, B, A] } ts_df pd.DataFrame(time_series_data) ts_df.set_index(日期, inplaceTrue) print(时间序列数据:) print(ts_df) # 时间序列重采样 daily_sales ts_df[销售额].resample(2D).mean() # 2天平均 print(\n2天平均销售额:) print(daily_sales) # 移动窗口计算 rolling_mean ts_df[销售额].rolling(window3).mean() print(\n3天移动平均:) print(rolling_mean)9.2 时间序列分析# 创建更复杂的时间序列数据 np.random.seed(42) dates pd.date_range(2023-01-01, periods90, freqD) sales_data { 日期: dates, 销售额: np.random.normal(1000, 200, 90).cumsum(), 订单数: np.random.poisson(50, 90) } sales_df pd.DataFrame(sales_data) sales_df.set_index(日期, inplaceTrue) print(销售时间序列数据:) print(sales_df.head()) # 时间序列分解趋势、季节性、残差 from statsmodels.tsa.seasonal import seasonal_decompose # 假设有月度季节性需要足够的数据 decomposition seasonal_decompose(sales_df[销售额][:30], modeladditive, period7) print(\n时间序列分解完成)10. 实战案例销售数据分析10.1 案例背景和数据准备让我们通过一个完整的销售数据分析案例来综合运用pandas的各种功能。# 创建模拟销售数据 np.random.seed(42) n_records 1000 data { 订单ID: range(1, n_records 1), 日期: pd.date_range(2023-01-01, periodsn_records, freqH), 产品类别: np.random.choice([电子产品, 服装, 食品, 家居], n_records), 销售额: np.random.normal(100, 30, n_records), 数量: np.random.randint(1, 10, n_records), 客户类型: np.random.choice([新客户, 老客户], n_records), 地区: np.random.choice([华北, 华东, 华南, 西部], n_records) } sales_df pd.DataFrame(data) sales_df[销售额] sales_df[销售额].clip(lower10) # 确保销售额为正数 print(销售数据概览:) print(sales_df.head()) print(f\n数据形状: {sales_df.shape}) print(\n数据类型:) print(sales_df.dtypes)10.2 数据探索性分析# 基本统计信息 print(销售数据描述性统计:) print(sales_df.describe()) # 分类变量统计 print(\n产品类别分布:) print(sales_df[产品类别].value_counts()) print(\n地区分布:) print(sales_df[地区].value_counts()) # 时间维度分析 sales_df[小时] sales_df[日期].dt.hour sales_df[星期] sales_df[日期].dt.day_name() print(\n按小时统计销售额:) hourly_sales sales_df.groupby(小时)[销售额].sum() print(hourly_sales)10.3 深入分析# 产品类别分析 category_analysis sales_df.groupby(产品类别).agg({ 销售额: [sum, mean, count], 数量: sum }).round(2) print(产品类别分析:) print(category_analysis) # 地区表现分析 region_analysis sales_df.groupby(地区).agg({ 销售额: [sum, mean], 订单ID: count }).round(2) region_analysis.columns [总销售额, 平均销售额, 订单数量] print(\n地区表现分析:) print(region_analysis) # 客户类型分析 customer_analysis sales_df.groupby(客户类型).agg({ 销售额: [sum, mean, count], 数量: mean }).round(2) print(\n客户类型分析:) print(customer_analysis)10.4 数据可视化集成import matplotlib.pyplot as plt # 设置中文字体 plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False # 创建可视化 fig, axes plt.subplots(2, 2, figsize(15, 10)) # 1. 产品类别销售额分布 category_sales sales_df.groupby(产品类别)[销售额].sum() axes[0, 0].pie(category_sales, labelscategory_sales.index, autopct%1.1f%%) axes[0, 0].set_title(产品类别销售额分布) # 2. 各地区销售额 region_sales sales_df.groupby(地区)[销售额].sum() axes[0, 1].bar(region_sales.index, region_sales.values) axes[0, 1].set_title(各地区销售额) axes[0, 1].set_ylabel(销售额) # 3. 时间趋势 daily_trend sales_df.set_index(日期)[销售额].resample(D).sum() axes[1, 0].plot(daily_trend.index, daily_trend.values) axes[1, 0].set_title(每日销售额趋势) axes[1, 0].set_ylabel(销售额) axes[1, 0].tick_params(axisx, rotation45) # 4. 客户类型对比 customer_sales sales_df.groupby(客户类型)[销售额].mean() axes[1, 1].bar(customer_sales.index, customer_sales.values) axes[1, 1].set_title(客户类型平均销售额) axes[1, 1].set_ylabel(平均销售额) plt.tight_layout() plt.show() # 保存分析结果 analysis_results { category_analysis: category_analysis, region_analysis: region_analysis, customer_analysis: customer_analysis } print(分析完成结果已保存!)11. 性能优化与最佳实践11.1 数据操作性能优化# 使用适当的数据类型节省内存 def optimize_memory(df): 优化DataFrame内存使用 original_memory df.memory_usage(deepTrue).sum() # 优化数值类型 for col in df.select_dtypes(include[int]).columns: df[col] pd.to_numeric(df[col], downcastinteger) for col in df.select_dtypes(include[float]).columns: df[col] pd.to_numeric(df[col], downcastfloat) # 优化对象类型 for col in df.select_dtypes(include[object]).columns: if df[col].nunique() / len(df) 0.5: # 唯一值比例小于50% df[col] df[col].astype(category) optimized_memory df.memory_usage(deepTrue).sum() reduction (original_memory - optimized_memory) / original_memory * 100 print(f内存使用优化: {original_memory:.2f} MB - {optimized_memory:.2f} MB) print(f减少: {reduction:.1f}%) return df # 应用内存优化 optimized_sales_df optimize_memory(sales_df.copy())11.2 高效数据处理技巧# 使用向量化操作替代循环 # 不推荐的方式慢 def calculate_discount_bad(df): discounts [] for i in range(len(df)): if df.iloc[i][销售额] 150: discounts.append(df.iloc[i][销售额] * 0.1) else: discounts.append(0) return discounts # 推荐的方式快 def calculate_discount_good(df): return np.where(df[销售额] 150, df[销售额] * 0.1, 0) # 测试性能 import time start_time time.time() discounts_bad calculate_discount_bad(sales_df) bad_time time.time() - start_time start_time time.time() discounts_good calculate_discount_good(sales_df) good_time time.time() - start_time print(f循环方式耗时: {bad_time:.4f}秒) print(f向量化方式耗时: {good_time:.4f}秒) print(f性能提升: {bad_time/good_time:.1f}倍)12. 常见问题与解决方案12.1 安装和导入问题问题1导入pandas时出现ModuleNotFoundError解决方案# 确保已正确安装pandas pip install pandas # 如果使用虚拟环境请激活虚拟环境 # 检查Python环境 python -c import pandas as pd; print(pd.__version__)问题2版本兼容性问题解决方案# 检查版本兼容性 import pandas as pd print(fpandas版本: {pd.__version__}) # 升级到最新版本 # pip install --upgrade pandas12.2 数据处理常见问题问题3内存不足处理大型数据集解决方案# 1. 使用分块读取 chunk_size 10000 chunks [] for chunk in pd.read_csv(large_file.csv, chunksizechunk_size): # 处理每个数据块 processed_chunk process_function(chunk) chunks.append(processed_chunk) result pd.concat(chunks) # 2. 指定数据类型减少内存使用 dtypes {column1: category, column2: float32} df pd.read_csv(large_file.csv, dtypedtypes) # 3. 只读取需要的列 usecols [important_col1, important_col2] df pd.read_csv(large_file.csv, usecolsusecols)**问题4