从泰迪杯国二到实战:一份特医食品数据分析的完整代码与思路复盘

从泰迪杯国二到实战:一份特医食品数据分析的完整代码与思路复盘 1. 从竞赛到实战特医食品数据分析全流程解析第一次参加泰迪杯数据分析比赛就拿到国二说实话我自己都没想到。当时我们团队三个人两个队友负责文档撰写我主要负责代码实现。八小时的比赛时间我们花了六小时完成全部题目最终在1600多支队伍中脱颖而出。现在回想起来这次经历给我最大的收获不是奖项本身而是把竞赛中的解题思路转化为实际项目的能力。特医食品数据分析这个题目很有意思它模拟了一个真实的医疗健康数据场景。182款特医食品的PDF说明书就是真实世界中的数据源——格式不统一、内容杂乱、存在各种异常情况。这和我们在实际工作中遇到的数据清洗问题如出一辙。整个项目流程可以分为三个关键阶段数据提取与清洗从五花八门的PDF中提取结构化数据数据分析与可视化发现数据中的规律和趋势推荐系统构建将分析结果转化为实际应用下面我就结合比赛代码详细复盘每个环节的技术实现和踩过的坑。这些经验不仅适用于竞赛对实际工作中的数据分析项目同样有参考价值。2. PDF数据提取的实战技巧2.1 处理多格式PDF表格特医食品说明书的PDF简直就是数据工程师的噩梦。我打开文件时就傻眼了——同样的营养成分表竟然有六种不同的表头格式营养成分 每100mL 每100kJ 营养成分 每100g 每100mL 每100kJ 营养成分 每100g 每100kJ 每份 ...更坑的是有些表格跨页显示导致同一份表格里出现重复表头。针对这种情况我设计了一个分步处理的方案先用pdfplumber提取原始文本通过【营养成分表】和【配方特点/营养学特征】定位目标内容根据表头类型选择不同的解析策略关键代码如下def cal2(name): s text_all[name] s_sons s.split(【配方特点/营养学特征】)[0].split(【营养成分表】)[1].split(\n) re_text [能量(kJ), 脂肪(g), 碳水化合物(g), 蛋白质, 钠, 氯, 钾, 磷] if s_sons[1]营养成分 每100mL 每100kJ: # 处理第一种表头格式 for i in re_text: for j in [x for x in s_sons if x ! 营养成分 每100mL 每100kJ]: if i in j: ret[i]str(j.replace(营养成分 每100mL 每100kJ,).strip().split( )[-1]) # 其他表头格式处理...2.2 异常数据处理的三个原则在实际提取过程中我总结了处理异常数据的三个经验预设多种格式提前分析可能出现的所有数据格式为每种情况编写处理逻辑设置默认值对缺失数据用0或空字符串填充避免后续计算报错保留原始信息在清洗数据的同时保留原始字段方便后期校验比如处理营养成分单位时有些数据用-表示缺失我统一替换为0data data.replace(-, 0) data1 data[蛋白质(g)].astype(float)3. 数据分析与可视化的关键发现3.1 国产特医食品的市场趋势通过分析登记年份和产品来源的数据我发现几个有趣的现象国产产品获批量从2017年到2023年整体呈上升趋势进口产品在2019年后明显减少2023年国产产品出现爆发式增长用双折线图可以清晰展示这个趋势plt.plot(result.index, result[国产产品], colorb, linestyle-, markero, label国产产品, linewidth2, markersize10) plt.plot(result.index, result[进口产品], colorg, linestyle--, marker*, label进口产品, linewidth1, markersize12)![国产与进口特医食品获批量趋势对比]这个发现对市场决策很有价值——国产特医食品正在快速占领市场进口产品的市场份额在不断萎缩。3.2 产品类别的分布特征使用旭日图分析产品类别和适用人群的关系时我发现72%的产品针对1岁以上人群特医婴配食品中国产和进口比例接近15% vs 13%全营养配方食品占比最高这些洞察可以帮助企业更好地定位产品方向fig px.sunburst(df, path[适用人群类别, 产品来源], values登记年份, color适用人群类别)![产品类别旭日图]4. 构建实用的推荐系统4.1 从文本相似度到智能推荐最初我考虑过协同过滤算法但数据特征不适合。最终选择基于TF-IDF和余弦相似度的方案合并产品所有信息为一个文本字段计算用户需求与产品描述的相似度返回相似度最高的产品作为推荐结果核心算法实现def recommend_products(input_text, tfidf_vectorizer, tfidf_matrix, data): input_tfidf tfidf_vectorizer.transform([input_text]) similarity cosine_similarity(input_tfidf, tfidf_matrix) top_indices np.argsort(-similarity.flatten())[:3] return data.iloc[top_indices]4.2 用PyQt打造用户界面为了让推荐系统更易用我开发了一个简单的GUI界面class App(QWidget): def __init__(self): super().__init__() self.setWindowTitle(特医食品推荐系统) self.setGeometry(100, 100, 1000, 700) # 创建输入框、按钮和结果显示区域 self.customer需求的描述_input QLineEdit(self) self.recommend_button QPushButton(推荐, self) self.recommendation_table QTableView(self)![推荐系统界面截图]实测发现用户输入的需求越详细推荐准确度越高。比如婴儿、蛋白质过敏 → 推荐水解蛋白配方10岁儿童、需要补充蛋白质、乳糖不耐受 → 推荐无乳糖高蛋白产品5. 经验总结与实用建议通过这个项目我深刻体会到数据分析的完整链路从原始数据提取到清洗转换再到可视化分析和应用落地。有几个特别实用的经验想分享PDF处理要先做格式调研提前分析所有可能的格式变化设计对应的解析方案可视化要讲好故事选择能突出关键发现的图表类型比如用旭日图展示层级关系推荐系统要结合实际场景不是所有问题都需要复杂算法有时文本相似度就能解决代码实现上最大的教训是异常处理。最初我低估了PDF格式的复杂性导致中途不得不重构代码。现在我会建议为每种异常情况编写单元测试使用try-except捕获意外错误保留原始数据用于校验这个项目中的所有代码和数据集我都整理好了如果需要可以参考完整实现。最重要的是这种从竞赛到实战的思维转换让我在后来的工作中受益匪浅——每次面对新项目我都会先思考这个问题的本质是什么有哪些现成的解决方案可以借鉴如何设计最简单有效的实现方案