数据读取与写入
目录
- [读取 CSV 文件](#读取 CSV 文件)
- [写入 CSV 文件](#写入 CSV 文件)
- [读取和写入 Excel 文件](#读取和写入 Excel 文件)
- [读取和写入 JSON 文件](#读取和写入 JSON 文件)
- [读取和写入 SQL 数据库](#读取和写入 SQL 数据库)
- 读取和写入其他格式
- 常见问题与技巧
读取 CSV 文件
CSV(Comma-Separated Values)是最常用的数据格式之一。
基本用法
python
import pandas as pd
# 读取 CSV 文件
df = pd.read_csv('data.csv')
# 查看前几行
print(df.head())
常用参数
python
import pandas as pd
# 指定分隔符
df = pd.read_csv('data.tsv', sep='\t') # 制表符分隔
# 指定编码(处理中文)
df = pd.read_csv('data.csv', encoding='utf-8')
df = pd.read_csv('data.csv', encoding='gbk') # Windows 中文编码
# 指定列名
df = pd.read_csv('data.csv', names=['姓名', '年龄', '城市'])
# 指定索引列
df = pd.read_csv('data.csv', index_col=0) # 第一列作为索引
df = pd.read_csv('data.csv', index_col='ID') # 指定列名作为索引
# 跳过行
df = pd.read_csv('data.csv', skiprows=1) # 跳过第一行
df = pd.read_csv('data.csv', skiprows=[0, 2, 3]) # 跳过指定行
# 只读取前 n 行
df = pd.read_csv('data.csv', nrows=100)
# 指定读取的列
df = pd.read_csv('data.csv', usecols=['姓名', '年龄'])
# 处理缺失值标记
df = pd.read_csv('data.csv', na_values=['NULL', 'N/A', ''])
# 指定数据类型
df = pd.read_csv('data.csv', dtype={'年龄': int, '工资': float})
# 解析日期
df = pd.read_csv('data.csv', parse_dates=['日期'])
实际示例
python
import pandas as pd
# 创建一个示例 CSV 文件用于演示
data = {
'ID': [1, 2, 3, 4, 5],
'姓名': ['张三', '李四', '王五', '赵六', '孙七'],
'年龄': [25, 30, 35, 28, 32],
'城市': ['北京', '上海', '广州', '深圳', '杭州'],
'工资': [8000, 12000, 10000, 11000, 9500],
'日期': ['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04', '2024-01-05']
}
df_example = pd.DataFrame(data)
df_example.to_csv('example.csv', index=False, encoding='utf-8-sig')
# 读取文件
df = pd.read_csv('example.csv', encoding='utf-8-sig', parse_dates=['日期'])
print(df)
print(df.dtypes)
写入 CSV 文件
基本用法
python
import pandas as pd
data = {
'姓名': ['张三', '李四', '王五'],
'年龄': [25, 30, 35],
'工资': [8000, 12000, 10000]
}
df = pd.DataFrame(data)
# 写入 CSV 文件
df.to_csv('output.csv', index=False)
常用参数
python
import pandas as pd
df = pd.DataFrame(data)
# 不写入索引
df.to_csv('output.csv', index=False)
# 指定分隔符
df.to_csv('output.tsv', sep='\t', index=False)
# 指定编码
df.to_csv('output.csv', encoding='utf-8-sig', index=False) # 带 BOM 的 UTF-8,Excel 可识别
# 指定列
df.to_csv('output.csv', columns=['姓名', '工资'], index=False)
# 不写入列名
df.to_csv('output.csv', header=False, index=False)
# 指定缺失值表示
df.to_csv('output.csv', na_rep='N/A', index=False)
# 指定浮点数格式
df.to_csv('output.csv', float_format='%.2f', index=False)
# 追加模式(不常用)
df.to_csv('output.csv', mode='a', header=False, index=False)
读取和写入 Excel 文件
安装依赖
bash
pip install pandas openpyxl # Excel 2007+ (.xlsx)
pip install pandas xlrd # Excel 2003 (.xls)
读取 Excel 文件
python
import pandas as pd
# 读取 Excel 文件
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) # 返回字典
df1 = all_sheets['Sheet1']
df2 = all_sheets['Sheet2']
# 读取指定行和列
df = pd.read_excel('data.xlsx',
usecols='A:C', # 只读 A、B、C 列
nrows=100) # 只读前 100 行
# 指定索引列
df = pd.read_excel('data.xlsx', index_col=0)
# 跳过行
df = pd.read_excel('data.xlsx', skiprows=1)
# 指定列名
df = pd.read_excel('data.xlsx', names=['列1', '列2', '列3'], header=0)
写入 Excel 文件
python
import pandas as pd
data1 = {
'姓名': ['张三', '李四', '王五'],
'年龄': [25, 30, 35],
'工资': [8000, 12000, 10000]
}
df1 = pd.DataFrame(data1)
data2 = {
'产品': ['A', 'B', 'C'],
'销量': [100, 200, 150],
'价格': [10, 20, 15]
}
df2 = pd.DataFrame(data2)
# 写入单个工作表
df1.to_excel('output.xlsx', index=False)
# 写入多个工作表
with pd.ExcelWriter('output.xlsx') as writer:
df1.to_excel(writer, sheet_name='员工', index=False)
df2.to_excel(writer, sheet_name='产品', index=False)
# 追加到现有 Excel 文件
with pd.ExcelWriter('output.xlsx', mode='a', if_sheet_exists='replace') as writer:
df2.to_excel(writer, sheet_name='产品', index=False)
# 设置格式(需要 openpyxl)
from openpyxl import load_workbook
df1.to_excel('output.xlsx', index=False)
wb = load_workbook('output.xlsx')
ws = wb.active
ws.column_dimensions['A'].width = 20
wb.save('output.xlsx')
读取和写入 JSON 文件
读取 JSON 文件
python
import pandas as pd
# 读取标准 JSON 文件
df = pd.read_json('data.json')
# JSON 文件示例(records 格式)
json_data = '''
[
{"姓名": "张三", "年龄": 25, "城市": "北京"},
{"姓名": "李四", "年龄": 30, "城市": "上海"},
{"姓名": "王五", "年龄": 35, "城市": "广州"}
]
'''
with open('data.json', 'w', encoding='utf-8') as f:
f.write(json_data)
df = pd.read_json('data.json')
print(df)
# 读取嵌套 JSON(需要先处理)
import json
with open('nested_data.json', 'r', encoding='utf-8') as f:
data = json.load(f)
df = pd.json_normalize(data) # 展平嵌套结构
# 从 URL 读取 JSON
df = pd.read_json('https://api.example.com/data.json')
写入 JSON 文件
python
import pandas as pd
data = {
'姓名': ['张三', '李四', '王五'],
'年龄': [25, 30, 35],
'城市': ['北京', '上海', '广州']
}
df = pd.DataFrame(data)
# 写入 JSON(records 格式)
df.to_json('output.json', orient='records', force_ascii=False, indent=2)
# 不同格式
df.to_json('output.json', orient='index') # 按索引
df.to_json('output.json', orient='columns') # 按列
df.to_json('output.json', orient='values') # 仅值
df.to_json('output.json', orient='split') # 分离格式
# 处理日期
df['日期'] = pd.date_range('2024-01-01', periods=3)
df.to_json('output.json', date_format='iso')
读取和写入 SQL 数据库
安装依赖
bash
pip install sqlalchemy pymysql # MySQL
pip install sqlalchemy psycopg2 # PostgreSQL
pip install sqlalchemy sqlite3 # SQLite(内置)
连接数据库并读取数据
python
import pandas as pd
from sqlalchemy import create_engine
# MySQL 连接
engine = create_engine('mysql+pymysql://user:password@localhost/dbname')
# PostgreSQL 连接
# engine = create_engine('postgresql://user:password@localhost/dbname')
# SQLite 连接(最简单,无需服务器)
engine = create_engine('sqlite:///database.db')
# 读取数据
query = "SELECT * FROM employees"
df = pd.read_sql(query, engine)
# 读取表(自动生成 SELECT *)
df = pd.read_sql_table('employees', engine)
# 使用参数化查询(防止 SQL 注入)
query = "SELECT * FROM employees WHERE age > :age"
df = pd.read_sql(query, engine, params={'age': 30})
# 读取整个数据库的所有表
from sqlalchemy import inspect
inspector = inspect(engine)
tables = inspector.get_table_names()
for table in tables:
df = pd.read_sql_table(table, engine)
print(f"{table}: {len(df)} rows")
写入数据库
python
import pandas as pd
from sqlalchemy import create_engine
# 创建连接
engine = create_engine('sqlite:///database.db')
data = {
'姓名': ['张三', '李四', '王五'],
'年龄': [25, 30, 35],
'工资': [8000, 12000, 10000]
}
df = pd.DataFrame(data)
# 写入数据(如果表不存在会自动创建)
df.to_sql('employees', engine, index=False, if_exists='replace')
# if_exists 参数选项:
# - 'fail': 如果表存在则失败(默认)
# - 'replace': 删除表后重新创建
# - 'append': 追加到现有表
# 分批写入大数据
df.to_sql('employees', engine, index=False, if_exists='append', chunksize=1000)
# 指定数据类型
from sqlalchemy.types import Integer, String, Float
df.to_sql('employees', engine, index=False,
dtype={'姓名': String(50), '年龄': Integer(), '工资': Float()})
读取和写入其他格式
Parquet 格式(高效压缩)
python
import pandas as pd
# 需要安装:pip install pyarrow 或 fastparquet
# 读取 Parquet
df = pd.read_parquet('data.parquet')
# 写入 Parquet
df.to_parquet('output.parquet', index=False)
# 压缩选项
df.to_parquet('output.parquet', compression='snappy') # 或 'gzip', 'brotli'
HDF5 格式(大数据)
python
import pandas as pd
# 需要安装:pip install tables
# 写入 HDF5
df.to_hdf('data.h5', key='df', mode='w')
# 读取 HDF5
df = pd.read_hdf('data.h5', key='df')
# 追加多个 DataFrame
df1.to_hdf('data.h5', key='df1', mode='w')
df2.to_hdf('data.h5', key='df2', mode='a') # append mode
HTML 表格
python
import pandas as pd
# 读取网页中的表格
tables = pd.read_html('https://example.com/table.html')
df = tables[0] # 第一个表格
# 将 DataFrame 转为 HTML
html = df.to_html(index=False)
print(html)
# 保存为 HTML 文件
df.to_html('output.html', index=False)
Pickle 格式(Python 专用)
python
import pandas as pd
# 保存为 pickle(保留所有类型信息)
df.to_pickle('data.pkl')
# 读取 pickle
df = pd.read_pickle('data.pkl')
从剪贴板读取
python
import pandas as pd
# 从剪贴板读取(类似复制 Excel 表格后读取)
df = pd.read_clipboard()
# 写入剪贴板
df.to_clipboard(index=False)
常见问题与技巧
1. 处理大文件
python
import pandas as pd
# 分块读取大文件
chunk_size = 10000
chunks = []
for chunk in pd.read_csv('large_file.csv', chunksize=chunk_size):
# 处理每个块
processed_chunk = chunk[chunk['age'] > 30]
chunks.append(processed_chunk)
# 合并所有块
df = pd.concat(chunks, ignore_index=True)
# 只读取需要的列(节省内存)
df = pd.read_csv('large_file.csv', usecols=['col1', 'col2', 'col3'])
# 指定数据类型(节省内存)
dtypes = {'col1': 'int32', 'col2': 'float32', 'col3': 'category'}
df = pd.read_csv('large_file.csv', dtype=dtypes)
2. 处理编码问题
python
import pandas as pd
import chardet
# 自动检测编码
with open('data.csv', 'rb') as f:
raw_data = f.read()
result = chardet.detect(raw_data)
encoding = result['encoding']
df = pd.read_csv('data.csv', encoding=encoding)
# 常见编码
# UTF-8: 国际通用
# GBK/GB2312: 中文 Windows
# ISO-8859-1: 西欧语言
3. 处理缺失值和特殊值
python
import pandas as pd
# 指定缺失值标记
df = pd.read_csv('data.csv',
na_values=['NULL', 'N/A', 'NA', 'null', 'None', ''])
# 保留字符串 'NA'
df = pd.read_csv('data.csv', keep_default_na=False, na_values=[''])
# 处理无穷大值
import numpy as np
df.replace([np.inf, -np.inf], np.nan, inplace=True)
4. 性能优化
python
import pandas as pd
# 使用 C 引擎(默认,更快)
df = pd.read_csv('data.csv', engine='c')
# Python 引擎(功能更全但较慢)
df = pd.read_csv('data.csv', engine='python')
# 禁用类型推断(加快读取速度)
df = pd.read_csv('data.csv', dtype=str) # 全部作为字符串读取
# 使用 low_memory=False(对于内存充足的情况)
df = pd.read_csv('data.csv', low_memory=False)
5. 实际应用示例
python
import pandas as pd
import os
# 读取多个文件并合并
files = ['data1.csv', 'data2.csv', 'data3.csv']
dfs = []
for file in files:
if os.path.exists(file):
df = pd.read_csv(file)
df['来源文件'] = file
dfs.append(df)
combined_df = pd.concat(dfs, ignore_index=True)
# 读取文件夹中所有 CSV 文件
import glob
csv_files = glob.glob('data/*.csv')
all_data = pd.concat([pd.read_csv(f) for f in csv_files], ignore_index=True)
# 条件读取(只读取符合条件的行)
def filter_func(chunk):
return chunk[chunk['age'] > 30]
df = pd.concat([filter_func(chunk) for chunk in pd.read_csv('data.csv', chunksize=1000)])
总结
Pandas 提供了丰富的数据读取和写入功能:
- 多种格式支持:CSV、Excel、JSON、SQL、Parquet 等
- 灵活的参数:可以精细控制读取和写入过程
- 性能优化:分块读取、指定数据类型等技巧
- 编码处理:正确处理各种字符编码