Skip to content

Module 7: 文件输入输出 (File I/O)

数据持久化的必备技能 —— 读写各种格式的数据文件


本章概览

数据分析的第一步是读取数据,最后一步是保存结果。本章将教你如何在 Python 中读写各种格式的文件:文本文件、CSV、Excel、Stata(.dta)、JSON 等。掌握文件 I/O,你就能与各种数据源无缝对接。

重要提示:本章是数据分析的基础设施,虽然不如回归分析有趣,但却是必不可少的技能。


学习目标

学完本章后,你将能够:

  • 理解文件路径和编码问题
  • 读写文本文件(.txt)
  • 处理 CSV 文件(最常用的数据格式)
  • 读写 Excel 文件(.xlsx)
  • 与 Stata 数据无缝对接(.dta)
  • 处理 JSON 数据(API 和 Web 数据)
  • 批量处理多个文件
  • 构建数据处理流水线

章节内容

01 - 文件读写基础

核心问题: 如何读写文本文件?

核心内容:

  • 为什么需要文件操作?
    • 保存数据分析结果
    • 读取外部数据
    • 生成报告和日志
    • 数据备份
  • 基本文件操作:
    • 写入文件:open('file.txt', 'w')
    • 读取文件:open('file.txt', 'r')
    • 追加内容:open('file.txt', 'a')
  • 上下文管理器(with 语句):
    python
    #  推荐(自动关闭文件)
    with open('file.txt', 'r', encoding='utf-8') as f:
        content = f.read()
    
    #  不推荐(需要手动关闭)
    f = open('file.txt', 'r')
    content = f.read()
    f.close()
  • 路径操作(pathlib):
    python
    from pathlib import Path
    
    data_dir = Path('data')
    raw_dir = data_dir / 'raw'  # 路径拼接
    raw_dir.mkdir(parents=True, exist_ok=True)  # 创建目录
    
    for file in data_dir.glob('*.txt'):  # 遍历文件
        print(file)
  • 编码问题:
    • 中文文件必须指定 encoding='utf-8'
    • Windows 默认编码是 gbk,可能导致乱码

实战案例:

python
# 案例:保存问卷结果
respondents = [
    {'id': 1001, 'age': 25, 'income': 50000},
    {'id': 1002, 'age': 30, 'income': 75000}
]

with open('survey_results.txt', 'w', encoding='utf-8') as f:
    f.write("问卷调查结果\n")
    f.write("=" * 40 + "\n")
    for resp in respondents:
        line = f"ID:{resp['id']}, 年龄:{resp['age']}, 收入:{resp['income']}\n"
        f.write(line)

02 - CSV 与 Excel 文件处理

核心问题: 如何读写表格数据?

核心内容:

  • CSV 文件(最常用):
    • 使用 csv 模块(基础)
    • 使用 Pandas(推荐):
      python
      import pandas as pd
      
      # 读取 CSV
      df = pd.read_csv('survey.csv')
      
      # 写入 CSV(避免 Excel 乱码)
      df.to_csv('output.csv', index=False, encoding='utf-8-sig')
      
      # 常用参数
      df = pd.read_csv(
          'data.csv',
          sep=',',              # 分隔符
          header=0,             # 第一行是列名
          usecols=[0, 1, 3],   # 只读某些列
          dtype={'age': int},   # 指定数据类型
          na_values=['NA', '']  # 缺失值标记
      )
  • Excel 文件:
    • 安装依赖:pip install openpyxl
    • 读取单个工作表:
      python
      df = pd.read_excel('survey.xlsx', sheet_name='Sheet1')
    • 读取多个工作表:
      python
      all_sheets = pd.read_excel('survey.xlsx', sheet_name=None)
    • 写入多个工作表:
      python
      with pd.ExcelWriter('report.xlsx') as writer:
          df1.to_excel(writer, sheet_name='2023', index=False)
          df2.to_excel(writer, sheet_name='2024', index=False)

实战案例:

python
# 案例:合并多个 CSV 文件
from pathlib import Path

data_dir = Path('surveys')
all_data = []

for csv_file in data_dir.glob('*.csv'):
    df = pd.read_csv(csv_file)
    df['source_file'] = csv_file.name  # 添加来源标识
    all_data.append(df)

combined_df = pd.concat(all_data, ignore_index=True)
combined_df.to_csv('combined_survey.csv', index=False)

03 - Stata 数据文件读写

核心问题: 如何与 Stata 数据无缝对接?

核心内容:

  • 为什么需要读写 Stata 文件?
    • 很多社科数据以 .dta 格式存储
    • 保留变量标签、值标签等元数据
    • 与 Stata 用户协作
  • 读取 Stata 文件:
    python
    import pandas as pd
    
    # 基本读取
    df = pd.read_stata('survey_data.dta')
    
    # 保留值标签(例如:1='Male', 2='Female')
    df = pd.read_stata('survey_data.dta', convert_categoricals=True)
  • 写入 Stata 文件:
    python
    # 保存为 Stata 13 格式
    df.to_stata('output.dta', write_index=False, version=117)
    
    # Stata 版本对照:
    # 117 = Stata 13/14
    # 118 = Stata 15/16
    # 119 = Stata 17
  • 处理变量标签和值标签:
    python
    # 添加变量标签
    variable_labels = {
        'id': 'Respondent ID',
        'gender': 'Gender',
        'education': 'Education Level'
    }
    
    df.to_stata(
        'output.dta',
        write_index=False,
        variable_labels=variable_labels
    )

实战案例:

python
# 案例:Stata 到 Python 数据流
import pandas as pd
import numpy as np

# 1. 读取 Stata 数据
df = pd.read_stata('raw_survey.dta')
print(f"原始数据: {len(df)} 行")

# 2. 数据清洗(Python)
df_clean = df[
    (df['age'] >= 18) &
    (df['age'] <= 100) &
    (df['income'] > 0)
].copy()

# 3. 新变量生成
df_clean['log_income'] = np.log(df_clean['income'])
df_clean['age_squared'] = df_clean['age'] ** 2

# 4. 保存回 Stata 格式
df_clean.to_stata('clean_survey.dta', write_index=False)
print(f"清洗后: {len(df_clean)} 行")

04 - JSON 数据处理

核心问题: 如何处理 Web 和 API 数据?

核心内容:

  • 什么是 JSON?
    • 现代 Web 数据的标准格式
    • 结构类似 Python 字典
    • 广泛用于 API、配置文件
  • 基本操作:
    python
    import json
    
    # Python 对象 → JSON 字符串
    data = {'id': 1001, 'age': 30, 'income': 75000}
    json_str = json.dumps(data, indent=2, ensure_ascii=False)
    
    # JSON 字符串 → Python 对象
    json_str = '{"name": "Alice", "age": 25}'
    data = json.loads(json_str)
    
    # 读写 JSON 文件
    with open('data.json', 'w', encoding='utf-8') as f:
        json.dump(data, f, indent=2, ensure_ascii=False)
    
    with open('data.json', 'r', encoding='utf-8') as f:
        data = json.load(f)
  • JSON 与 Pandas 互转:
    python
    # Pandas → JSON
    df.to_json('data.json', orient='records', force_ascii=False, indent=2)
    
    # JSON → Pandas
    df = pd.read_json('data.json', orient='records')

实战案例:

python
# 案例:从 API 获取数据
import requests
import pandas as pd

# 1. 获取 JSON 数据
response = requests.get('https://api.example.com/data')
data = response.json()

# 2. 转为 DataFrame
df = pd.DataFrame(data['results'])

# 3. 保存为 CSV
df.to_csv('api_data.csv', index=False)

文件格式对比

格式优点缺点使用场景
TXT简单、通用无结构日志、简单报告
CSV通用、轻量、易读无类型信息、无元数据数据交换、表格数据
Excel多工作表、格式丰富文件大、速度慢报告、给非技术人员
Stata(.dta)保留标签、元数据仅社科领域使用社科数据、与 Stata 协作
JSON结构化、嵌套数据体积大API 数据、配置文件
Parquet高效、压缩好不可读大数据、生产环境

选择建议

需求推荐格式原因
数据交换CSV通用、所有工具都支持
给导师/同事Excel可视化好、易编辑
Stata 协作DTA保留元数据
API 数据JSON标准格式
大数据(>1GB)Parquet高效、压缩好
中间结果CSV/Pickle快速、简单

如何学习本章?

学习路线

第 1 天(2小时): 文件读写基础

  • 阅读 01 - 文件读写基础
  • 练习读写文本文件
  • 学习 pathlib 路径操作

第 2 天(3小时): CSV 与 Excel

  • 阅读 02 - CSV 与 Excel 文件处理
  • 用 Pandas 读写 CSV
  • 练习合并多个 CSV 文件

第 3 天(2小时): Stata 数据

  • 阅读 03 - Stata 数据文件读写
  • 读取 .dta 文件
  • 练习 Stata ↔ Python 数据流

第 4 天(2小时): JSON 数据

  • 阅读 04 - JSON 数据处理
  • 练习 JSON 读写
  • JSON 与 Pandas 互转

总时间: 9 小时(1 周)

最小化学习路径

对于社科学生,优先级如下:

必学(日常分析,5小时):

  • 02 - CSV 与 Excel(最常用)
  • 03 - Stata 数据文件(社科必备)
  • Pandas 读写基础

重要(完整技能,4小时):

  • 01 - 文件读写基础
  • 04 - JSON 数据处理

可选(高级主题):

  • 批量处理多个文件
  • Parquet、HDF5 等高效格式
  • 数据库连接(SQL)

学习建议

  1. 以实际需求为导向

    • 有什么格式的数据,就学对应的方法
    • CSV 和 Stata 是社科学生的重点
    • JSON 在使用 API 时才需要
  2. 记住核心模式

    python
    # 几乎所有格式都遵循这个模式:
    
    # 读取
    data = pd.read_xxx('file.xxx')
    
    # 处理
    data_clean = data[data['age'] > 18]
    
    # 保存
    data_clean.to_xxx('output.xxx')
  3. 常见错误和解决方案

    • 乱码: 指定 encoding='utf-8'encoding='utf-8-sig'
    • 文件未找到: 检查路径,使用绝对路径或 Path()
    • 缺失值: 指定 na_values=['NA', '', '-999']
    • 数据类型: 使用 dtype={'col': int} 指定类型
  4. 实践项目 创建一个数据处理流水线:

    python
    # data_pipeline.py
    
    import pandas as pd
    from pathlib import Path
    
    def process_survey(input_file, output_file):
        """处理问卷数据"""
        # 1. 读取
        df = pd.read_stata(input_file)
        print(f"原始数据: {len(df)} 行")
        
        # 2. 清洗
        df_clean = df[
            (df['age'] >= 18) &
            (df['age'] <= 100) &
            (df['income'] > 0)
        ]
        print(f"清洗后: {len(df_clean)} 行")
        
        # 3. 保存
        df_clean.to_csv(output_file, index=False, encoding='utf-8-sig')
        print(f"已保存到: {output_file}")
    
    # 使用
    process_survey('raw_survey.dta', 'clean_survey.csv')

常见问题

Q: 为什么读取中文 CSV 会乱码? A: 编码问题。尝试:

python
# 方法 1:UTF-8
df = pd.read_csv('data.csv', encoding='utf-8')

# 方法 2:GBK(Windows 中文)
df = pd.read_csv('data.csv', encoding='gbk')

# 方法 3:自动检测
df = pd.read_csv('data.csv', encoding='utf-8-sig')

Q: 为什么保存的 CSV 用 Excel 打开是乱码? A: Excel 默认用 GBK 编码打开文件。解决方案:

python
# 保存时使用 utf-8-sig(Excel 兼容的 UTF-8)
df.to_csv('output.csv', index=False, encoding='utf-8-sig')

Q: 如何处理大文件(>1GB)? A: 分块读取:

python
# 分块读取
for chunk in pd.read_csv('large_file.csv', chunksize=10000):
    # 处理每个 chunk
    processed = chunk[chunk['age'] > 18]
    # 保存或进一步处理

Q: Stata 和 CSV 哪个好? A:

  • Stata(.dta): 保留变量标签和值标签,适合社科数据
  • CSV: 通用格式,所有工具都支持,但丢失元数据
  • 建议: 原始数据用 Stata,中间结果用 CSV

Q: 为什么推荐 Pandas 而不是 csv 模块? A:

  • Pandas 更强大:自动类型推断、缺失值处理、数据操作
  • csv 模块更底层:需要手动处理很多细节
  • 对于数据分析,Pandas 是首选

Q: 如何批量处理多个文件? A:

python
from pathlib import Path

data_dir = Path('surveys')
for file in data_dir.glob('*.csv'):
    df = pd.read_csv(file)
    # 处理...
    df.to_csv(f'processed_{file.name}', index=False)

下一步

完成本章后,你将掌握:

  • 读写文本、CSV、Excel、Stata、JSON 文件
  • 处理编码和路径问题
  • 批量处理多个文件
  • 构建数据处理流水线

Module 8 中,我们将学习错误处理和调试,让代码更健壮可靠。

Module 9 中,我们将深入学习 NumPy、Pandas、Matplotlib 等数据科学核心库。

掌握文件 I/O,你就能处理任何数据源了!继续前进!


快速链接

基于 MIT 许可证发布。内容版权归作者所有。