4. 文件读写与数据导入:CSV、Excel、JSON、SQLite

数据导入,说白了就是给程序喂饭。喂得好不好,直接决定了后面分析能不能跑起来。我刚开始做质控工具的时候,就遇到过因为读取参数没配好,整个batch的数据类型全乱了——嗯,从那以后我养成了一个习惯:每读一个文件,先看一眼它的元数据。

这章我们就聊四个最常见的格式:CSV、Excel、JSON 和 SQLite。别小看这些基础操作,用好 pandad 这些接口,能让你的数据输入流程自动化起来。

4.1 CSV:最通用的表格数据

CSV 是我在质控项目里遇到最多的格式。生产环境里的日志、测试数据、设备参数,动不动就是 CSV。它的优势就是轻量,任何文本编辑器都能打开。

我个人习惯用 pandas.read_csv(),参数很灵活,但常用的就那么几个。

import pandas as pd

# 最基础的读取
df = pd.read_csv('qc_data.csv')

# 指定编码,避免乱码(我吃过这个亏)
df = pd.read_csv('qc_data.csv', encoding='utf-8')

# 跳过前两行注释,指定列名
df = pd.read_csv('qc_data.csv', skiprows=2, names=['batch_id', 'value', 'status'])

# 只看前100行,快速预览
df = pd.read_csv('qc_data.csv', nrows=100)

记得有一次,同事给我的 CSV 文件里时间列全是字符串,结果后面的统计全部报错。我加上 parse_dates=['timestamp'] 就搞定了。这里要注意:数据量大的时候,用 dtype 参数指定类型,能省不少内存。

小技巧: 不确定文件内容时,先用 df.head() 和 df.info() 扫一眼。我每次都会这么做,就像出门前看一眼天气预报。

4.2 Excel:更复杂的表格

Excel 文件比 CSV 复杂多了,有多个 sheet、合并单元格、公式、条件格式。在质控场景里,我们经常需要从不同部门拿到的 Excel 报表里提取数据。

pandas.read_excel() 的核心是处理多 sheet 和定位数据区域。

import pandas as pd

# 读取默认 sheet(第一个)
df = pd.read_excel('qc_report.xlsx')

# 指定 sheet 名称
df = pd.read_excel('qc_report.xlsx', sheet_name='测量数据')

# 指定 sheet 索引(0 开始)
df = pd.read_excel('qc_report.xlsx', sheet_name=0)

# 读取所有 sheet,返回字典
sheets = pd.read_excel('qc_report.xlsx', sheet_name=None)
for name, df in sheets.items():
    print(f"Sheet: {name}, 行数: {len(df)}")

为什么我会强调 sheet 参数?因为我曾经遇到过一份报告,里面有十几个 sheet,每个 sheet 对应不同的测试项目。如果一个个手动打开看,那得累死。直接用 sheet_name=None 一次性全部读进来,后面用循环处理就方便多了。

注意: Excel 文件有行数和列数的限制(老版本 65536 行、新版 1048576 行)。如果文件超大,建议考虑转换成 CSV 或直接切分。

4.3 JSON:半结构化数据的首选

JSON 在 API 接口和配置文件中特别常见。质控系统里,设备采集的原始数据经常用 JSON 格式返回,因为它的结构自由,可以嵌套。

pandas 读取 JSON 有两个常用场景:一是读本地文件,二是从 API 拿到的字符串。

import pandas as pd
import json

# 从文件读取
df = pd.read_json('instrument_data.json')

# 读取嵌套结构,可以用 orient 参数
# 比如数据是 {"measurements": [{"id": 1, "value": 0.5}, ...]}
df = pd.read_json('instrument_data.json', orient='records')

# 从字符串读取
json_str = '[{"id": 1, "value": 0.5}, {"id": 2, "value": 0.6}]'
df = pd.read_json(json_str)

# 处理多层嵌套:先读到 Pandas 再展开
df = pd.read_json('deep_nested.json')
# 用 json_normalize 展开嵌套列
from pandas import json_normalize
data = json.load(open('deep_nested.json'))
df_flat = json_normalize(data, record_path='samples', meta=['batch_id'])

我个人建议:如果 JSON 结构很复杂,别怕,先用 pd.json_normalize() 展开,它比手动写循环快多了。

4.4 SQLite:轻量级数据库

很多时候,数据不是放在文件里,而是存在数据库里。SQLite 是个很好的起点,它不需要装数据库服务器,一个文件就是整个库。我们在开发质控工具时,经常拿 SQLite 来存历史记录和配置。

pandas 的 read_sql() 可以配合 sqlite3 使用。

import sqlite3
import pandas as pd

# 连接数据库文件
conn = sqlite3.connect('qc_history.db')

# 直接写 SQL 查询
df = pd.read_sql("SELECT * FROM measurements WHERE batch = 'B001'", conn)

# 使用参数化查询,避免 SQL 注入
query = "SELECT * FROM measurements WHERE batch = ? AND date > ?"
df = pd.read_sql(query, conn, params=('B001', '2024-01-01'))

# 查询所有表名
tables = pd.read_sql("SELECT name FROM sqlite_master WHERE type='table'", conn)

# 别忘了关闭连接
conn.close()

这里有个坑:我之前用 read_sql() 时,忘了关连接,结果程序跑了几千次后,数据库文件被锁住了。后来我改用 with 上下文管理器,省心多了。

# 推荐写法:自动管理连接
with sqlite3.connect('qc_history.db') as conn:
    df = pd.read_sql("SELECT * FROM measurements", conn)

4.5 数据导入的小结对比

格式 主函数 常见坑 质控场景
CSV read_csv 编码、分隔符、类型推断错误 设备日志、批量测量数据
Excel read_excel 多 sheet、合并单元格、格式干扰 部门报表、手动录入数据
JSON read_json 嵌套结构、列表与字典混用 API 返回、设备采集原始数据
SQLite read_sql 连接未关闭、SQL 语法、参数传递 历史记录、配置持久化
文件读取与数据导入核心流程 CSV 文件 Excel 文件 JSON 文件 SQLite 数据库 Pandas 读取函数 read_csv / read_excel read_json / read_sql DataFrame(统一数据结构) 质量检查 → 统计 → 可视化 → 报告

核心思路: 无论来源是文件还是数据库,最终都转化为 DataFrame 这个统一结构。这样后面的清洗、分析、质控逻辑,就可以复用一套代码。我在设计质控框架时,都是先定义数据接口,再具体实现读取逻辑。

记住一个原则:读进来的数据,先用 .info() 和 .describe() 检查一遍。如果类型不对、有缺失值、有重复行,趁早处理。我曾经因为没检查,直接跑分析,结果花了半天发现是数据读错了——嗯,这教训我记到现在。