Pandas数据分析 - 第四章:数据读取与保存

第四章:数据读取与保存

📋 章节概述

本章讲解 Pandas 的数据读写功能,涵盖 CSV、Excel、JSON、SQL 等常见数据格式。通过本章学习,你将掌握实际工作中最常用的数据导入导出技能。

🎯 学习目标

  1. 掌握 CSV 文件的读写操作
  2. 掌握 Excel 文件的读写操作
  3. 掌握 JSON 数据的读写操作
  4. 了解 SQL 数据库的读写操作
  5. 学会处理不同编码和分隔符
  6. 掌握大数据文件的分块读取

📊 知识结构图

数据读写
CSV
Excel
JSON
SQL
其他格式
read_csv
to_csv
编码处理
分块读取
read_excel
to_excel
多工作表
ExcelWriter
read_json
to_json
orient参数
嵌套JSON
read_sql
to_sql
SQLAlchemy
SQLite示例
Parquet
HDF5
Pickle
HTML

python 复制代码
import pandas as pd
import numpy as np
import json
import os

# 设置显示选项
pd.set_option('display.max_columns', None)
pd.set_option('display.width', None)

# 创建工作目录
data_dir = "data"
os.makedirs(data_dir, exist_ok=True)

4.1 CSV 文件读写详解

CSV(Comma-Separated Values)是最常见的数据交换格式,几乎所有数据处理软件都支持 CSV 格式。

CSV 读写流程

read_csv
to_csv
CSV文件
DataFrame

常用参数

参数 说明 示例
sep 分隔符 sep=';'
encoding 编码格式 encoding='utf-8'
header 指定行作为列名 header=0
index_col 指定某列为索引 index_col='id'
usecols 只读取指定列 usecols=['A','B']
nrows 只读取前n行 nrows=100
skiprows 跳过指定行 skiprows=2

示例1:创建示例数据并保存为 CSV

python 复制代码
# 创建销售订单数据
orders_data = pd.DataFrame({
    "订单号": ["ORD2026001", "ORD2026002", "ORD2026003", "ORD2026004", "ORD2026005",
               "ORD2026006", "ORD2026007", "ORD2026008", "ORD2026009", "ORD2026010"],
    "客户姓名": ["张伟", "李娜", "王强", "刘洋", "陈静", "赵敏", "周杰", "吴刚", "郑华", "孙丽"],
    "产品名称": ["笔记本电脑", "无线鼠标", "机械键盘", "显示器", "耳机",
                 "平板电脑", "U盘", "移动硬盘", "摄像头", "音箱"],
    "类别": ["电子产品", "配件", "配件", "电子产品", "配件",
             "电子产品", "存储", "存储", "配件", "配件"],
    "数量": [1, 2, 1, 2, 1, 1, 3, 1, 2, 1],
    "单价": [5999, 99, 299, 1299, 199, 3499, 89, 459, 299, 159],
    "订单日期": pd.to_datetime(["2026-01-15", "2026-01-16", "2026-01-18", "2026-01-20", "2026-01-22",
                               "2026-02-01", "2026-02-05", "2026-02-10", "2026-02-15", "2026-02-20"]),
    "地区": ["北京", "上海", "广州", "深圳", "北京", "上海", "广州", "深圳", "北京", "上海"]
})

# 计算订单金额
orders_data["订单金额"] = orders_data["数量"] * orders_data["单价"]

print("销售订单数据预览:")
orders_data.head()
复制代码
销售订单数据预览:

| | 订单号 | 客户姓名 | 产品名称 | 类别 | 数量 | 单价 | 订单日期 | 地区 | 订单金额 |
| 0 | ORD2026001 | 张伟 | 笔记本电脑 | 电子产品 | 1 | 5999 | 2026-01-15 | 北京 | 5999 |
| 1 | ORD2026002 | 李娜 | 无线鼠标 | 配件 | 2 | 99 | 2026-01-16 | 上海 | 198 |
| 2 | ORD2026003 | 王强 | 机械键盘 | 配件 | 1 | 299 | 2026-01-18 | 广州 | 299 |
| 3 | ORD2026004 | 刘洋 | 显示器 | 电子产品 | 2 | 1299 | 2026-01-20 | 深圳 | 2598 |

4 ORD2026005 陈静 耳机 配件 1 199 2026-01-22 北京 199
python 复制代码
# 保存为 CSV 文件
csv_path = f"{data_dir}/orders.csv"
orders_data.to_csv(csv_path, index=False, encoding='utf-8-sig')  # utf-8-sig 兼容 Excel
print(f"数据已保存到: {csv_path}")
print(f"文件大小: {os.path.getsize(csv_path)} bytes")
复制代码
数据已保存到: data/orders.csv
文件大小: 763 bytes

示例2:读取 CSV 文件

python 复制代码
# 基本读取
print("基本读取:")
df_csv = pd.read_csv(csv_path)
df_csv.head(3)
复制代码
基本读取:

| | 订单号 | 客户姓名 | 产品名称 | 类别 | 数量 | 单价 | 订单日期 | 地区 | 订单金额 |
| 0 | ORD2026001 | 张伟 | 笔记本电脑 | 电子产品 | 1 | 5999 | 2026-01-15 | 北京 | 5999 |
| 1 | ORD2026002 | 李娜 | 无线鼠标 | 配件 | 2 | 99 | 2026-01-16 | 上海 | 198 |

2 ORD2026003 王强 机械键盘 配件 1 299 2026-01-18 广州 299
python 复制代码
# 指定编码读取(处理中文)
print("指定编码读取:")
df_csv_utf8 = pd.read_csv(csv_path, encoding='utf-8-sig')
print(f"成功读取 {len(df_csv_utf8)} 行数据")
复制代码
指定编码读取:
成功读取 10 行数据
python 复制代码
# 指定某列为索引
print("指定某列为索引:")
df_indexed = pd.read_csv(csv_path, index_col='订单号')
df_indexed.head(3)
复制代码
指定某列为索引:

| | 客户姓名 | 产品名称 | 类别 | 数量 | 单价 | 订单日期 | 地区 | 订单金额 |
| 订单号 | | | | | | | | |
| ORD2026001 | 张伟 | 笔记本电脑 | 电子产品 | 1 | 5999 | 2026-01-15 | 北京 | 5999 |
| ORD2026002 | 李娜 | 无线鼠标 | 配件 | 2 | 99 | 2026-01-16 | 上海 | 198 |

ORD2026003 王强 机械键盘 配件 1 299 2026-01-18 广州 299
python 复制代码
# 只读取指定列
print("只读取指定列:")
df_subset = pd.read_csv(csv_path, usecols=['客户姓名', '产品名称', '订单金额'])
df_subset.head()
复制代码
只读取指定列:

| | 客户姓名 | 产品名称 | 订单金额 |
| 0 | 张伟 | 笔记本电脑 | 5999 |
| 1 | 李娜 | 无线鼠标 | 198 |
| 2 | 王强 | 机械键盘 | 299 |
| 3 | 刘洋 | 显示器 | 2598 |

4 陈静 耳机 199
python 复制代码
# 读取前 N 行
print("读取前 N 行:")
df_partial = pd.read_csv(csv_path, nrows=5)
print(f"只读取前 5 行: {len(df_partial)} 行")
df_partial
复制代码
读取前 N 行:
只读取前 5 行: 5 行

| | 订单号 | 客户姓名 | 产品名称 | 类别 | 数量 | 单价 | 订单日期 | 地区 | 订单金额 |
| 0 | ORD2026001 | 张伟 | 笔记本电脑 | 电子产品 | 1 | 5999 | 2026-01-15 | 北京 | 5999 |
| 1 | ORD2026002 | 李娜 | 无线鼠标 | 配件 | 2 | 99 | 2026-01-16 | 上海 | 198 |
| 2 | ORD2026003 | 王强 | 机械键盘 | 配件 | 1 | 299 | 2026-01-18 | 广州 | 299 |
| 3 | ORD2026004 | 刘洋 | 显示器 | 电子产品 | 2 | 1299 | 2026-01-20 | 深圳 | 2598 |

4 ORD2026005 陈静 耳机 配件 1 199 2026-01-22 北京 199

示例3:处理不同分隔符

python 复制代码
# 创建分号分隔的文件
semicolon_path = f"{data_dir}/orders_semicolon.csv"
orders_data.to_csv(semicolon_path, index=False, sep=';', encoding='utf-8-sig')

# 读取分号分隔的 CSV
print("读取分号分隔的 CSV:")
df_semicolon = pd.read_csv(semicolon_path, sep=';')
df_semicolon.head(3)
复制代码
读取分号分隔的 CSV:

| | 订单号 | 客户姓名 | 产品名称 | 类别 | 数量 | 单价 | 订单日期 | 地区 | 订单金额 |
| 0 | ORD2026001 | 张伟 | 笔记本电脑 | 电子产品 | 1 | 5999 | 2026-01-15 | 北京 | 5999 |
| 1 | ORD2026002 | 李娜 | 无线鼠标 | 配件 | 2 | 99 | 2026-01-16 | 上海 | 198 |

2 ORD2026003 王强 机械键盘 配件 1 299 2026-01-18 广州 299

示例4:大文件分块读取

当处理大文件时,可以使用 chunksize 参数分块读取,避免内存溢出。

python 复制代码
# 创建一个大文件用于演示
large_data = pd.concat([orders_data] * 100, ignore_index=True)  # 1000行
large_path = f"{data_dir}/large_orders.csv"
large_data.to_csv(large_path, index=False, encoding='utf-8-sig')

# 分块读取大文件
print("分块读取大文件:")
chunk_size = 200
chunks = []
for chunk in pd.read_csv(large_path, chunksize=chunk_size):
    chunks.append(chunk)
    print(f"  读取 chunk: {len(chunk)} 行")

df_large = pd.concat(chunks, ignore_index=True)
print(f"\n总计读取: {len(df_large)} 行")
复制代码
分块读取大文件:
  读取 chunk: 200 行
  读取 chunk: 200 行
  读取 chunk: 200 行
  读取 chunk: 200 行
  读取 chunk: 200 行

总计读取: 1000 行

4.2 Excel 文件读写详解

Excel 是办公场景中最常用的数据格式,Pandas 支持读写 Excel 文件。

依赖库

用途
openpyxl 读写 .xlsx 格式(Excel 2007+)
xlrd 读取 .xls 格式(旧版 Excel)
xlwt 写入 .xls 格式(旧版 Excel)

安装:pip install openpyxl xlrd xlwt

Excel 读写流程

read_excel
to_excel
ExcelWriter
Excel文件
DataFrame
多工作表

示例5:保存到 Excel

python 复制代码
excel_path = f"{data_dir}/sales_report.xlsx"

# 保存到 Excel(单工作表)
print("保存到 Excel(单工作表):")
orders_data.to_excel(excel_path, index=False, sheet_name='订单数据')
print(f"已保存到: {excel_path}")
复制代码
保存到 Excel(单工作表):
已保存到: data/sales_report.xlsx
python 复制代码
# 保存多个工作表
print("保存多个工作表:")
with pd.ExcelWriter(excel_path, engine='openpyxl') as writer:
    orders_data.to_excel(writer, sheet_name='订单数据', index=False)
    
    # 创建汇总数据
    summary = orders_data.groupby('类别').agg({
        '订单金额': 'sum',
        '数量': 'sum'
    }).reset_index()
    summary.to_excel(writer, sheet_name='类别汇总', index=False)
    
    # 创建地区汇总
    region_summary = orders_data.groupby('地区')['订单金额'].sum().reset_index()
    region_summary.to_excel(writer, sheet_name='地区汇总', index=False)

print(f"已保存多个工作表到: {excel_path}")
复制代码
保存多个工作表:
已保存多个工作表到: data/sales_report.xlsx

示例6:读取 Excel 文件

python 复制代码
# 读取指定工作表
print("读取指定工作表:")
df_excel = pd.read_excel(excel_path, sheet_name='订单数据')
df_excel.head(3)
复制代码
读取指定工作表:

| | 订单号 | 客户姓名 | 产品名称 | 类别 | 数量 | 单价 | 订单日期 | 地区 | 订单金额 |
| 0 | ORD2026001 | 张伟 | 笔记本电脑 | 电子产品 | 1 | 5999 | 2026-01-15 | 北京 | 5999 |
| 1 | ORD2026002 | 李娜 | 无线鼠标 | 配件 | 2 | 99 | 2026-01-16 | 上海 | 198 |

2 ORD2026003 王强 机械键盘 配件 1 299 2026-01-18 广州 299
python 复制代码
# 读取所有工作表
print("读取所有工作表:")
all_sheets = pd.read_excel(excel_path, sheet_name=None)  # 返回字典
print(f"工作表列表: {list(all_sheets.keys())}")
for sheet_name, df in all_sheets.items():
    print(f"  {sheet_name}: {len(df)} 行")
复制代码
读取所有工作表:
工作表列表: ['订单数据', '类别汇总', '地区汇总']
  订单数据: 10 行
  类别汇总: 3 行
  地区汇总: 4 行
python 复制代码
# 读取类别汇总
print("读取类别汇总:")
df_summary = pd.read_excel(excel_path, sheet_name='类别汇总')
df_summary
复制代码
读取类别汇总:

| | 类别 | 订单金额 | 数量 |
| 0 | 存储 | 726 | 4 |
| 1 | 电子产品 | 12096 | 4 |

2 配件 1453 7

4.3 JSON 数据读写详解

JSON(JavaScript Object Notation)是 Web 开发中最常用的数据格式,常用于 API 数据传输和配置文件。

orient 参数说明

格式 示例
records 记录列表 [{}, {}, ...]
index 索引为键 {'0': {}, '1': {}}
columns 列为键 {'col': {'0': val}}
values 纯值数组 [[], [], ...]

read_json
to_json
JSON文件
DataFrame
records
index
columns

示例7:保存为 JSON

python 复制代码
json_path = f"{data_dir}/orders.json"

# 保存为 JSON(records 格式)
print("保存为 JSON(records 格式):")
orders_data.to_json(json_path, orient='records', force_ascii=False, indent=2, date_format='iso')
print(f"已保存到: {json_path}")

# 显示 JSON 内容
with open(json_path, 'r', encoding='utf-8') as f:
    json_content = json.load(f)
print(f"JSON 记录数: {len(json_content)}")
print(f"第一条记录: {json_content[0]}")
复制代码
保存为 JSON(records 格式):
已保存到: data/orders.json
JSON 记录数: 10
第一条记录: {'订单号': 'ORD2026001', '客户姓名': '张伟', '产品名称': '笔记本电脑', '类别': '电子产品', '数量': 1, '单价': 5999, '订单日期': '2026-01-15T00:00:00.000', '地区': '北京', '订单金额': 5999}
python 复制代码
# 不同 orient 格式对比
print("不同 orient 格式对比:")
for orient in ['records', 'index', 'columns', 'values']:
    temp_path = f"{data_dir}/orders_{orient}.json"
    orders_data.head(2).to_json(temp_path, orient=orient, force_ascii=False, date_format='iso')
    with open(temp_path, 'r', encoding='utf-8') as f:
        content = json.load(f)
    print(f"\n  orient='{orient}':")
    print(f"    {json.dumps(content, ensure_ascii=False)[:100]}...")
复制代码
不同 orient 格式对比:

  orient='records':
    [{"订单号": "ORD2026001", "客户姓名": "张伟", "产品名称": "笔记本电脑", "类别": "电子产品", "数量": 1, "单价": 5999, "订单日期": "20...

  orient='index':
    {"0": {"订单号": "ORD2026001", "客户姓名": "张伟", "产品名称": "笔记本电脑", "类别": "电子产品", "数量": 1, "单价": 5999, "订单日期"...

  orient='columns':
    {"订单号": {"0": "ORD2026001", "1": "ORD2026002"}, "客户姓名": {"0": "张伟", "1": "李娜"}, "产品名称": {"0": "笔记本电脑...

  orient='values':
    [["ORD2026001", "张伟", "笔记本电脑", "电子产品", 1, 5999, "2026-01-15T00:00:00.000", "北京", 5999], ["ORD2026002...

示例8:读取 JSON

python 复制代码
# 读取 JSON 文件
print("读取 JSON 文件:")
df_json = pd.read_json(json_path, orient='records')
df_json.head(3)
复制代码
读取 JSON 文件:

| | 订单号 | 客户姓名 | 产品名称 | 类别 | 数量 | 单价 | 订单日期 | 地区 | 订单金额 |
| 0 | ORD2026001 | 张伟 | 笔记本电脑 | 电子产品 | 1 | 5999 | 2026-01-15T00:00:00.000 | 北京 | 5999 |
| 1 | ORD2026002 | 李娜 | 无线鼠标 | 配件 | 2 | 99 | 2026-01-16T00:00:00.000 | 上海 | 198 |

2 ORD2026003 王强 机械键盘 配件 1 299 2026-01-18T00:00:00.000 广州 299
python 复制代码
# 创建嵌套 JSON 示例
nested_json = {
    "company": "科技有限公司",
    "year": 2026,
    "employees": [
        {"name": "张伟", "department": "技术部", "salary": 12000},
        {"name": "李娜", "department": "销售部", "salary": 15000},
        {"name": "王强", "department": "技术部", "salary": 18000}
    ]
}

nested_path = f"{data_dir}/company.json"
with open(nested_path, 'w', encoding='utf-8') as f:
    json.dump(nested_json, f, ensure_ascii=False, indent=2)

# 读取嵌套 JSON
print("读取嵌套 JSON:")
with open(nested_path, 'r', encoding='utf-8') as f:
    nested_data = json.load(f)
df_employees = pd.DataFrame(nested_data['employees'])
print(f"  公司: {nested_data['company']}")
print(f"  年份: {nested_data['year']}")
print("  员工数据:")
df_employees
复制代码
读取嵌套 JSON:
  公司: 科技有限公司
  年份: 2026
  员工数据:

| | name | department | salary |
| 0 | 张伟 | 技术部 | 12000 |
| 1 | 李娜 | 销售部 | 15000 |

2 王强 技术部 18000

4.4 SQL 数据库读写

Pandas 支持通过 SQLAlchemy 连接各种数据库(MySQL、PostgreSQL、SQLite 等)。

依赖库

用途
sqlalchemy 数据库连接引擎
pymysql MySQL 驱动
psycopg2 PostgreSQL 驱动

连接字符串示例

python 复制代码
# SQLite
sqlite:///:memory:          # 内存数据库
sqlite:///path/to/db.sqlite # 文件数据库

# MySQL
mysql+pymysql://user:password@localhost/dbname

# PostgreSQL
postgresql://user:password@localhost/dbname

to_sql
read_sql
DataFrame
SQL数据库
SQLAlchemy

示例9:SQLite 内存数据库演示

python 复制代码
try:
    from sqlalchemy import create_engine
    
    # 创建内存数据库
    engine = create_engine('sqlite:///:memory:')
    
    # 写入数据
    orders_data.to_sql('orders', engine, index=False, if_exists='replace')
    print("数据已写入 SQLite 内存数据库")
    
    # 读取全部数据
    df_sqlite = pd.read_sql('SELECT * FROM orders', engine)
    print(f"读取到 {len(df_sqlite)} 行数据")
    
    # 条件查询
    df_high_value = pd.read_sql(
        'SELECT * FROM orders WHERE "订单金额" > 1000 ORDER BY "订单金额" DESC',
        engine
    )
    print(f"高价值订单(>1000): {len(df_high_value)} 条")
    print("前3条:")
    df_high_value[['订单号', '产品名称', '订单金额']].head(3)
    
except ImportError:
    print("请安装 sqlalchemy: pip install sqlalchemy")
复制代码
数据已写入 SQLite 内存数据库
读取到 10 行数据
高价值订单(>1000): 3 条
前3条:

示例10:SQLite 本地数据库文件

python 复制代码
try:
    from sqlalchemy import create_engine
    
    # 创建本地 SQLite 数据库文件
    sqlite_path = f"{data_dir}/sales_database.sqlite"
    engine_file = create_engine(f'sqlite:///{sqlite_path}')
    
    # 写入多个表
    orders_data.to_sql('orders', engine_file, index=False, if_exists='replace')
    
    # 创建汇总表
    category_summary = orders_data.groupby('类别').agg({
        '订单金额': 'sum',
        '数量': 'sum'
    }).reset_index()
    category_summary.to_sql('category_summary', engine_file, index=False, if_exists='replace')
    
    print(f"数据库文件已创建: {sqlite_path}")
    print(f"文件大小: {os.path.getsize(sqlite_path)} bytes")
    
    # 从本地数据库读取
    df_from_db = pd.read_sql('SELECT * FROM orders', engine_file)
    print(f"\n从数据库读取 orders 表: {len(df_from_db)} 行")
    
    # 查询汇总表
    df_summary_db = pd.read_sql('SELECT * FROM category_summary', engine_file)
    print("category_summary 表内容:")
    print(df_summary_db)
    
except ImportError:
    print("请安装 sqlalchemy: pip install sqlalchemy")
复制代码
数据库文件已创建: data/sales_database.sqlite
文件大小: 12288 bytes

从数据库读取 orders 表: 10 行
category_summary 表内容:
     类别   订单金额  数量
0    存储    726   4
1  电子产品  12096   4
2    配件   1453   7
python 复制代码
# SQL 复杂查询示例
try:
    print("\nSQL 复杂查询 - 按地区统计订单金额:")
    region_query = '''
        SELECT 地区, COUNT(*) as 订单数, SUM(订单金额) as 总金额, AVG(订单金额) as 平均金额
        FROM orders
        GROUP BY 地区
        ORDER BY 总金额 DESC
    '''
    df_region_stats = pd.read_sql(region_query, engine_file)
    df_region_stats
    
except NameError:
    print("请先运行上面的代码块创建数据库")
复制代码
SQL 复杂查询 - 按地区统计订单金额:

4.5 其他格式简介

格式 读取 写入 适用场景
Parquet read_parquet() to_parquet() 大数据处理
HDF5 read_hdf() to_hdf() 科学数据
Pickle read_pickle() to_pickle() 临时存储
HTML read_html() to_html() 网页表格
Clipboard read_clipboard() to_clipboard() 剪贴板

4.6 实战案例:销售数据整合

场景描述

你需要整合来自不同来源的销售数据:

  1. 从 CSV 文件导入线上订单数据
  2. 从 Excel 文件导入线下门店数据
  3. 从 JSON API 获取合作伙伴数据
  4. 合并所有数据并生成汇总报表
  5. 导出为多种格式供不同部门使用

CSV线上数据
数据合并
Excel线下数据
JSON合作数据
数据分析
Excel报表
CSV报表
JSON报表

步骤1:准备多来源数据

python 复制代码
# 线上订单数据(CSV 格式)
online_data = pd.DataFrame({
    "订单ID": [f"ON{str(i).zfill(5)}" for i in range(1, 6)],
    "客户": ["客户A", "客户B", "客户C", "客户D", "客户E"],
    "产品": ["产品X", "产品Y", "产品Z", "产品X", "产品Y"],
    "金额": [1500, 2300, 1800, 2100, 1200],
    "渠道": ["线上", "线上", "线上", "线上", "线上"],
    "日期": pd.date_range("2026-01-01", periods=5)
})

# 线下门店数据(Excel 格式)
offline_data = pd.DataFrame({
    "订单ID": [f"OFF{str(i).zfill(5)}" for i in range(1, 6)],
    "客户": ["客户F", "客户G", "客户H", "客户I", "客户J"],
    "产品": ["产品Y", "产品Z", "产品X", "产品Z", "产品Y"],
    "金额": [2800, 1500, 3200, 1900, 2600],
    "渠道": ["线下", "线下", "线下", "线下", "线下"],
    "日期": pd.date_range("2026-01-01", periods=5)
})

# 合作伙伴数据(JSON 格式)
partner_json = {
    "orders": [
        {"订单ID": "PT00001", "客户": "客户K", "产品": "产品X", "金额": 3500, "渠道": "合作", "日期": "2026-01-03"},
        {"订单ID": "PT00002", "客户": "客户L", "产品": "产品Y", "金额": 4200, "渠道": "合作", "日期": "2026-01-05"},
        {"订单ID": "PT00003", "客户": "客户M", "产品": "产品Z", "金额": 2800, "渠道": "合作", "日期": "2026-01-07"}
    ]
}
partner_data = pd.DataFrame(partner_json["orders"])
partner_data["日期"] = pd.to_datetime(partner_data["日期"], format="%Y-%m-%d")

print("线上订单数据:")
print(online_data)
print("\n线下门店数据:")
print(offline_data)
print("\n合作伙伴数据:")
print(partner_data)
复制代码
线上订单数据:
      订单ID   客户   产品    金额  渠道         日期
0  ON00001  客户A  产品X  1500  线上 2026-01-01
1  ON00002  客户B  产品Y  2300  线上 2026-01-02
2  ON00003  客户C  产品Z  1800  线上 2026-01-03
3  ON00004  客户D  产品X  2100  线上 2026-01-04
4  ON00005  客户E  产品Y  1200  线上 2026-01-05

线下门店数据:
       订单ID   客户   产品    金额  渠道         日期
0  OFF00001  客户F  产品Y  2800  线下 2026-01-01
1  OFF00002  客户G  产品Z  1500  线下 2026-01-02
2  OFF00003  客户H  产品X  3200  线下 2026-01-03
3  OFF00004  客户I  产品Z  1900  线下 2026-01-04
4  OFF00005  客户J  产品Y  2600  线下 2026-01-05

合作伙伴数据:
      订单ID   客户   产品    金额  渠道         日期
0  PT00001  客户K  产品X  3500  合作 2026-01-03
1  PT00002  客户L  产品Y  4200  合作 2026-01-05
2  PT00003  客户M  产品Z  2800  合作 2026-01-07

步骤2:保存各来源数据到不同格式

python 复制代码
online_path = f"{data_dir}/online_orders.csv"
offline_path = f"{data_dir}/offline_orders.xlsx"
partner_path = f"{data_dir}/partner_orders.json"

online_data.to_csv(online_path, index=False, encoding='utf-8-sig')
offline_data.to_excel(offline_path, index=False, sheet_name='线下订单')
partner_data.to_json(partner_path, orient='records', force_ascii=False, indent=2, date_format='iso')

print(f"线上数据已保存: {online_path}")
print(f"线下数据已保存: {offline_path}")
print(f"合作数据已保存: {partner_path}")
复制代码
线上数据已保存: data/online_orders.csv
线下数据已保存: data/offline_orders.xlsx
合作数据已保存: data/partner_orders.json

步骤3:读取并合并所有数据

python 复制代码
df_online = pd.read_csv(online_path)
df_offline = pd.read_excel(offline_path)
df_partner = pd.read_json(partner_path, orient='records')
df_partner["日期"] = pd.to_datetime(df_partner["日期"])

# 合并所有数据
all_orders = pd.concat([df_online, df_offline, df_partner], ignore_index=True)

print(f"线上订单: {len(df_online)} 条")
print(f"线下订单: {len(df_offline)} 条")
print(f"合作订单: {len(df_partner)} 条")
print(f"合并后总计: {len(all_orders)} 条")
print("\n合并后数据预览:")
all_orders
复制代码
线上订单: 5 条
线下订单: 5 条
合作订单: 3 条
合并后总计: 13 条

合并后数据预览:

| | 订单ID | 客户 | 产品 | 金额 | 渠道 | 日期 |
| 0 | ON00001 | 客户A | 产品X | 1500 | 线上 | 2026-01-01 |
| 1 | ON00002 | 客户B | 产品Y | 2300 | 线上 | 2026-01-02 |
| 2 | ON00003 | 客户C | 产品Z | 1800 | 线上 | 2026-01-03 |
| 3 | ON00004 | 客户D | 产品X | 2100 | 线上 | 2026-01-04 |
| 4 | ON00005 | 客户E | 产品Y | 1200 | 线上 | 2026-01-05 |
| 5 | OFF00001 | 客户F | 产品Y | 2800 | 线下 | 2026-01-01 00:00:00 |
| 6 | OFF00002 | 客户G | 产品Z | 1500 | 线下 | 2026-01-02 00:00:00 |
| 7 | OFF00003 | 客户H | 产品X | 3200 | 线下 | 2026-01-03 00:00:00 |
| 8 | OFF00004 | 客户I | 产品Z | 1900 | 线下 | 2026-01-04 00:00:00 |
| 9 | OFF00005 | 客户J | 产品Y | 2600 | 线下 | 2026-01-05 00:00:00 |
| 10 | PT00001 | 客户K | 产品X | 3500 | 合作 | 2026-01-03 00:00:00 |
| 11 | PT00002 | 客户L | 产品Y | 4200 | 合作 | 2026-01-05 00:00:00 |

12 PT00003 客户M 产品Z 2800 合作 2026-01-07 00:00:00

步骤4:数据分析

python 复制代码
print("按渠道统计:")
channel_stats = all_orders.groupby("渠道").agg({
    "金额": ["sum", "mean", "count"]
}).round(2)
channel_stats.columns = ["总金额", "平均金额", "订单数"]
channel_stats
复制代码
按渠道统计:

| | 总金额 | 平均金额 | 订单数 |
| 渠道 | | | |
| 合作 | 10500 | 3500.0 | 3 |
| 线上 | 8900 | 1780.0 | 5 |

线下 12000 2400.0 5
python 复制代码
print("按产品统计:")
product_stats = all_orders.groupby("产品")["金额"].sum().sort_values(ascending=False)
product_stats
复制代码
按产品统计:





产品
产品Y    13100
产品X    10300
产品Z     8000
Name: 金额, dtype: int64

步骤5:导出汇总报表(多格式)

python 复制代码
report_path = f"{data_dir}/sales_report_final"

# 导出为 Excel(多工作表)
excel_report_path = f"{report_path}.xlsx"
with pd.ExcelWriter(excel_report_path, engine='openpyxl') as writer:
    all_orders.to_excel(writer, sheet_name='全部订单', index=False)
    channel_stats.to_excel(writer, sheet_name='渠道统计')
    product_stats.to_excel(writer, sheet_name='产品统计')

print(f"Excel 报表: {excel_report_path}")

# 导出为 CSV
csv_report_path = f"{report_path}.csv"
all_orders.to_csv(csv_report_path, index=False, encoding='utf-8-sig')
print(f"CSV 报表: {csv_report_path}")

# 导出为 JSON
json_report_path = f"{report_path}.json"
all_orders.to_json(json_report_path, orient='records', force_ascii=False, indent=2, date_format='iso')
print(f"JSON 报表: {json_report_path}")
复制代码
Excel 报表: data/sales_report_final.xlsx
CSV 报表: data/sales_report_final.csv
JSON 报表: data/sales_report_final.json

本章小结

学习内容回顾

1. CSV 文件读写

  • read_csv(): 读取 CSV,支持多种参数
  • to_csv(): 保存为 CSV
  • 处理编码、分隔符、大文件分块读取

2. Excel 文件读写

  • read_excel(): 读取 Excel,支持多工作表
  • to_excel(): 保存为 Excel
  • ExcelWriter: 多工作表写入
  • 依赖: openpyxl, xlrd

3. JSON 数据读写

  • read_json(): 读取 JSON
  • to_json(): 保存为 JSON
  • orient 参数: records, index, columns, values

4. SQL 数据库读写

  • read_sql(): 执行 SQL 查询
  • to_sql(): 写入数据库表
  • SQLAlchemy: 数据库连接引擎

5. 其他格式

  • Parquet: 高效列式存储
  • HDF5: 层次化数据格式
  • Pickle: Python 对象序列化

6. 实战应用

  • 多来源数据整合
  • 数据格式转换
  • 报表生成与导出

下章预告

第五章:数据选择与过滤

将学习数据选择与过滤的核心技能,包括:

  • loc 基于标签的选择
  • iloc 基于位置的选择
  • 布尔索引条件筛选
  • query() 方法查询
  • isin()、between() 等便捷方法

课后练习

练习1:创建一个包含学生成绩的数据集,然后:

  • 保存为 CSV 文件(使用不同编码)
  • 保存为 Excel 文件(多工作表)
  • 保存为 JSON 文件(不同 orient)

练习2:从 CSV 文件读取数据,然后:

  • 只读取前 10 行
  • 只读取指定列
  • 跳过前 2 行

练习3:创建一个 SQLite 数据库,然后:

  • 将 DataFrame 写入数据库
  • 使用 SQL 查询筛选数据
  • 将查询结果读取为 DataFrame

练习4:整合多个数据文件:

  • 创建 3 个 CSV 文件(模拟不同月份数据)
  • 读取并合并所有数据
  • 按月份统计并导出报表
相关推荐
deepdata_cn3 小时前
数据分析之数据粒度(Granularity)
数据挖掘·数据分析·颗粒度
YangYang9YangYan3 小时前
2026年经管专业学习数据分析的指南
学习·数据挖掘·数据分析
551只玄猫3 小时前
【数学建模 matlab 实验报告9】数据的统计分析与描述
数学建模·matlab·数据分析·课程设计·实验报告
李昊哲小课3 小时前
Pandas数据分析 - 第七章:数据合并与连接
数据挖掘·数据分析·pandas
gushinghsjj4 小时前
元数据管理包含哪些?元数据管理如何支持数据分析?
数据库·oracle·数据分析
编程界一哥4 小时前
2026最新:原神PC启动提示缺失msvcp140.dll,安全修复工具哪家强?
数据挖掘
qyr67894 小时前
全球蜂窝分布式天线系统市场报告2026-2032
大数据·人工智能·数据分析·市场报告·蜂窝分布式天线系统
泰迪智能科技015 小时前
分享|大数据挖掘建模平台赋能企业智能决策与数字化转型
人工智能·数据挖掘
新知图书5 小时前
微软Power BI主要架构
数据分析·power bi·商务数据分析