ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

用Python和CSV自制血糖管理工具:从数据清洗到可视化报告

用Python和CSV自制血糖管理工具:从数据清洗到可视化报告 简介这是一款面向网络管理员与运维人员的工具资源SugarNMSTool 2.0 专注于扫描并识别网络中开启 SNMP 服务的华为交换机通过解析 OID 信息快速定位设备状态适用于日常设备发现、性能监控与故障排查场景。压缩包共8个文件大小3.65MB包含可执行的 jar 程序、bat/sh 跨平台启动脚本、txt 使用说明与 PDF 快速入门手册以及 dat 拓扑数据文件结构简洁便于快速上手。已有1262人学习下载。通过学习该工具源码与配套文档读者可以理解 SNMP 协议各版本差异及 OID 树状结构的具体应用掌握利用 SNMP 查询接口状态、CPU 利用率等设备信息的方法进而提升对华为交换机远程管理与网络安全的实操能力。 打开电脑里那份断断续续记了半年的血糖记录表时我发现一个问题血糖数据只有零散的几十行根本看不出任何规律复诊时医生扫了一眼就问“平时有没有低血糖”我支支吾吾答不上来。那之后我花了两个晚上做了一个叫 SugarNMSTool 的小工具名字里 NMS 是 No More Sugar 的缩写直译就是“少吃糖工具”。它帮我完成了从血糖仪原始数据、日常饮食备注到一张能直接给医生看的变化趋势图的完整链路。如果你也在做血糖管理或者家里有需要长期记录血糖的长辈这篇文章里的思路、代码和踩坑记录应该能帮你少走不少弯路。1. 血糖记录这件事难在“坚持”而不在“测”1.1 为什么表格总是记三天就断很多人的血糖记录是从一张 Excel 表开始的。第一天测完空腹打开电脑记一下第二天想着“睡醒再补”结果一忙就忘第三天直接放弃了。这不是懒而是录入太繁琐——打开电脑、找到文件、定位到对应日期、填数字、填备注、保存整个流程走下来至少两分钟。两分钟在平时不算什么但放在“测完血糖后手边还有一堆事”的场景里就是致命的打断。我用过一段时间的手机血糖记录 App界面花哨能算各种统计但同样有致命问题数据都在厂商的云端导出格式五花八门有的甚至要手动一句一句复制。家人更是不愿意用因为每次都要解锁手机、点开 App、找到入口、再输入。对于六十多岁的长辈来说这个学习成本太高了。SugarNMSTool 在设计上做了两个核心取舍第一录入方式必须比测血糖本身还快第二数据必须完全掌握在自己手里任何 App 退出服务都不影响数据安全。1.2 设计原则让录入比测血糖还快最终我把录入简化成两种方式。最常用的是直接在 CSV 表格里追加一行因为 CSV 可以用记事本打开也可以用 Excel 打开哪种顺手用哪种。第二是用一个简单的命令行交互式录入输入格式是固定的2024-11-18,7:20,6.8,空腹,早餐牛奶燕麦,无 2024-11-18,9:40,8.1,早餐后2h,无加餐,无一行五个字段分别是日期、时间、血糖值、餐别、备注、用药。刚开始是六个字段后来把“用药”并入“备注”因为很多人长期不吃药空着这个字段反而让人疑惑。实际用下来手输一行也就十秒钟比打开任何 App 都快。这里有一个很重要的设计原则千万别一开始就做复杂的数据库表结构。CSV 文件就是最简单的数据存储它的好处在于可迁移、可复制、可用 Excel 直接打开。数据库虽然查询方便但对家庭场景来说是过度设计出了问题反而难排查。2. 工具的功能设计与数据结构2.1 字段只设五个够用且不乱数据结构设计是所有功能的地基。我在早期版本里设过十几个字段包括运动时长、心情、天气、饮水毫升数最后发现这些字段不仅没有带来分析价值反而成了录入的负担。后来精简到五列每一列都有明确的不可替代作用字段名示例作用日期2024-11-18按天聚合、生成日历视图时间7:20判断空腹/餐后参与时段分布血糖值6.8核心指标单位统一为 mmol/L餐别空腹分组统计的锚点备注早餐牛奶燕麦记录饮食、用药、身体状态等上下文餐别这一列我固定了几个选项空腹、早餐后2h、午餐后2h、晚餐后2h、睡前、随机。之所以不用自由文本输入是因为自由文本必然会出现“早饭前”“上午”“吃完饭”这种无法归类的写法统计的时候就傻眼了。2.2 目录结构与模块划分代码层面SugarNMSTool 采用的是最简单的模块划分SugarNMSTool/ ├── data/ │ └── blood_sugar.csv ├── src/ │ ├── clean.py # 数据清洗与去重 │ ├── stat.py # 统计计算 │ └── plot.py # 图表绘制 ├── output/ │ └── report_202411.html └── run.py # 入口脚本clean.py负责把各种格式不统一的数据整理为标准格式stat.py负责计算平均值、达标率、趋势线这些核心指标plot.py生成可视化图表。程序入口只有 run.py 一个文件用户不需要去改其他代码。2.3 为什么用 CSV 而不是数据库有朋友建议我用 SQLite理由是可以做复杂查询。但在实际使用场景里这个需求完全不存在——一个家庭一天最多产生 4 到 6 条血糖记录一年撑死两千行。如此小的数据量用 SQLite 反而增加了备份和迁移负担。CSV 可以被任何文本编辑器打开能被 Git 做版本管理用户随时可以复制一份发给医生。补充一句用 CSV 还有一个容易被忽略的好处你永远不会被某一种工具绑架。哪怕有一天 SugarNMSTool 的代码全丢了那些 .csv 文件依然可以直接交给任何数据分析工具处理。对长期健康数据管理来说可迁移性比方便性更重要。3. 核心实现从原始数据到一张能“说服医生”的图表3.1 数据清洗把“脏表”恢复成可统计的数据真实世界里的血糖记录永远是脏的。我从家里人手里拿到的第一份表格里日期格式有2024/11/18、2024.11.18、11月18日三种时间有的写7:20有的写7.20还有的写上午7点多。如果直接做统计日期排序会乱套图表横轴也会出现奇怪的断层。所以 clean.py 里最关键的功能是时间解析。我统一的规则是日期只接受YYYY-MM-DD或YYYY/MM/DD两种格式时间只接受HH:MM格式解析失败的数据单独放到data/problems.csv而不是直接删除。这个“保留问题数据而不是丢弃”的习惯帮我避免了很多次数据丢失事故。3.2 血糖分组的隐性逻辑血糖值本身只是一个数字真正有意义的是它处在一个什么样的时间上下文里。同样是 7.0 mmol/L如果出现在清晨空腹那就是一个值得警惕的信号如果出现在餐后两小时那反而是控制得不错的结果。所以统计模块里有一个核心分组逻辑按时间段和餐别把数据分成四类空腹早上起床后、进食前测量参考范围 3.9 - 6.1 mmol/L餐后 2h从第一口饭开始计时参考范围 4.4 - 7.8 mmol/L睡前睡前测量用于发现夜间低血糖风险随机不定时测量仅做参考不做达标率判断值得注意的是这里的参考范围仅用于图表标注不能代替医生诊断。我特意在图表标题里加上“参考范围仅供参考请遵医嘱”这句话避免家里人把一个统计图表当成诊断结果。3.3 报告的三个关键视图SugarNMSTool 生成的 HTML 报告包含三大部分。第一部分是每日血糖曲线横轴是日期纵轴是血糖值画上参考区间的上下限虚线一眼就能看出哪些天超标了。第二部分是按餐别分组的箱线图用来看空腹、餐后 2h 的分布是否有整体上升或下降趋势。第三部分是达标率统计即各分组中落在参考范围内的数据占总数据量的百分比。这三张图各有用途曲线图用来“看过程”箱线图用来“看分布”达标率用来“看结论”。复诊时我把报告导出成 PDF 直接带给医生医生说“这比我看你手机里那些 App 快多了”。3.4 移动平均为什么比单点值更好用单日血糖值波动很大比如某天晚餐吃得晚餐后 2h 血糖到了 9.2第二天同一时间又只有 6.7。这种波动是正常的但在图表上看起来就像过山车很容易造成不必要的焦虑。我加了 7 日移动平均线之后整体趋势清晰了很多。移动平均的算法很简单df[rolling_7day] df[glucose].rolling(window7).mean()窗口取 7 是因为一周的周期能覆盖工作和休息日的生活节奏差异。这个参数不是固定的如果你的作息以 5 天为一个周期也可以改成 5但数据量至少要超过 30 条再谈移动平均否则没有统计意义。4. 实操教程从CSV到能出图的命令行工具4.1 环境准备与依赖安装SugarNMSTool 基于 Python 3.9 开发核心依赖只有三个pandas、matplotlib、jinja2。安装命令很简单pip install pandas matplotlib jinja2不要安装额外的东西依赖越少换电脑跑起来的成本就越低。我在自己另一台不带 GUI 的 Linux 小主机上也跑过没有任何问题。4.2 一个可直接运行的数据处理示例下面这段代码来自早期版本的 run.py展示了从读取 CSV 到输出统计结果的完整流程。我已经精简过注释去掉了很多边界判断只保留主线逻辑import pandas as pd def load_and_clean(file_path): df pd.read_csv(file_path, encodingutf-8) df[datetime] pd.to_datetime( df[日期].astype(str) df[时间].astype(str), format%Y-%m-%d %H:%M, errorscoerce ) df df.dropna(subset[datetime]) df[value] pd.to_numeric(df[血糖值], errorscoerce) df df.dropna(subset[value]) df df.drop_duplicates(subset[datetime, value], keepfirst) return df def daily_summary(df): daily df.groupby(df[datetime].dt.date).agg( 测次(value, count), 平均血糖(value, mean), 最高血糖(value, max), 最低血糖(value, min) ).round(2) return daily if __name__ __main__: df load_and_clean(data/blood_sugar.csv) daily daily_summary(df) print(daily) daily.to_csv(output/daily_summary.csv)运行后在控制台会输出一张按日期汇总的表格同时保存 daily_summary.csv 到 output 目录。这张表就是后续画图和生成报告的数据基础。4.3 图表绘制部分的简化实现数据统计完成后出图的关键思路是“分层绘制”。第一层画原始数据散点第二层画参考区间阴影第三层画 7 日移动平均线import matplotlib.pyplot as plt def plot_trend(df, out_pathoutput/trend.png): fig, ax plt.subplots(figsize(12, 5)) ax.scatter(df[datetime], df[value], s20, alpha0.6) ax.axhspan(3.9, 6.1, colorgreen, alpha0.08) ax.axhspan(6.1, 10.0, coloryellow, alpha0.05) ax.plot(df[datetime], df[rolling_7day], colorred, linewidth2) ax.set_xlabel(日期) ax.set_ylabel(血糖 (mmol/L)) fig.autofmt_xdate() plt.savefig(out_path, dpi150, bbox_inchestight) plt.close(fig)axhspan 用半透明色块标出参考区间这样不管原始散点有多少一眼就能看出哪段时间在区间外。颜色选择上用了最简单的红黄绿语义但透明度都压得很低避免背景色干扰数据本身的显示。4.4 第一次运行必做的三件事第一次把工具跑通后建议立刻做这三件事核对时间解析结果打开 daily_summary.csv 看看日期是否连续核对重复数据处理检查有没有同一条记录被误删检查参考区间年龄段是否匹配糖尿病患者和普通人的控制目标其实不一样要根据医嘱调整。我自己的做法是把参考区间做成一个配置文件 config.json改数值不用动代码{ ref_fasting_min: 3.9, ref_fasting_max: 6.1, ref_postprandial_min: 4.4, ref_postprandial_max: 7.8, rolling_window: 7 }5. 被数据坑过的三次经历5.1 时间格式不统一图表横轴突然变成乱序第一次用 matplotlib 画图的时候我没有做严格的格式转换直接拿 CSV 里的日期字符串当横轴。结果因为有些行写的是2024/11/18有些写的是2024-11-18pandas 在排序时把斜杠格式的当成了无效数据图表横轴直接出现一大段空白。排查了很久才发现问题是同一个 Excel 文件在跨平台编辑时自动改了时间显示格式。解决办法就是所有数据进入统计前必须经过统一的日期解析失败的写进 problem 文件。现在我对任何来源的 CSV 都抱着“一定有问题”的态度去清洗宁可多花五分钟检查也不要让一个问题数据毁掉整张报告。5.2 单位混用导致血糖值“凭空高了一倍”家里有一台老式血糖仪显示单位是 mg/dL而新买的那台显示的是 mmol/L。两种单位之间就差了一个 18 的换算系数如果混在一起用6.5 mmol/L 就会被记成 117 mg/dL整个统计直接失真。这件事发生在数据已经记录了三个星期之后要不是核对原始记录根本发现不了。从那以后我在 CSV 里加了一列“单位”字段默认填 mmol/L导入时统一做换算# mg/dL 转 mmol/L除以 18 if row[单位] mg/dL: row[血糖值] round(row[血糖值] / 18.0, 2)现在我对家人的要求是只用一台血糖仪避免单位混用的根源。如果非要换设备一定要重新建立数据基线。5.3 重复录入造成的“幽灵数据”家庭成员一起维护一份 CSV 时容易出现同一条记录被录了两次的情况。第一次遇到时没发现直到报告里某一天的“测次”显示为 10 次远超正常测量频率才知道出了大问题。去重逻辑里我用了(datetime, value)作为唯一键即同一个时间点测出同一个数值的记录只保留一条。这个方法简单有效但有一个例外如果同一天同一时间真的测了两次且数值一样这种情况极少即使被去重掉了也不会影响整体统计结论。6. 让工具真正跑进家庭日常的三个经验6.1 不要追求功能多要追求“能不能连续记三个月”工具做出来之后最大的敌人不是代码 bug而是使用者的遗忘。家人前两周用得很开心第三周开始慢慢不记了因为每天打开电脑这件事本身就是一个负担。后来我把录入方式改成了在手机上的一个共享文本文件里写一行字手机上随时打开就能写之后再同步回电脑做统计连续记录的天数才慢慢拉长。所以我的建议是宁可功能少也要把录入成本压到最低。如果一天三次测试、每次录入超过 30 秒这个工具就注定会被抛弃。6.2 报告周期要匹配复诊节奏SugarNMSTool 一开始只支持按月生成报告但家里人复诊间隔不是稳定的 30 天有时三个星期就去一次。后来我把报告参数改成接受任意起止日期复诊前一天导出对应时间段的数据就行了。这个改动很小但对实际使用的价值非常大。6.3 数据备份用最简单的同步盘我不推荐搞什么复杂的数据备份方案直接把整个 data 文件夹丢进坚果云或者 OneDrive 同步目录就行。每次录入后同步会自动发生不需要任何额外操作。之所以不用 Git是因为绝大多数家庭成员不了解 Git 概念而同步盘的冲突处理逻辑更接近日常使用习惯。这套工具从去年底跑到现在家里人已经连续记录了四个多月。我每周一看一次周报看到趋势线整体平稳心里就踏实不少。如果你也想做类似的东西不需要照抄代码核心思路就一句话数据要干净整洁、录入要足够快、报告要能在两分钟内看懂。做到这三点这个工具就能真正活进日常生活里。本文还有配套的精品资源点击获取
返回列表