1. 先搞清楚 Pandas 到底解决什么问题,以及它为什么值得学

如果你刚开始接触 Python 数据分析,或者已经在用 Excel 但处理稍大一点的数据就卡顿,Pandas 大概率会成为你第一个真正用起来的专业工具。它不是“又一个数据处理库”,而是几乎所有 Python 数据分析、机器学习、自动化报表场景的底层标配。

很多人误以为 Pandas 只是“高级版的 Excel”,其实它的核心价值在于三件事:

  1. 能处理 Excel 打不开或操作卡顿的数据量 :Excel 超过几十万行就容易崩溃,而 Pandas 可以轻松处理百万行级别的数据(当然取决于你的内存大小)。
  2. 能把重复的数据清洗、转换、计算步骤写成脚本 :不用每次手动操作,特别适合定期报表、数据预处理流水线。
  3. 为后续的机器学习、可视化、API 输出做准备 :几乎所有的 Python 数据科学库(如 Scikit-learn、Matplotlib)都直接支持 Pandas 的数据结构。

我建议不要一上来就想着“精通”,而是先明确你最常遇到的几个场景:是不是经常要合并多个 Excel 文件?是不是要对大量数据进行分组统计?是不是需要清洗不规则的数据格式?这些具体问题,Pandas 都有对应的函数可以直接解决。

2. 安装和环境配置:避开第一个坑

Pandas 是 Python 的第三方库,所以安装前你得先有 Python 环境。这里最容易出问题的是版本兼容性和安装方式。

2.1 选择 Python 环境

如果你还没装 Python,直接去官网下载最新稳定版(目前是 3.11+)。Windows、macOS、Linux 都支持,但注意:

  • Windows 用户 :安装时务必勾选“Add Python to PATH”,否则后面命令行会找不到 Python。
  • macOS 用户 :系统自带的 Python 版本可能较旧,建议用 Homebrew 重新安装或直接下载官方安装包。
  • Linux 用户 :通常自带 Python,但可能需要用包管理器安装 pip(如 sudo apt install python3-pip )。

2.2 安装 Pandas 的两种方式

方式一:用 pip 安装(最通用) 打开终端(Windows 是 CMD 或 PowerShell,macOS/Linux 是 Terminal),输入:

pip install pandas

如果你系统里有多个 Python 版本,可能需要用 pip3

pip3 install pandas

方式二:用 Conda 安装(适合已装 Anaconda 或 Miniconda 的用户)

conda install pandas

Conda 的好处是会自动处理依赖库(如 NumPy),适合科学计算全家桶环境。

安装后验证 : 打开 Python 交互环境(命令行输入 python python3 ),输入:

import pandas as pd
print(pd.__version__)

如果没报错且显示版本号(如 2.1.4),说明安装成功。

2.3 常见安装问题排查

  • 报错“pip 不是内部命令” :说明 Python 没正确加入 PATH,重新安装 Python 或手动配置环境变量。
  • 报错权限不足 :在命令前加 sudo (macOS/Linux),或用 pip install --user pandas
  • 下载超时或失败 :换国内镜像源,如 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pandas
  • 安装成功但 import 报错 :可能是多版本 Python 冲突,确认当前运行的 Python 和安装 Pandas 的是同一个。

3. 核心数据结构:Series 和 DataFrame 才是关键

Pandas 最核心的两个概念是 Series 和 DataFrame。很多教程花大量时间讲函数,但如果你没理解这两个结构,后面会越学越乱。

3.1 Series:带标签的一维数组

Series 可以理解为“增强版的列表”,每个元素都有对应的索引标签。创建 Series 的最简单方式:

import pandas as pd

# 从列表创建
scores = pd.Series([85, 90, 78, 92], index=['张三', '李四', '王五', '赵六'])
print(scores)

输出:

张三    85
李四    90
王五    78
赵六    92
dtype: int64

什么时候用 Series?

  • 单列数据(如温度记录、产品价格)
  • 作为 DataFrame 的一列
  • 简单的键值对数据(比字典更方便统计)

3.2 DataFrame:二维表格,90% 的使用场景

DataFrame 是多个 Series 的集合,相当于 Excel 的一张工作表。这是 Pandas 最常用的结构。

创建 DataFrame 的几种方式:

# 从字典创建(最常用)
data = {
    '姓名': ['张三', '李四', '王五'],
    '年龄': [25, 30, 28],
    '城市': ['北京', '上海', '广州']
}
df = pd.DataFrame(data)
print(df)

查看数据的基本信息:

df.head()        # 前5行
df.tail(3)       # 后3行  
df.shape         # 行列数:(3, 3)
df.columns       # 列名:Index(['姓名', '年龄', '城市'], dtype='object')
df.info()        # 数据类型、内存占用等详细信息
df.describe()    # 数值列的统计摘要(计数、均值、标准差等)

关键理解:

  • DataFrame 的每一列都是一个 Series
  • 索引(行标签)和列名是快速定位数据的关键
  • 大部分操作都是围绕“选择某些行/列”然后“对它们进行计算”

4. 数据读取和导出:从实际文件开始

学 Pandas 一定要用真实数据练习,而不是一直用演示数据。最常见的需求就是读写各种格式的文件。

4.1 读取常见文件格式

读取 CSV 文件(最常用):

df = pd.read_csv('data.csv')

读取 Excel 文件:

df = pd.read_excel('data.xlsx', sheet_name='Sheet1')

读取 JSON 文件:

df = pd.read_json('data.json')

重要参数(避免踩坑):

  • encoding :中文文件常用 encoding='utf-8' encoding='gbk'
  • header :指定哪行作为列名, header=0 表示第一行
  • index_col :指定哪列作为行索引
  • na_values :指定哪些值被视为缺失值(如 na_values=['NULL', 'N/A']

4.2 读取时常见问题处理

中文乱码问题:

# 尝试不同的编码
df = pd.read_csv('data.csv', encoding='gbk')  # Windows 创建的文件
df = pd.read_csv('data.csv', encoding='utf-8-sig')  # 带 BOM 的 UTF-8

大文件内存优化:

# 只读取需要的列
df = pd.read_csv('large_data.csv', usecols=['列1', '列2'])

# 分块读取
chunk_iter = pd.read_csv('large_data.csv', chunksize=10000)
for chunk in chunk_iter:
    process(chunk)  # 逐块处理

文件路径问题:

  • 相对路径: 'data.csv' (当前目录下的文件)
  • 绝对路径: 'C:/Users/name/data.csv' (Windows)或 '/home/name/data.csv' (Linux/macOS)
  • 建议使用原始字符串或正斜杠: r'C:\Users\data.csv' 'C:/Users/data.csv'

4.3 数据导出

保存为 CSV:

df.to_csv('output.csv', index=False)  # index=False 表示不保存行索引

保存为 Excel:

df.to_excel('output.xlsx', sheet_name='结果', index=False)

保存为 JSON:

df.to_json('output.json', orient='records', force_ascii=False)  # force_ascii=False 支持中文

5. 数据清洗实战:80% 的时间都在这里

真实数据很少是完美的,数据清洗是 Pandas 最重要的应用场景。下面按实际处理顺序介绍关键操作。

5.1 处理缺失值

检测缺失值:

df.isnull().sum()  # 每列缺失值数量
df.isnull().mean()  # 每列缺失值比例

处理方式:

# 删除缺失行
df.dropna()  # 删除任何包含缺失值的行
df.dropna(subset=['重要列'])  # 只删除重要列缺失的行

# 填充缺失值
df.fillna(0)  # 用0填充
df.fillna({'列1': 0, '列2': '未知'})  # 不同列用不同值填充
df['列名'].fillna(df['列名'].mean())  # 用均值填充

选择策略:

  • 缺失值很少(<5%):可以直接删除
  • 缺失值较多:根据业务逻辑填充(用均值、中位数、众数或预测值)
  • 重要指标缺失:可能需要回源头重新采集

5.2 数据类型转换

查看当前类型:

df.dtypes

类型转换:

# 转换为数值类型
df['价格'] = pd.to_numeric(df['价格'], errors='coerce')  # 转换失败变为NaN

# 转换为日期类型
df['日期'] = pd.to_datetime(df['日期'])

# 转换为分类类型(节省内存)
df['城市'] = df['城市'].astype('category')

为什么重要:

  • 正确的数据类型才能进行相应的计算(如日期差、数值统计)
  • 分类类型可以大幅减少内存占用
  • 避免后续分析时出现意想不到的错误

5.3 重复值处理

检测重复值:

df.duplicated().sum()  # 完全重复的行数
df.duplicated(subset=['列1', '列2']).sum()  # 指定列重复的行数

处理重复值:

df.drop_duplicates()  # 删除完全重复的行
df.drop_duplicates(subset=['身份证号'], keep='last')  # 按身份证去重,保留最后一条

5.4 字符串清洗

常用字符串操作:

# 大小写转换
df['姓名'] = df['姓名'].str.lower()

# 去除空格
df['地址'] = df['地址'].str.strip()

# 字符串替换
df['产品名'] = df['产品名'].str.replace('旧型号', '新型号')

# 字符串包含检测
df[df['描述'].str.contains('优惠', na=False)]  # 筛选包含"优惠"的行

6. 数据筛选和排序:快速找到你要的信息

6.1 条件筛选

基本条件筛选:

# 单条件
df[df['年龄'] > 30]  # 年龄大于30的行

# 多条件
df[(df['年龄'] > 30) & (df['城市'] == '北京')]  # 并且关系
df[(df['年龄'] > 30) | (df['城市'] == '上海')]  # 或者关系

# 字符串条件
df[df['姓名'].str.startswith('张')]  # 姓张的人

常用筛选方法:

# isin:在某个列表中
df[df['城市'].isin(['北京', '上海', '广州'])]

# between:在某个范围内
df[df['年龄'].between(25, 35)]

# query方法(更简洁的语法)
df.query('年龄 > 30 and 城市 == "北京"')

6.2 行列选择

选择列:

df['姓名']           # 单列,返回Series
df[['姓名', '年龄']]  # 多列,返回DataFrame

选择行:

df.iloc[0]          # 第0行
df.iloc[0:5]        # 前5行
df.iloc[[0, 2, 4]]  # 第0、2、4行

df.loc[df['年龄'] > 30]  # 按条件选择行

iloc vs loc 的区别:

  • iloc :按位置选择(整数索引)
  • loc :按标签选择(行索引名和列名)

6.3 数据排序

按值排序:

df.sort_values('年龄')                    # 按年龄升序
df.sort_values('年龄', ascending=False)   # 按年龄降序
df.sort_values(['城市', '年龄'])          # 先按城市排,同城市按年龄排

按索引排序:

df.sort_index()  # 按行索引排序

7. 数据分组和聚合:从描述到分析的关键一步

分组聚合是 Pandas 最强大的功能之一,让你能从不同维度分析数据。

7.1 基本分组操作

单列分组:

grouped = df.groupby('城市')

多列分组:

grouped = df.groupby(['城市', '性别'])

分组后查看:

grouped.size()        # 每组的行数
grouped.groups        # 查看分组详情

7.2 常用聚合函数

基本聚合:

grouped['年龄'].mean()     # 每组的平均年龄
grouped['工资'].sum()      # 每组的工资总和
grouped['身高'].max()      # 每组的最大身高

多个聚合函数:

grouped['年龄'].agg(['mean', 'std', 'count'])  # 同时计算均值、标准差、计数

不同列用不同聚合:

agg_dict = {'年龄': 'mean', '工资': 'sum', '姓名': 'count'}
grouped.agg(agg_dict)

7.3 实际案例:销售数据分析

假设有销售数据:

sales_data = {
    '日期': ['2024-01-01', '2024-01-01', '2024-01-02', '2024-01-02'],
    '销售员': ['张三', '李四', '张三', '李四'],
    '产品': ['A', 'B', 'A', 'B'],
    '金额': [100, 150, 200, 120]
}
sales_df = pd.DataFrame(sales_data)

# 按销售员分组,计算总销售额
sales_by_person = sales_df.groupby('销售员')['金额'].sum()

# 按产品和日期分组,计算平均销售额
sales_by_product_date = sales_df.groupby(['产品', '日期'])['金额'].mean()

8. 数据合并和连接:整合多个数据源

实际工作中,数据往往分散在多个文件或表中,需要合并分析。

8.1 纵向合并(追加行)

concat 基本用法:

# 合并两个结构相同的DataFrame
df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'A': [5, 6], 'B': [7, 8]})
result = pd.concat([df1, df2], ignore_index=True)

实际应用:合并多个月份的销售数据

jan_data = pd.read_csv('sales_jan.csv')
feb_data = pd.read_csv('sales_feb.csv')
mar_data = pd.read_csv('sales_mar.csv')

all_data = pd.concat([jan_data, feb_data, mar_data], ignore_index=True)

8.2 横向合并(连接列)

merge 基本用法(类似 SQL JOIN):

# 两个有共同列的DataFrame
orders = pd.DataFrame({
    '订单ID': [1, 2, 3],
    '客户ID': [101, 102, 101],
    '金额': [100, 200, 150]
})

customers = pd.DataFrame({
    '客户ID': [101, 102, 103],
    '姓名': ['张三', '李四', '王五']
})

# 内连接(默认)
result = pd.merge(orders, customers, on='客户ID')

# 左连接(保留所有订单,即使客户信息缺失)
result_left = pd.merge(orders, customers, on='客户ID', how='left')

连接类型总结:

  • inner :只保留两个表都有的键(交集)
  • left :保留左表所有记录,右表没有的用NaN填充
  • right :保留右表所有记录,左表没有的用NaN填充
  • outer :保留所有记录(并集)

8.3 实际案例:学生成绩管理系统

# 学生基本信息
students = pd.DataFrame({
    '学号': [1, 2, 3],
    '姓名': ['张三', '李四', '王五'],
    '班级': ['A班', 'B班', 'A班']
})

# 成绩信息
scores = pd.DataFrame({
    '学号': [1, 2, 1, 3],
    '科目': ['数学', '数学', '英语', '数学'],
    '分数': [85, 90, 88, 92]
})

# 合并信息
student_scores = pd.merge(students, scores, on='学号', how='left')

# 按班级和科目统计平均分
class_avg = student_scores.groupby(['班级', '科目'])['分数'].mean()

9. 时间序列处理:专门的时间数据分析技巧

Pandas 对时间序列数据的支持非常强大,特别是金融、物联网、日志分析等场景。

9.1 时间类型转换

字符串转时间:

df['日期'] = pd.to_datetime(df['日期字符串'])

设置时间索引:

df.set_index('日期', inplace=True)

9.2 时间序列重采样

降采样(低频化):

# 每日数据转为月度数据
df.resample('M').mean()  # 月均值
df.resample('M').sum()   # 月总和

升采样(高频化):

# 月度数据转为每日数据(需要填充)
df.resample('D').ffill()  # 前向填充
df.resample('D').interpolate()  # 插值填充

9.3 时间窗口计算

滚动窗口(固定大小):

# 7日滚动平均
df['价格'].rolling(window=7).mean()

# 30日滚动最大值
df['成交量'].rolling(window=30).max()

扩展窗口(从开始到现在):

# 累计平均值
df['价格'].expanding().mean()

# 累计最大值
df['价格'].expanding().max()

10. 性能优化和高级技巧

10.1 内存优化

查看内存使用:

df.info(memory_usage='deep')  # 详细内存使用

优化数据类型:

# 整数列优化
df['小整数列'] = df['小整数列'].astype('int8')

# 字符串列优化
df['分类列'] = df['分类列'].astype('category')

# 浮点数列优化
df['小数列'] = df['小数列'].astype('float32')

10.2 大数据处理技巧

分块处理:

chunk_size = 10000
result_chunks = []

for chunk in pd.read_csv('large_file.csv', chunksize=chunk_size):
    processed_chunk = process_function(chunk)  # 处理每个块
    result_chunks.append(processed_chunk)

result = pd.concat(result_chunks)

使用更高效的数据格式:

# 保存为 Parquet 格式(压缩好,读取快)
df.to_parquet('data.parquet')
df = pd.read_parquet('data.parquet')

10.3 向量化操作替代循环

不好的做法(慢):

for i in range(len(df)):
    if df.loc[i, '年龄'] > 30:
        df.loc[i, '类别'] = '中年'
    else:
        df.loc[i, '类别'] = '青年'

好的做法(快):

df['类别'] = np.where(df['年龄'] > 30, '中年', '青年')

11. 常见错误和调试技巧

11.1 复制警告问题

SettingWithCopyWarning 解决方案:

# 会产生警告的代码
subset = df[df['年龄'] > 30]
subset['新列'] = 1  # 警告!

# 解决方案1:明确复制
subset = df[df['年龄'] > 30].copy()
subset['新列'] = 1  # 安全

# 解决方案2:使用 loc
df.loc[df['年龄'] > 30, '新列'] = 1  # 安全

11.2 缺失值处理陷阱

NaN 的比较问题:

# 错误:NaN == NaN 是 False
df[df['列名'] == np.nan]  # 不会匹配任何行

# 正确:使用 isna()
df[df['列名'].isna()]

11.3 数据类型错误

常见类型错误排查:

# 检查是否有非数值字符
pd.to_numeric(df['应该是数字的列'], errors='coerce').isna().sum()

# 检查日期格式是否统一
pd.to_datetime(df['日期列'], errors='coerce').isna().sum()

12. 实战项目思路:从学习到应用

学完基础后,最好的巩固方式就是做实际项目。以下是几个适合练习的方向:

12.1 销售数据分析项目

目标: 分析某公司销售数据,找出销售趋势和优化点

步骤:

  1. 读取多个月份的销售 CSV 文件
  2. 清洗数据(处理缺失值、重复值、异常值)
  3. 按产品、地区、时间维度分析销售额
  4. 计算关键指标(同比增长率、客户复购率等)
  5. 输出可视化报告

12.2 网站用户行为分析

目标: 分析用户访问日志,优化用户体验

步骤:

  1. 解析日志文件(可能需要正则表达式)
  2. 按时间窗口分析访问量变化
  3. 用户路径分析(点击流数据)
  4. 异常检测(如爬虫访问识别)
  5. 输出用户行为洞察报告

12.3 自动化报表系统

目标: 搭建自动化的数据报表流程

步骤:

  1. 定时从数据库或 API 获取数据
  2. 用 Pandas 进行数据清洗和计算
  3. 生成汇总统计和可视化
  4. 自动发送邮件或保存到指定位置
  5. 添加错误处理和日志记录

学习 Pandas 的关键不是记住所有函数,而是理解数据处理的思维模式:先明确目标,再选择合适的工具和方法。建议从一个小项目开始,边做边学,遇到问题查文档或搜索解决方案,这样进步最快。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐