适用版本 : Pandas 1.x / 2.x
核心函数 :pd.read_csv(),pd.read_table(),pd.read_fwf()
目标: 快速解决各类分隔符文件、日志文件及原始文本的读取问题。
1. 核心函数对比
选择哪个函数?
| 函数 | 默认分隔符 | 典型应用场景 |
|---|---|---|
pd.read_csv() |
, (逗号) |
CSV 文件、Excel 导出的逗号分隔文件 |
pd.read_table() |
\t (Tab) |
TSV 文件、日志文件、自定义分隔符文件 |
pd.read_fwf() |
固定宽度 | 老系统日志、POSITIONAL 数据 |
pd.read_json() |
- | JSON 格式数据 |
pd.read_html() |
- | 网页中的 Table 表格 |
2. 通用参数速查 (Applicable to most readers)
最常用的 10 个参数,适用于 read_csv 和 read_table。
python
import pandas as pd
# --- 基础读取 ---
df = pd.read_csv('data.csv')
# --- 常用参数组合模板 ---
df = pd.read_csv(
filepath_or_buffer='data.txt', # 文件路径 (也可是 URL 或 file-like object)
sep=',', # 分隔符 (delimiter 的别名)
header=0, # 表头行号 (None 表示无表头)
names=['col1', 'col2'], # 自定义列名 (配合 header=None)
index_col='id', # 指定索引列
usecols=['col1', 'col2'], # 只读取指定的列 (提高大文件读取速度)
dtype={'col1': str, 'col2': int}, # 指定列数据类型 (防止类型推断错误)
skiprows=5, # 跳过前 N 行 (常用于跳过注释)
nrows=1000, # 只读取前 N 行 (用于快速预览大数据集)
encoding='utf-8', # 文件编码 (非常重要!)
na_values=['NA', 'NULL', '-'], # 自定义缺失值标记
parse_dates=['date_col'], # 解析日期列
chunksize=10000, # 分块读取 (返回一个迭代器)
comment='#' # 忽略以 # 开头的行
)
3. 分隔符文件 (CSV / TSV / Custom Delimiter)
处理各种分隔符的文本文件。
3.1 标准 CSV
python
# 最简单情况
df = pd.read_csv('input.csv')
# 逗号分隔,第一行为表头
df = pd.read_csv('input.csv', sep=',', header=0)
3.2 TSV (Tab-Separated Values)
python
# 方法 1: 使用 read_table (默认 sep='\t')
df_tsv = pd.read_table('data.tsv')
# 方法 2: 使用 read_csv 指定分隔符
df_tsv = pd.read_csv('data.tsv', sep='\t')
3.3 自定义分隔符 (Pipe, Semicolon 等)
python
# Pipe (|) 分隔
df_pipe = pd.read_csv('data.txt', sep='\|', engine='python') # 注意转义
# Semicolon (;) 分隔 (常见于欧洲地区 CSV)
df_semi = pd.read_csv('data.csv', sep=';')
# 不定长空白分隔 (Whitespace)
df_ws = pd.read_csv('data.txt', delim_whitespace=True) # 等价于 sep='\s+'
4. 特殊格式处理
处理非标准、脏乱数据或特定场景。
4.1 无表头文件
python
# 方法 1: 指定 header=None
df = pd.read_csv('no_header.csv', header=None)
# 方法 2: 手动提供列名
df = pd.read_csv(
'no_header.csv',
header=None,
names=['user_id', 'item_id', 'rating', 'timestamp']
)
4.2 多级表头 (Multi-Header)
python
# 读取合并单元格或层级表头
df = pd.read_csv('multi_header.csv', header=[0, 1])
4.3 固定宽度文件 (FWF)
python
# 通过列宽定义
df = pd.read_fwf(
'fixed_width.txt',
widths=[5, 10, 15], # 每列的宽度
names=['ID', 'Name', 'Address']
)
# 或通过列位置切分
df = pd.read_fwf(
'fixed_width.txt',
colspecs=[(0, 5), (5, 15), (15, 30)],
names=['ID', 'Name', 'Address']
)
4.4 读取压缩文件
python
# Pandas 可自动识别压缩格式
df_gz = pd.read_csv('data.csv.gz')
df_zip = pd.read_csv('data.csv.zip')
df_bz2 = pd.read_csv('data.csv.bz2')
5. 大文件处理策略 (Big Data Handling)
防止内存溢出 (OOM) 的关键技巧。
python
# --- 技巧 1: 只读取需要的列 ---
cols_to_use = ['col_a', 'col_b', 'col_c']
df = pd.read_csv('huge_file.csv', usecols=cols_to_use)
# --- 技巧 2: 指定数据类型 (节省 30%-50% 内存) ---
dtypes = {
'user_id': 'int32', # 默认 int64 -> int32
'category': 'category', # 字符串分类 -> category (极省内存)
'value': 'float32'
}
df = pd.read_csv('huge_file.csv', dtype=dtypes)
# --- 技巧 3: 分块读取 (Chunking) ---
chunk_iter = pd.read_csv('huge_file.csv', chunksize=100000) # 每块 10万行
for chunk in chunk_iter:
# 对每个 chunk 进行处理
process(chunk)
# 例如:聚合、过滤、写入数据库等
# --- 技巧 4: 迭代器模式 ---
reader = pd.read_csv('huge_file.csv', iterator=True)
df_part = reader.get_chunk(1000) # 每次获取 1000 行
6. 编码与错误处理 (Encoding & Errors)
解决 UnicodeDecodeError 的终极方案。
| 编码 (Encoding) | 适用场景 |
|---|---|
utf-8 |
默认首选,通用性强 |
latin-1 / ISO-8859-1 |
西欧语言,容错性极强 (几乎从不报错) |
gbk / gb2312 |
中文 Windows 系统生成的文件 |
utf-16 |
某些特殊导出文件 |
python
# 尝试不同编码
try:
df = pd.read_csv('data.txt', encoding='utf-8')
except UnicodeDecodeError:
df = pd.read_csv('data.txt', encoding='latin-1')
# 忽略无法解码的字符 (Pandas 1.3+)
df = pd.read_csv('data.txt', encoding_errors='ignore')
# 遇到错误替换字符
df = pd.read_csv('data.txt', encoding_errors='replace')
7. 常见错误与解决方案 (Troubleshooting)
| 问题现象 | 原因分析 | 解决方案 |
|---|---|---|
| UnicodeDecodeError | 文件编码不匹配 | 尝试 encoding='latin-1' 或 encoding='gbk' |
| ParserError: Expected X fields | 分隔符不一致或引号内有换行 | sep 设置错误;尝试 engine='python' 或 on_bad_lines='skip' (pd>=1.3) |
| 列被读成一行 (Single Column) | 分隔符未被正确识别 | 检查 sep (如 ` |
| 空行被读入 DataFrame | 文件中存在空行 | skip_blank_lines=True (默认) |
| 日期列变成字符串 | 未指定 parse_dates |
pd.read_csv(..., parse_dates=['date_col']) |
| 内存爆炸 (Memory Explosion) | 未指定 dtype,全是 object | 使用 dtype 参数,尤其是 category 类型 |
| 混合类型列 (Mixed Types) | 列中既有数字又有字符串 | dtype=str 或 low_memory=False (不推荐,仅调试用) |
8. 实战代码片段 (Copy & Paste)
python
# 场景 1: 快速预览未知文件
pd.read_csv('unknown.txt', nrows=5, header=None)
# 场景 2: 读取 Linux Log 文件 (通常分隔符不规则)
pd.read_csv(
'app.log',
sep=r'\s+', # 正则匹配任意空白符
header=None,
names=['time', 'level', 'message']
)
# 场景 3: 从剪贴板读取数据 (Ctrl+C 的数据)
df = pd.read_clipboard()
# 场景 4: 从字符串读取
from io import StringIO
data = "col1,col2\n1,a\n2,b"
df = pd.read_csv(StringIO(data))