Pandas--数据读取与写入
数据读取与写入
目录
- 读取 CSV 文件
- 写入 CSV 文件
- 读取和写入 Excel 文件
- 读取和写入 JSON 文件
- 读取和写入 SQL 数据库
- 读取和写入其他格式
- 常见问题与技巧
读取 CSV 文件
CSV(Comma-Separated Values)是最常用的数据格式之一。
基本用法
import pandas as pd# 读取 CSV 文件
df = pd.read_csv('data.csv')# 查看前几行
print(df.head())
常用参数
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=['日期'])
实际示例
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 文件
基本用法
import pandas as pddata = {'姓名': ['张三', '李四', '王五'],'年龄': [25, 30, 35],'工资': [8000, 12000, 10000]
}
df = pd.DataFrame(data)# 写入 CSV 文件
df.to_csv('output.csv', index=False)
常用参数
import pandas as pddf = 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 文件
安装依赖
pip install pandas openpyxl # Excel 2007+ (.xlsx)
pip install pandas xlrd # Excel 2003 (.xls)
读取 Excel 文件
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 文件
import pandas as pddata1 = {'姓名': ['张三', '李四', '王五'],'年龄': [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 文件
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 文件
import pandas as pddata = {'姓名': ['张三', '李四', '王五'],'年龄': [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 数据库
安装依赖
pip install sqlalchemy pymysql # MySQL
pip install sqlalchemy psycopg2 # PostgreSQL
pip install sqlalchemy sqlite3 # SQLite(内置)
连接数据库并读取数据
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")
写入数据库
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 格式(高效压缩)
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 格式(大数据)
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 表格
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 专用)
import pandas as pd# 保存为 pickle(保留所有类型信息)
df.to_pickle('data.pkl')# 读取 pickle
df = pd.read_pickle('data.pkl')
从剪贴板读取
import pandas as pd# 从剪贴板读取(类似复制 Excel 表格后读取)
df = pd.read_clipboard()# 写入剪贴板
df.to_clipboard(index=False)
常见问题与技巧
1. 处理大文件
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. 处理编码问题
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. 处理缺失值和特殊值
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. 性能优化
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. 实际应用示例
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['来源文件'] = filedfs.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 等
- 灵活的参数:可以精细控制读取和写入过程
- 性能优化:分块读取、指定数据类型等技巧
- 编码处理:正确处理各种字符编码
