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 一次性全部读进来,后面用循环处理就方便多了。
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 语法、参数传递 | 历史记录、配置持久化 |
核心思路: 无论来源是文件还是数据库,最终都转化为 DataFrame 这个统一结构。这样后面的清洗、分析、质控逻辑,就可以复用一套代码。我在设计质控框架时,都是先定义数据接口,再具体实现读取逻辑。
记住一个原则:读进来的数据,先用 .info() 和 .describe() 检查一遍。如果类型不对、有缺失值、有重复行,趁早处理。我曾经因为没检查,直接跑分析,结果花了半天发现是数据读错了——嗯,这教训我记到现在。