Skip to content

Pandas 数据处理

Data Processing with Pandas

Pandas 是 Python 数据分析的核心库,提供高效的数据操作和分析工具。


目录


核心概念

DataFrame 和 Series

Series

一维标记数组,类似带索引的列表。

import pandas as pd
s = pd.Series([1, 3, 5, 7], index=['a', 'b', 'c', 'd'])

DataFrame

二维标记数据结构,类似电子表格或 SQL 表。

df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie'],
    'age': [25, 30, 35],
    'city': ['Beijing', 'Shanghai', 'Guangzhou']
})

数据读取和导出

读取数据

# CSV 文件
df = pd.read_csv('data.csv')

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

# SQL 查询
df = pd.read_sql_query('SELECT * FROM table', connection)

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

导出数据

df.to_csv('output.csv', index=False, encoding='utf-8-sig')
df.to_excel('output.xlsx', index=False)
df.to_json('output.json', orient='records', force_ascii=False)

数据选择

列选择

# 单列
df['column_name']

# 多列
df[['col1', 'col2']]

行选择

# 位置索引
df.iloc[0:5]  # 前 5 行

# 标签索引
df.loc[df['age'] > 30]  # 条件筛选

混合选择

df.loc[df['age'] > 30, ['name', 'city']]

数据清洗

处理缺失值

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

# 删除缺失值
df.dropna()

# 填充缺失值
df.fillna(0)  # 填充 0
df.fillna(df.mean())  # 填充均值
df['col'].fillna(method='ffill')  # 前向填充

处理重复值

# 检测重复
df.duplicated().sum()

# 删除重复
df.drop_duplicates()

数据类型转换

df['column'] = df['column'].astype('int')
df['date'] = pd.to_datetime(df['date'])

数据转换

应用函数

# 列级别
df['new_col'] = df['old_col'].apply(lambda x: x * 2)

# 行级别
df.apply(lambda row: row['col1'] + row['col2'], axis=1)

映射替换

# 值映射
df['category'] = df['code'].map({'A': '优秀', 'B': '良好'})

# 值替换
df.replace({'old': 'new'})

分组聚合

基础分组

# 单列分组
df.groupby('category')['sales'].sum()

# 多列分组
df.groupby(['category', 'region'])['sales'].agg(['sum', 'mean', 'count'])

聚合函数

df.groupby('category').agg({
    'sales': 'sum',
    'profit': 'mean',
    'quantity': ['min', 'max']
})

数据合并

连接(Concat)

# 纵向连接
pd.concat([df1, df2], axis=0)

# 横向连接
pd.concat([df1, df2], axis=1)

合并(Merge)

# INNER JOIN
pd.merge(df1, df2, on='key', how='inner')

# LEFT JOIN
pd.merge(df1, df2, on='key', how='left')

# 多键合并
pd.merge(df1, df2, on=['key1', 'key2'])

实践应用

典型数据分析流程

1. 数据读取 → read_csv()
2. 数据概览 → head(), info(), describe()
3. 数据清洗 → 处理缺失值、重复值
4. 数据转换 → 类型转换、创建新列
5. 数据探索 → 分组聚合、相关性分析
6. 结果导出 → to_csv()

代码示例

示例 1: 完整的数据清洗流程

import pandas as pd

# 1. 读取数据
df = pd.read_csv('sales_data.csv')

# 2. 数据概览
print(f"数据形状:{df.shape}")
print(f"列名:{df.columns.tolist()}")
print(f"缺失值统计:\n{df.isnull().sum()}")

# 3. 处理缺失值
df['age'] = df['age'].fillna(df['age'].median())
df['city'] = df['city'].fillna('Unknown')

# 4. 删除重复值
df = df.drop_duplicates()

# 5. 数据类型转换
df['date'] = pd.to_datetime(df['date'])
df['category'] = df['category'].astype('category')

# 6. 创建新列
df['revenue'] = df['price'] * df['quantity']
df['profit_margin'] = df['profit'] / df['revenue']

# 7. 导出清洗后的数据
df.to_csv('cleaned_data.csv', index=False, encoding='utf-8-sig')

示例 2: 分组分析

# 按类别和地区分析销售
summary = df.groupby(['category', 'region']).agg({
    'revenue': ['sum', 'mean'],
    'quantity': 'sum',
    'order_id': 'count'
}).round(2)

# 重命名列
summary.columns = ['total_revenue', 'avg_revenue', 'total_quantity', 'order_count']

# 计算占比
summary['revenue_pct'] = summary['total_revenue'] / summary['total_revenue'].sum()

print(summary.sort_values('total_revenue', ascending=False))

示例 3: 时间序列分析

# 设置日期索引
df.set_index('date', inplace=True)

# 按月份重采样
monthly_sales = df['revenue'].resample('M').sum()

# 计算环比增长率
mom_growth = monthly_sales.pct_change()

# 计算移动平均
moving_avg = monthly_sales.rolling(window=3).mean()

# 可视化
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(12, 6))
monthly_sales.plot(ax=ax, label='月度销售')
moving_avg.plot(ax=ax, label='3 月移动平均')
ax.legend()
plt.show()

常见问题

Q1: copy() 警告怎么处理?

A: 使用 .copy() 明确创建副本:

# 正确做法
df_filtered = df[df['age'] > 30].copy()
df_filtered['new_col'] = value

Q2: 如何高效处理大文件?

A: - 分块读取:pd.read_csv('large.csv', chunksize=10000) - 指定数据类型:dtype={'col': 'category'} - 只读取需要的列:usecols=['col1', 'col2']

Q3: apply() 太慢怎么办?

A: - 优先使用向量化操作 - 使用内置的 str、dt 访问器 - 考虑使用 numba 加速


最佳实践

✅ 推荐做法

# 链式操作
result = (df
    .query('age > 30')
    .groupby('city')['sales']
    .sum()
    .reset_index()
    .sort_values('sales', ascending=False)
)

# 使用参数名
df.merge(df2, on='id', how='left')

❌ 避免做法

# 修改原始数据
df.dropna(inplace=True)  # 不推荐

# 循环处理
for i in range(len(df)):  # 慢!
    df.loc[i, 'new'] = df.loc[i, 'old'] * 2

参考资源

官方文档

书籍

  • 《利用 Python 进行数据分析》- Wes McKinney
  • 《Python for Data Analysis》

教程


下一步学习


最后更新: 2026-06-01