1. Pandas速查手册:数据分析师的瑞士军刀

第一次接触Pandas是在2015年处理一个电商用户行为分析项目时。当时面对几十万行的CSV数据,传统的Excel已经力不从心,而Pandas仅用几行代码就完成了数据加载、清洗和分析的全流程。从那时起,这份"速查手册"就成为了我数据分析工作中最常翻阅的参考资料。

Pandas作为Python生态中最强大的数据分析库,其核心价值在于:

  • 提供高性能的DataFrame数据结构,处理结构化数据比原生Python快10-100倍
  • 内置丰富的数据操作API,涵盖数据清洗、转换、聚合等全流程
  • 完美兼容NumPy、Matplotlib等科学计算库,形成完整的数据分析工具链
  • 支持从CSV、Excel、SQL、JSON等多种数据源快速导入导出

这份手册将聚焦实际工作中最高频使用的Pandas功能,通过典型场景示例展示如何用最简洁的代码解决90%的数据处理问题。无论是刚入门的数据分析师,还是需要快速查阅某个API用法的资深工程师,都能从中获得实用参考。

2. 核心数据结构与基础操作

2.1 Series与DataFrame的创建与属性

Pandas的两大核心数据结构就像Excel中的列和工作表:

import pandas as pd

# 创建Series(带标签的一维数组)
temperatures = pd.Series([22.5, 23.1, 24.3], 
                        index=['北京', '上海', '广州'],
                        name='日平均温度')

# 创建DataFrame(二维表格)
data = {
    '城市': ['北京', '上海', '广州'],
    '人口(万)': [2171, 2487, 1868],
    'GDP(亿元)': [36103, 38701, 25019]
}
df = pd.DataFrame(data, index=['A', 'B', 'C'])

关键属性速查:

  • df.shape :获取行列数(注意不是len(df))
  • df.columns :查看所有列名(可赋值修改)
  • df.index :查看行索引(支持重置reset_index())
  • df.dtypes :查看各列数据类型
  • df.info() :显示内存占用和类型摘要

2.2 数据读取与写入的实战技巧

实际项目中最常遇到的各种数据源处理方案:

# 处理含中文路径的CSV文件(engine参数很关键)
df = pd.read_csv('销售数据.csv', engine='python')

# 读取Excel特定工作表(skiprows跳过表头注释)
df = pd.read_excel('财务报告.xlsx', 
                  sheet_name='Q3',
                  skiprows=3)

# 从数据库读取(推荐使用SQLAlchemy连接)
from sqlalchemy import create_engine
engine = create_engine('mysql://user:pass@localhost/db')
df = pd.read_sql('SELECT * FROM orders', engine)

# 保存数据时的实用参数
df.to_csv('processed.csv', 
         index=False,  # 不保存行索引
         encoding='utf_8_sig')  # 支持Excel中文显示

避坑指南:读取大型文件时建议指定 dtype 参数避免类型推断开销,如 dtype={'phone': str} 将电话号码强制存为字符串。

3. 数据清洗与预处理实战

3.1 缺失值处理的五种策略

真实数据中缺失值的典型处理流程:

# 检测缺失值
null_counts = df.isnull().sum()

# 方案1:删除缺失行(适合缺失比例<5%的情况)
df_drop = df.dropna(subset=['重要列'])

# 方案2:填充固定值
df_fill = df.fillna({'年龄': 0, '收入': df['收入'].median()})

# 方案3:前向/后向填充(时间序列常用)
df_ffill = df.fillna(method='ffill')

# 方案4:插值法
df_interp = df.interpolate()

# 方案5:标记缺失值作为特殊类别
df['是否缺失'] = df['收入'].isnull().astype(int)

3.2 数据去重与异常值处理

电商数据清洗的典型示例:

# 删除完全重复的行
df = df.drop_duplicates()

# 按关键列去重(保留最后出现的记录)
df = df.drop_duplicates(subset=['用户ID', '订单日期'], 
                       keep='last')

# IQR方法检测数值异常值
Q1 = df['消费金额'].quantile(0.25)
Q3 = df['消费金额'].quantile(0.75)
IQR = Q3 - Q1
df_clean = df[~((df['消费金额'] < (Q1 - 1.5*IQR)) | 
                (df['消费金额'] > (Q3 + 1.5*IQR)))]

4. 数据筛选与高级索引

4.1 条件筛选的三种范式

# 布尔索引(最灵活)
high_gdp = df[df['GDP'] > 10000]

# query方法(适合复杂条件)
result = df.query('人口 > 2000 and GDP < 30000')

# loc/iloc访问(明确区分标签/位置索引)
# 获取前两行的指定列
subset = df.loc[['A', 'B'], ['城市', '人口']] 

# 按位置获取第2-3行
subset = df.iloc[1:3, :]

4.2 多重索引与数据透视

处理层次化索引的销售数据:

# 设置多重索引
df_multi = df.set_index(['地区', '城市'])

# 交叉分析(生成透视表)
pivot = pd.pivot_table(df,
                      values='销售额',
                      index='地区',
                      columns='季度',
                      aggfunc=['sum', 'mean'])

# 堆叠与解堆
stacked = pivot.stack()
unstacked = stacked.unstack()

5. 数据合并与分组聚合

5.1 数据集合并的四种方式

# 横向合并(类似SQL JOIN)
merged = pd.merge(df1, df2, 
                 left_on='key1', 
                 right_on='key2',
                 how='left')

# 纵向拼接(相同结构数据)
concated = pd.concat([df1, df2], axis=0)

# 按索引合并
joined = df1.join(df2, how='inner')

# 比较更新(类似字典update)
df1.update(df2)  # 用df2的值更新df1

经验之谈:merge()的how参数有left/right/inner/outer四种模式,处理用户订单数据时inner最常用,但做留存分析时需要outer保留所有用户。

5.2 分组聚合的完整流程

销售数据分析的典型分组操作:

# 基础分组
grouped = df.groupby(['地区', '产品类别'])

# 多维度聚合
agg_result = grouped.agg({
    '销售额': ['sum', 'mean', 'count'],
    '利润': lambda x: (x>0).mean()  # 利润率
})

# 使用命名聚合(Pandas 1.0+)
result = grouped.agg(
    total_sales=pd.NamedAgg(column='销售额', aggfunc='sum'),
    avg_price=pd.NamedAgg(column='单价', aggfunc='mean')
)

# 分组后过滤(筛选组内条件)
filtered = grouped.filter(lambda x: x['销售额'].sum() > 10000)

6. 时间序列处理技巧

6.1 时间类型转换与重采样

处理物联网设备数据的典型场景:

# 字符串转时间类型
df['时间'] = pd.to_datetime(df['timestamp'], 
                          format='%Y-%m-%d %H:%M:%S')

# 设为索引后按小时重采样
df = df.set_index('时间')
hourly = df.resample('H').mean()

# 滚动窗口计算(7天移动平均)
df['7d_avg'] = df['温度'].rolling('7D').mean()

# 时区处理(中国标准时间)
df = df.tz_localize('UTC').tz_convert('Asia/Shanghai')

6.2 日期特征工程

构建机器学习特征时的常用技巧:

df['年份'] = df.index.year
df['季度'] = df.index.quarter
df['是否周末'] = df.index.dayofweek >= 5
df['时段'] = df.index.hour.apply(
    lambda x: '凌晨' if x<6 else '上午' if x<12 else 
             '下午' if x<18 else '晚上')

7. 性能优化与高级技巧

7.1 处理千万级数据的四个诀窍

# 1. 指定数据类型节省内存
dtypes = {
    'id': 'int32',
    'price': 'float32',
    'category': 'category'  # 分类数据专用类型
}
df = pd.read_csv('large.csv', dtype=dtypes)

# 2. 使用迭代器分块处理
chunk_iter = pd.read_csv('huge.csv', 
                        chunksize=100000)
results = []
for chunk in chunk_iter:
    results.append(process(chunk))
final = pd.concat(results)

# 3. 避免链式赋值(使用loc单次操作)
# 错误方式:df[df['age']>30]['score'] = 100
# 正确方式:
df.loc[df['age']>30, 'score'] = 100

# 4. 使用eval()加速计算
df.eval('profit = revenue - cost', inplace=True)

7.2 与其他工具的协同使用

# 与NumPy互转
arr = df.values  # DataFrame转ndarray
df = pd.DataFrame(arr)  # ndarray转DataFrame

# 配合Matplotlib可视化
df.plot(kind='bar', x='城市', y='GDP')

# 使用Styler生成条件格式
(df.style
   .background_gradient(cmap='Blues')
   .format({'GDP': "{:.1f}亿"}))

八年Pandas使用经验中最深刻的体会是:掌握20%的核心功能就能解决80%的日常问题,但剩下20%的复杂场景往往需要深入理解数据结构和内存机制。建议新手先熟练使用本手册中的高频操作,再逐步探索更高级的 groupby.apply MultiIndex 等特性。当处理特别大的数据集时,可以考虑升级到Dask或PySpark,但Pandas仍然是快速探索和原型开发的最佳选择。

Logo

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

更多推荐