ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Python图书馆借阅数据分析实战:从2014-2017流水到主题词与帕累托

Python图书馆借阅数据分析实战:从2014-2017流水到主题词与帕累托 简介这份资源面向具备一定Python基础、希望上手真实数据分析项目的高校学生与数据挖掘初学者围绕图书馆借阅场景提供一套从数据到结论的完整实现方案。压缩包共16个文件约46.45MB其中7个xlsx为2014至2017年图书借还、图书目录与读者信息等原始数据4个py脚本分别完成主题词提取、帕累托分析、热门书分析与排名变化计算另有3个txt提供停用词、图书馆新词及《中国图书馆图书分类法》简表等辅助语料并附readme说明与一张背景掩码图。目前已有2275人学习下载。读者可据此复现借书名TOP20排名变化、热门图书分布与帕累托图等分析结果理解文本分词、词频统计与可视化在图书情报领域的落地方式同时获得可复用的数据清洗与脚本组织思路适合作为课程设计、毕业设计或数据分析练手项目的参考。1. 从一份 2014–2017 借阅流水说起这套 Python 分析包到底能干什么如果你手头正好有一批图书馆借还日志却只会用 Excel 拉透视表那这套资源值得花一个下午拆开看。它是一份基于 Python 的图书馆借阅数据分析设计与实现核心数据是 2014 到 2017 四年的图书借还流水配套图书目录、读者信息、中图法简表、停用词表以及四个已经写好的分析脚本提取主题词、生成帕累托、热门书分析、排名变化。换句话说它不是空壳论文而是把“数据清洗—主题提取—借阅热度—长尾分布—排名演化”这条链路用可运行的 Python 代码串了起来。适合谁一是做数据分析入门项目、需要真实业务数据练手的人二是图书馆或档案室的技术岗想快速把借阅日志变成可解释的指标三是写课程设计或毕业设计需要一套结构完整、数据自洽的参考实现。它解决的不是“从零爬数据”而是“数据已经躺在 Excel 里怎么用 Python 把它讲成一个有结论的故事”。下面按“资源结构—环境与数据—脚本拆解—避坑—进阶”的顺序把这份包拆到能直接复现的程度。2. 资源结构与数据字典先认清每个文件在链路里的位置2.1 目录里到底有什么哪些是原料哪些是产物拿到压缩包后先别急着跑脚本。把文件按角色分三类后面排错会快很多。第一类是原始数据图书借还2014.xlsx到图书借还2017.xlsx四个年度流水图书目录.xlsx是书目主数据读者信息.xlsx是读者维度表。第二类是辅助字典《中国图书馆图书分类法》简表.txt用来把分类号映射到学科大类stopwords.txt和library_new_words.txt分别服务分词停用和自定义词典。第三类是脚本与产物四个图书馆大数据分析_*.py是分析入口借书名TOP202014-2017排名变化.xlsx是排名变化脚本的输出示例背景_掩码.png一般用于词云或可视化底图。这里有个容易忽略的点data目录和根目录下的 xlsx 可能重复。我一般先确认脚本里读的是哪个路径再决定保留哪一份避免改了 A 文件、脚本读的却是 B 文件最后结论对不上。文件角色关键字段/用途图书借还2014–2017.xlsx原始流水借书时间、还书时间、图书条码、读者证号图书目录.xlsx书目主数据书名、分类号、ISBN、作者读者信息.xlsx读者维度读者类型、单位、性别等中图法简表.txt分类字典分类号到学科大类的映射stopwords.txt分词停用过滤无意义高频词library_new_words.txt自定义词典保证专业书名不被切碎四个分析脚本计算入口主题词、帕累托、热门书、排名变化2.2 数据字段与关联键借还流水怎么和书目、读者接上借阅分析能不能做深取决于三张表能不能关联。常见做法是借还流水里的“图书条码”或“书名”去关联图书目录.xlsx拿到分类号再用“读者证号”关联读者信息.xlsx拿到读者类型。如果流水里只有书名没有条码就得用书名做模糊匹配这一步是后面最大的坑之一。先做一次字段体检用 pandas 把四年的流水读进来看列名是否一致、有没有合并单元格导致的表头错位。下面这段代码我一般放在任何分析之前跑一遍import pandas as pd import os # 四个年度流水统一读取先看结构再谈分析 years [2014, 2015, 2016, 2017] frames [] for y in years: path f图书借还{y}.xlsx df pd.read_excel(path) df[年份] y print(y, df.shape, list(df.columns)) frames.append(df) all_loan pd.concat(frames, ignore_indexTrue) print(合并后总记录数, len(all_loan)) print(all_loan.head())逻辑说明先按年读取而不是一次性读是为了定位某一年表头异常加“年份”列是为了后面做跨年对比。参数上pd.read_excel默认读第一个 sheet如果实际数据在第二个 sheet要显式传sheet_name。pd.concat用ignore_indexTrue重置索引避免四年索引重复导致后续loc取值混乱。提示如果某一年读出来列名是Unnamed: 0之类多半是原表有合并标题行用header1或先手工清理表头不要硬跑。2.3 环境准备Python 版本与依赖库怎么选这套脚本依赖的核心库是 pandas、openpyxl、jieba、matplotlib可能还有 wordcloud。Python 建议 3.8 以上pandas 1.x 和 2.x 在read_excel行为上略有差异如果脚本里用了append这类已废弃方法在 2.x 会直接报错。我一般用虚拟环境隔离python -m venv venv # Windows venv\Scripts\activate # macOS / Linux source venv/bin/activate pip install pandas openpyxl jieba matplotlib wordcloud参数说明openpyxl是 pandas 读写 xlsx 的引擎不装会在read_excel时报缺少引擎jieba负责中文分词主题词脚本离不开它wordcloud只有做词云可视化时才需要。如果安装wordcloud编译失败常见做法是换用预编译 wheel 或先跳过词云、只跑统计部分。3. 四个脚本逐个拆主题词、帕累托、热门书、排名变化怎么跑3.1 主题词提取jieba 分词加自定义词典的完整流程图书馆大数据分析_提取主题词.py的目标是从书名里抽出高频主题词回答“这几年读者到底在借什么方向的书”。中文书名分词最大的问题是专业词被切碎比如“中国图书馆图书分类法”可能被切成“中国”“图书馆”“图书”“分类法”。所以脚本里配了library_new_words.txt用jieba.load_userdict加载自定义词典再用stopwords.txt过滤“的”“研究”“上册”这类无意义词。import jieba import pandas as pd from collections import Counter # 加载自定义词典和停用词 jieba.load_userdict(library_new_words.txt) with open(stopwords.txt, encodingutf-8) as f: stopwords set(line.strip() for line in f if line.strip()) books pd.read_excel(图书目录.xlsx) # 假设书名列名为“书名”按实际列名调整 titles books[书名].dropna().astype(str) word_counter Counter() for title in titles: words jieba.lcut(title) for w in words: w w.strip() # 过滤停用词、单字和纯数字 if len(w) 1 and w not in stopwords and not w.isdigit(): word_counter[w] 1 top_words word_counter.most_common(50) for word, cnt in top_words: print(word, cnt)逻辑说明load_userdict必须在lcut之前调用否则自定义词不生效停用词用集合而不是列表是为了把查找复杂度从 O(n) 降到 O(1)。参数上len(w) 1过滤单字是因为单字主题词信息量太低most_common(50)取前 50实际写报告时可以按需调整。如果发现高频词里全是“上册”“下册”“第二版”说明停用词表没覆盖到往stopwords.txt里补即可。3.2 帕累托分析验证借阅是否服从二八分布图书馆大数据分析_生成帕累托.py要回答的是是不是 20% 的书贡献了 80% 的借阅量。这是图书馆采购和排架最关心的结论之一。做法是按书名或条码统计借阅次数降序排列算累计占比再画帕累托图。import pandas as pd import matplotlib.pyplot as plt all_loan pd.concat( [pd.read_excel(f图书借还{y}.xlsx).assign(年份y) for y in [2014, 2015, 2016, 2017]], ignore_indexTrue ) # 按书名统计借阅次数按实际列名调整 loan_count all_loan[书名].value_counts().reset_index() loan_count.columns [书名, 借阅次数] loan_count loan_count.sort_values(借阅次数, ascendingFalse) # 计算累计占比 loan_count[累计次数] loan_count[借阅次数].cumsum() loan_count[累计占比] loan_count[累计次数] / loan_count[借阅次数].sum() loan_count[书目占比] range(1, len(loan_count) 1) loan_count[书目占比] loan_count[书目占比] / len(loan_count) # 找累计占比首次超过 80% 的位置 key_point loan_count[loan_count[累计占比] 0.8].iloc[0] print(贡献 80% 借阅量所需书目占比, round(key_point[书目占比] * 100, 2), %) fig, ax1 plt.subplots(figsize(10, 6)) ax1.bar(range(len(loan_count)), loan_count[借阅次数]) ax1.set_xlabel(图书排名) ax1.set_ylabel(借阅次数) ax2 ax1.twinx() ax2.plot(range(len(loan_count)), loan_count[累计占比], colorred) ax2.set_ylabel(累计占比) plt.title(图书借阅帕累托图) plt.show()逻辑说明value_counts默认降序但显式sort_values更稳累计占比用cumsum除以总和避免手工循环。参数上 0.8是帕累托的经典阈值也可以改成 0.7 或 0.9 看敏感度。如果key_point取不到说明数据里书目太少或借阅太均匀这时候结论要谨慎不能硬套二八定律。3.3 热门书分析TOP N 榜单与年度对比图书馆大数据分析_热门书分析.py输出的是各年度借阅 TOP N。这里的关键不是排序本身而是处理并列名次和跨年书名不一致。常见做法是先按年份分组再在组内value_counts取前 N。all_loan pd.concat( [pd.read_excel(f图书借还{y}.xlsx).assign(年份y) for y in [2014, 2015, 2016, 2017]], ignore_indexTrue ) top_n 20 for y, group in all_loan.groupby(年份): top_books group[书名].value_counts().head(top_n) print(f\n{y} 年借阅 TOP{top_n}) for i, (book, cnt) in enumerate(top_books.items(), 1): print(i, book, cnt)逻辑说明groupby(年份)后组内统计保证榜单是年度独立的head(top_n)取前 Ntop_n可按报告需要改成 10 或 50。参数上如果书名有空格或全半角差异先做str.strip()和统一全半角否则同一本书会被拆成两条。这一步不做榜单会出现“同名两行”的玄学现象。3.4 排名变化2014–2017 名次迁移怎么算才不误导图书馆大数据分析_排名变化.py对应产物是借书名TOP202014-2017排名变化.xlsx。它的价值在于看一本书是“持续热门”还是“昙花一现”。做法是每年算一次排名再把四年排名拼成一张宽表算名次差值。all_loan pd.concat( [pd.read_excel(f图书借还{y}.xlsx).assign(年份y) for y in [2014, 2015, 2016, 2017]], ignore_indexTrue ) rank_by_year {} for y, group in all_loan.groupby(年份): vc group[书名].value_counts() rank_by_year[y] vc.rank(methodmin, ascendingFalse) rank_df pd.DataFrame(rank_by_year) # 只保留至少一年进入前 20 的书 top20_mask (rank_df 20).any(axis1) rank_df rank_df[top20_mask] rank_df[名次变化] rank_df[2014] - rank_df[2017] rank_df.to_excel(借书名TOP202014-2017排名变化.xlsx) print(rank_df.sort_values(名次变化, ascendingFalse).head(10))逻辑说明rank(methodmin)处理并列名次避免跳号名次变化 2014 排名 - 2017 排名正值表示名次上升数字变小。参数上(rank_df 20).any(axis1)保证只要有一年进过前 20 就保留避免漏掉新晋热门书。如果某年数据缺失该列会是 NaN差值计算前要先决定是填充还是剔除。4. 避坑与排查跑这套脚本最容易翻车的五个地方4.1 现象read_excel报缺少引擎或读出来全是 NaN原因通常是没装openpyxl或者 xlsx 实际是 xls 格式、甚至是被改过后缀的 csv。解决先pip install openpyxl再用pd.read_excel(path, engineopenpyxl)显式指定如果仍失败用file命令或 Excel 另存为确认真实格式。读出来全是 NaN多半是header行号不对试着传header1或先看前几行。4.2 现象分词结果里专业词被切碎主题词全是碎片原因是library_new_words.txt没加载或加载顺序在lcut之后。解决确保jieba.load_userdict在第一次分词前调用检查词典文件编码是 UTF-8如果某个词仍被切碎把它单独加进词典并重启内核。另一个隐蔽原因是词典里一行有多个词用空格分隔jieba 要求每行一个词或“词 词频 词性”格式。4.3 现象帕累托累计占比超过 1 或曲线不单调原因是借阅次数里有负数或空值或者cumsum前没排序。解决先loan_count loan_count[loan_count[借阅次数] 0]再排序、再累计。如果数据里有退书记录导致负值要明确业务口径退书算不算借阅算的话取绝对值还是单独剔除这个决定要在报告里写清楚。4.4 现象跨年榜单里同一本书出现两次原因是书名存在全半角、空格、括号差异比如“Python编程 从入门到实践”和“Python编程从入门到实践”。解决统计前统一做str.replace( , ).str.replace(, :)之类的规范化或者改用 ISBN/条码做关联键。用书名做键永远有歧义能拿到条码就别用书名。4.5 现象排名变化表里名次差值是 NaN 或大得离谱原因是某年该书没有借阅记录排名为 NaN相减后仍是 NaN或者并列名次处理方式不一致导致跳号。解决对缺失年份的排名填充一个“最大排名 1”的哨兵值再算差值并列名次统一用methodmin。差值大得离谱通常是哨兵值选得太大报告里要注明“未进榜”和“排名下降”是两回事。5. 进阶玩法把四年流水做成可复用的分析模板跑通四个脚本只是起点。真正让这套资源产生复利的是把它抽象成“年度更新一次”的模板。我的习惯是加一个config.py把年份列表、文件路径、TOP N、帕累托阈值全部参数化这样明年拿到图书借还2018.xlsx只需改一行配置。# config.py YEARS [2014, 2015, 2016, 2017] LOAN_FILE 图书借还{y}.xlsx BOOK_FILE 图书目录.xlsx READER_FILE 读者信息.xlsx TOP_N 20 PARETO_THRESHOLD 0.8然后在各脚本里from config import *把硬编码的年份和路径替换掉。参数说明PARETO_THRESHOLD单独抽出来是为了做敏感度分析时不用改业务代码TOP_N抽出来是为了同一套逻辑既能出 10 本榜单也能出 50 本榜单。再进一步可以把“借阅次数”升级成“借阅时长”。流水里同时有借书时间和还书时间两者相减得到持有时长能区分“借了没看”和“反复续借”。常见做法是all_loan[借书时间] pd.to_datetime(all_loan[借书时间]) all_loan[还书时间] pd.to_datetime(all_loan[还书时间]) all_loan[持有时长] (all_loan[还书时间] - all_loan[借书时间]).dt.days # 过滤异常值负数和超过 365 天的记录 valid all_loan[(all_loan[持有时长] 0) (all_loan[持有时长] 365)] print(valid.groupby(年份)[持有时长].describe())逻辑说明pd.to_datetime把字符串转成时间类型才能相减.dt.days取整数天。参数上 365是经验阈值超过一年的记录多半是数据录入错误或长期未还直接纳入均值会拉偏结论。这一步做完热门书榜单就能从“借得最多”细化到“看得最久”对采购建议更有说服力。最后一个技巧是验证。任何结论出来前我都会做一次“总数对账”四年流水总记录数应该等于各年记录数之和按书名统计的借阅次数总和应该等于有效流水条数。对不上就说明中间有过滤或去重吃掉了数据。从那以后我每次跑完分析都强制走一遍总数对账宁可多花五分钟也不让报告里出现对不上的数字。希望帮到你。本文还有配套的精品资源点击获取
返回列表