前言

在数据科学领域,Pandas 是 Python 生态中最核心的工具之一。无论是数据清洗、转换还是可视化准备,Pandas 都提供了高效且直观的 API。本文将通过实际案例,系统地讲解 Pandas 的常用操作和进阶技巧。

数据分析

环境搭建

安装

1
2
3
4
5
6
# 安装 Pandas
pip install pandas

# 推荐使用 Anaconda(包含 Pandas 及众多数据科学包)
# 或安装核心三件套
pip install pandas numpy matplotlib

导入和数据创建

1
2
3
4
5
6
7
8
9
10
11
12
13
import pandas as pd
import numpy as np

# 从字典创建 DataFrame
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'],
'age': [25, 30, 35, 28, 32],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shenzhen', 'Beijing'],
'salary': [15000, 22000, 18000, 25000, 19000],
'department': ['Engineering', 'Marketing', 'Engineering', 'Sales', 'Marketing']
})

print(df.head())

Series 与 DataFrame

数据结构 维度 类比
Series 1 维 Excel 中的一列
DataFrame 2 维 Excel 中的一张表
Panel 3 维 已弃用

数据读取与写入

文件格式支持

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# CSV 文件
df = pd.read_csv('data.csv', encoding='utf-8')

# Excel 文件
df = pd.read_excel('data.xlsx', sheet_name='Sheet1')

# JSON 文件
df = pd.read_json('data.json')

# SQL 数据库
from sqlalchemy import create_engine
engine = create_engine('sqlite:///database.db')
df = pd.read_sql('SELECT * FROM users', engine)

# 写入文件
df.to_csv('output.csv', index=False)
df.to_excel('output.xlsx', sheet_name='Results')
df.to_json('output.json', orient='records')

读取大数据集的技巧

1
2
3
4
5
6
7
8
9
10
11
12
# 分块读取大文件
chunk_size = 10000
chunks = []
for chunk in pd.read_csv('large_file.csv', chunksize=chunk_size):
# 对每个块进行处理
filtered = chunk[chunk['value'] > 0]
chunks.append(filtered)

df_large = pd.concat(chunks, ignore_index=True)

# 只读取需要的列
df = pd.read_csv('data.csv', usecols=['name', 'salary', 'city'])

数据探索

基本信息查看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 查看前几行
df.head(10)

# 数据概览
df.info()

# 统计描述
df.describe()

# 形状
df.shape # (1000, 8)

# 列名
df.columns.tolist()

# 数据类型
df.dtypes

# 唯一值
df['city'].unique()
df['city'].value_counts()

缺失值检测

1
2
3
4
5
6
7
8
9
# 检测缺失值
df.isnull().sum()

# 缺失值比例
(df.isnull().sum() / len(df)) * 100

# 可视化缺失值
import missingno as msno
msno.matrix(df)

数据选择与过滤

基本选择

1
2
3
4
5
6
7
8
9
10
11
12
13
# 选择列
df['name'] # 单列,返回 Series
df[['name', 'age']] # 多列,返回 DataFrame

# loc:基于标签
df.loc[0] # 第一行
df.loc[0:5, 'name':'age'] # 按标签切片
df.loc[df['age'] > 30] # 条件筛选

# iloc:基于位置
df.iloc[0] # 第一行
df.iloc[:5, :3] # 前 5 行,前 3 列
df.iloc[0, 0] # 单个值

高级过滤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 多条件过滤
filtered = df[
(df['age'] >= 25) &
(df['age'] <= 35) &
(df['city'].isin(['Beijing', 'Shanghai']))
]

# 字符串过滤
df[df['name'].str.contains('A')] # 包含 A
df[df['name'].str.startswith('B')] # 以 B 开头
df[df['name'].str.len() > 4] # 名称长度大于 4

# query 方法(推荐)
result = df.query('age > 25 and salary >= 20000 and city == "Shanghai"')

数据清洗

处理缺失值

1
2
3
4
5
6
7
8
9
10
11
# 删除包含缺失值的行
df_cleaned = df.dropna()

# 删除包含缺失值的列
df_cleaned = df.dropna(axis=1)

# 填充缺失值
df['age'].fillna(df['age'].mean(), inplace=True) # 均值填充
df['city'].fillna('Unknown', inplace=True) # 固定值填充
df['salary'].fillna(method='ffill', inplace=True) # 前向填充
df['salary'].fillna(method='bfill', inplace=True) # 后向填充

处理重复值

1
2
3
4
5
6
7
8
# 检测重复行
df.duplicated().sum()

# 删除重复行
df.drop_duplicates(inplace=True)

# 按特定列去重
df.drop_duplicates(subset=['name', 'email'], keep='first', inplace=True)

数据类型转换

1
2
3
4
5
6
7
# 类型转换
df['age'] = df['age'].astype(int)
df['date'] = pd.to_datetime(df['date'])
df['price'] = pd.to_numeric(df['price'], errors='coerce')

# 分类类型(节省内存)
df['city'] = df['city'].astype('category')

数据变换

apply 函数

1
2
3
4
5
6
7
8
9
10
11
12
13
# 对单列应用函数
df['salary_level'] = df['salary'].apply(
lambda x: 'High' if x >= 20000 else 'Low'
)

# 对多列应用函数
def calculate_bonus(row):
if row['department'] == 'Sales':
return row['salary'] * 0.2
else:
return row['salary'] * 0.1

df['bonus'] = df.apply(calculate_bonus, axis=1)

创建新列

1
2
3
4
5
6
7
8
9
10
11
12
13
# 条件创建
df['age_group'] = pd.cut(
df['age'],
bins=[0, 25, 35, 45, 100],
labels=['Young', 'Mid', 'Senior', 'Veteran']
)

# 编码转换
df['dept_code'] = df['department'].map({
'Engineering': 'ENG',
'Marketing': 'MKT',
'Sales': 'SLS'
})

数据聚合

GroupBy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 基础聚合
dept_stats = df.groupby('department').agg({
'salary': ['mean', 'median', 'max', 'min', 'count'],
'age': 'mean'
})

# 自定义聚合
def salary_range(x):
return x.max() - x.min()

city_stats = df.groupby('city').agg(
total_employees=('name', 'count'),
avg_salary=('salary', 'mean'),
salary_spread=('salary', salary_range)
).reset_index()

print(city_stats)

透视表

1
2
3
4
5
6
7
8
9
# 创建透视表
pivot = pd.pivot_table(
df,
values='salary',
index='department',
columns='age_group',
aggfunc='mean',
fill_value=0
)

窗口函数

1
2
3
4
5
6
7
8
9
10
# 滚动平均
df['salary_ma_3'] = df.groupby('department')['salary'].transform(
lambda x: x.rolling(window=3, min_periods=1).mean()
)

# 累计和
df['cumulative_salary'] = df.groupby('department')['salary'].cumsum()

# 排名
df['rank'] = df.groupby('department')['salary'].rank(ascending=False)

数据合并

各种 Join

1
2
3
4
5
6
7
8
9
10
11
# 内连接
merged = pd.merge(df1, df2, on='user_id', how='inner')

# 左连接
merged = pd.merge(df1, df2, on='user_id', how='left')

# 外连接
merged = pd.merge(df1, df2, on='user_id', how='outer')

# 纵向拼接
combined = pd.concat([df_2024, df_2025], ignore_index=True)

性能优化

数据类型优化

1
2
3
4
5
6
7
8
9
10
11
# 查看内存占用
df.memory_usage(deep=True)

# 优化整数类型
df['age'] = pd.to_numeric(df['age'], downcast='integer')

# 优化浮点数类型
df['salary'] = pd.to_numeric(df['salary'], downcast='float')

# 使用分类类型
df['city'] = df['city'].astype('category')

向量化操作

1
2
3
4
5
6
# ❌ 慢:逐行迭代
for i in range(len(df)):
df.loc[i, 'bonus'] = df.loc[i, 'salary'] * 0.1

# ✅ 快:向量化操作
df['bonus'] = df['salary'] * 0.1

实战案例:销售数据分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 完整的分析流程
import pandas as pd
import matplotlib.pyplot as plt

# 1. 读取数据
sales = pd.read_csv('sales_2024.csv', parse_dates=['date'])

# 2. 数据清洗
sales.dropna(subset=['amount', 'product'], inplace=True)
sales['month'] = sales['date'].dt.month

# 3. 月度汇总
monthly = sales.groupby('month').agg(
total_revenue=('amount', 'sum'),
order_count=('order_id', 'nunique'),
avg_order_value=('amount', 'mean')
).reset_index()

# 4. Top 产品
top_products = sales.groupby('product')['amount'].sum().nlargest(10)

# 5. 输出结果
print("=== 月度销售概况 ===")
print(monthly)
print(f"\n=== Top 10 产品 ===")
print(top_products)

总结

Pandas 是数据分析的瑞士军刀。掌握本文介绍的核心操作(数据读取、清洗、变换、聚合、合并),足以应对日常 90% 的数据分析需求。建议在实际项目中多加练习,尽快熟悉这些 API。