数据读取与写入
数据分析的第一步通常是从各种数据源读取数据。Pandas 支持多种文件格式的读取和写入,包括 CSV、Excel、JSON、SQL 等。本章将详细介绍这些操作。
读取 CSV 文件
CSV(Comma-Separated Values)是最常见的数据文件格式。
基本读取
import pandas as pd
# 最简单的读取
df = pd.read_csv('data.csv')
# 查看数据
print(df.head())
print(df.shape)
常用参数
# 指定分隔符
df = pd.read_csv('data.txt', sep='\t') # 制表符分隔
df = pd.read_csv('data.csv', sep=';') # 分号分隔
# 指定编码
df = pd.read_csv('data.csv', encoding='utf-8') # UTF-8
df = pd.read_csv('data.csv', encoding='gbk') # 中文编码
# 指定列名
df = pd.read_csv('data.csv', header=0) # 第一行作为列名(默认)
df = pd.read_csv('data.csv', header=None) # 不使用列名
df = pd.read_csv('data.csv', names=['A', 'B', 'C']) # 指定列名
# 指定索引列
df = pd.read_csv('data.csv', index_col=0) # 第一列作为索引
df = pd.read_csv('data.csv', index_col='name') # 指定列作为索引
# 读取部分行
df = pd.read_csv('data.csv', nrows=100) # 只读取前100行
# 跳过行
df = pd.read_csv('data.csv', skiprows=2) # 跳过前2行
df = pd.read_csv('data.csv', skiprows=[1, 3, 5]) # 跳过指定行
处理缺失值
# 指定缺失值标记
df = pd.read_csv('data.csv', na_values=['NA', 'NULL', '-', ''])
# 读取时填充缺失值
df = pd.read_csv('data.csv', na_fill='N/A')
# 读取指定列
df = pd.read_csv('data.csv', usecols=['name', 'age', 'city'])
实践示例
# 创建示例 CSV 文件
sample_data = """name,age,city,salary
张三,25,北京,10000
李四,30,上海,15000
王五,35,,20000
赵六,28,深圳,12000
"""
# 保存为 CSV
with open('employees.csv', 'w', encoding='utf-8') as f:
f.write(sample_data)
# 读取 CSV
df = pd.read_csv('employees.csv')
print(df)
# name age city salary
# 0 张三 25 北京 10000
# 1 李四 30 上海 15000
# 2 王五 35 NaN 20000
# 3 赵六 28 深圳 12000
写入 CSV 文件
# 基本写入
df.to_csv('output.csv')
# 不保存索引
df.to_csv('output.csv', index=False)
# 指定分隔符
df.to_csv('output.txt', sep='\t')
# 指定编码
df.to_csv('output.csv', encoding='utf-8-sig') # UTF-8 with BOM(Excel 兼容)
# 只保存部分列
df.to_csv('output.csv', columns=['name', 'salary'])
# 缺失值处理
df.to_csv('output.csv', na_rep='N/A') # 将缺失值保存为 'N/A'
读取 Excel 文件
Excel 文件通常包含一个或多个工作表。
读取 Excel
# 安装 openpyxl(支持 .xlsx)
# pip install openpyxl
# 读取第一个工作表
df = pd.read_excel('data.xlsx')
# 读取指定工作表
df = pd.read_excel('data.xlsx', sheet_name='Sheet1')
df = pd.read_excel('data.xlsx', sheet_name=0) # 通过索引
# 读取所有工作表
all_sheets = pd.read_excel('data.xlsx', sheet_name=None)
# 返回字典:{工作表名: DataFrame}
# 读取时指定列名
df = pd.read_excel('data.xlsx', header=0) # 第一行作为列名
df = pd.read_excel('data.xlsx', header=None) # 无列名
# 指定跳过的行
df = pd.read_excel('data.xlsx', skiprows=2) # 跳过前2行
# 读取指定列
df = pd.read_excel('data.xlsx', usecols='A:C') # 读取 A-C 列
df = pd.read_excel('data.xlsx', usecols=[0, 2, 4]) # 读取 1,3,5 列
写入 Excel
# 写入单个工作表
df.to_excel('output.xlsx')
# 不保存索引
df.to_excel('output.xlsx', index=False)
# 指定工作表名称
df.to_excel('output.xlsx', sheet_name='员工信息')
# 写入多个工作表
with pd.ExcelWriter('output.xlsx') as writer:
df1.to_excel(writer, sheet_name='Sheet1')
df2.to_excel(writer, sheet_name='Sheet2')
# 写入时设置格式(需要 openpyxl)
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill
# 写入并设置列宽(需要 xlsxwriter)
df.to_excel('output.xlsx', engine='xlsxwriter')
实践示例
# 创建示例 Excel 文件
df_sample = pd.DataFrame({
'姓名': ['张三', '李四', '王五'],
'年龄': [25, 30, 35],
'部门': ['技术部', '市场部', '人事部']
})
# 保存为 Excel
df_sample.to_excel('sample.xlsx', index=False)
# 读取 Excel
df_read = pd.read_excel('sample.xlsx')
print(df_read)
读取 JSON 文件
JSON 是常见的数据交换格式。
读取 JSON
# 读取 JSON 文件
df = pd.read_json('data.json')
# 读取 JSON 字符串
json_str = '{"name": ["张三", "李四"], "age": [25, 30]}'
df = pd.read_json(json_str)
# 读取 JSON Lines 格式(每行一个 JSON 对象)
df = pd.read_json('data.jsonl', lines=True)
# 指定方向
# records: 每行一个对象 {column: value}
df = pd.read_json(json_str, orient='records')
# index: 索引为键 {index: {column: value}}
# columns: 列为主键 {columns: {column: [values]}}
# values: 二维数组
# split: {index: [], columns: [], data: []}
写入 JSON
# 基本写入
df.to_json('output.json')
# 指定格式
df.to_json('output.json', orient='records', force_ascii=False)
# 格式化输出
df.to_json('output.json', indent=2, force_ascii=False)
# JSON Lines 格式
df.to_json('output.jsonl', orient='records', lines=True)
读取 HTML
读取网页表格
# 读取网页中的表格
tables = pd.read_html('https://example.com/data.html')
# 读取第一个表格
df = tables[0]
# 读取所有表格,返回列表
all_tables = pd.read_html('https://example.com/data.html')
# 指定读取第几个表格
df = pd.read_html('https://example.com/data.html', match='关键词')[0]
写入 HTML
# 保存为 HTML
df.to_html('output.html')
# 不保存索引
df.to_html('output.html', index=False)
# 自定义样式
df.to_html('output.html',
classes='table table-striped',
border=0)
# 生成完整的 HTML 页面
html = df.to_html()
full_html = f"""
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Data</title>
<style>
table {{ border-collapse: collapse; }}
th, td {{ border: 1px solid black; padding: 8px; }}
</style>
</head>
<body>
{html}
</body>
</html>
"""
读取 SQL 数据库
使用 SQLAlchemy
# 安装
# pip install sqlalchemy pymysql
from sqlalchemy import create_engine
# 创建数据库连接
engine = create_engine('sqlite:///database.db') # SQLite
engine = create_engine('mysql+pymysql://user:pass@localhost/dbname') # MySQL
# 读取 SQL 查询结果
df = pd.read_sql('SELECT * FROM users', engine)
# 读取整个表
df = pd.read_sql_table('users', engine)
# 使用参数化查询
df = pd.read_sql('SELECT * FROM users WHERE age > ?', engine, params=[25])
写入 SQL
# 写入数据库
df.to_sql('new_table', engine, if_exists='replace', index=False)
# 参数说明:
# if_exists='replace' - 如果表存在则替换
# if_exists='append' - 如果表存在则追加
# if_exists='fail' - 如果表存在则失败(默认)
读取其他格式
读取 Parquet(列式存储,适合大数据)
# 安装
# pip install pyarrow fastparquet
# 读取
df = pd.read_parquet('data.parquet')
# 写入
df.to_parquet('output.parquet', engine='pyarrow')
读取 HDF5
# 安装
# pip install tables
# 读取
df = pd.read_hdf('data.h5', key='dataset_name')
# 写入
df.to_hdf('output.h5', key='dataset_name', mode='w')
读取 Clipboard(剪贴板)
# 从剪贴板读取
df = pd.read_clipboard()
# 写入剪贴板
df.to_clipboard()
读取 Feather
# 安装
# pip install feather-format
# 读取
df = pd.read_feather('data.feather')
# 写入
df.to_feather('output.feather')
数据保存最佳实践
选择合适的格式
| 格式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| CSV | 通用数据交换 | 通用性强、易读 | 大文件性能差、无类型 |
| Excel | 报告、与非技术人共享 | 易于查看和编辑 | 大文件性能差 |
| JSON | Web API、数据交换 | 结构灵活 | 占用空间大 |
| Parquet | 大数据分析 | 高压缩比、列式存储 | 需要特殊工具 |
| HDF5 | 科学计算、大数据 | 支持大数据、压缩 | 生态较小 |
| Feather | 快速读写 | 极快读写速度 | 主要用于 Python |
实践建议
# 1. 大数据量使用 Parquet
df.to_parquet('large_data.parquet', compression='snappy')
# 2. 需要与其他系统交换使用 JSON
df.to_json('data.json', orient='records', force_ascii=False)
# 3. 需要人类可读使用 Excel
df.to_excel('report.xlsx', sheet_name='销售数据')
# 4. 临时数据使用 CSV
df.to_csv('temp.csv', index=False)
实战示例
示例:读取多种数据源并合并
import pandas as pd
# 1. 从 CSV 读取用户数据
users_df = pd.read_csv('users.csv')
print("用户数据:")
print(users_df)
# 2. 从 Excel 读取订单数据
orders_df = pd.read_excel('orders.xlsx')
print("\n订单数据:")
print(orders_df)
# 3. 从 JSON 读取产品数据
products_df = pd.read_json('products.json')
print("\n产品数据:")
print(products_df)
# 4. 合并数据
# 订单关联用户和商品信息
merged = orders_df.merge(users_df, on='user_id')
merged = merged.merge(products_df, on='product_id')
# 5. 保存合并后的数据
merged.to_csv('merged_data.csv', index=False)
print("\n合并后数据:")
print(merged)
小结
本章我们学习了:
- CSV 文件:读取、写入、参数配置
- Excel 文件:读取、写入、工作表操作
- JSON 文件:读取、写入、各种格式
- HTML:读取网页表格、生成 HTML
- SQL 数据库:使用 SQLAlchemy 读写数据库
- 其他格式:Parquet、HDF5、Feather
- 最佳实践:如何选择合适的文件格式
练习
- 创建一个包含学生成绩的 CSV 文件,读取并计算平均分
- 将 DataFrame 同时保存为 CSV、Excel 和 JSON 格式
- 从网上读取一个包含表格的网页数据
- 使用 SQL 创建一个内存数据库并写入/读取数据
参考资源
下一步
现在你已经学会了如何读取和写入各种数据格式。接下来让我们学习 数据选择与过滤,掌握如何在 DataFrame 中灵活地选择需要的数据!