课程小作业

张开发
2026/4/20 4:31:25 15 分钟阅读

分享文章

课程小作业
准备工作你需要安装以下第三方库。在命令行CMD或Terminal中运行pip install pandas matplotlib pyecharts jieba wordcloud snownlp openpyxlPython 代码实现请将你的 Excel 文件命名为 student_info.xls 并与代码放在同一目录下。注意由于我无法直接读取你的本地文件以下代码中我添加了“模拟数据”的逻辑。如果你的 Excel 文件列名与代码中不一致例如“籍贯”写成了“生源地”请修改代码中的列名。import pandas as pdimport jiebafrom collections import Counterfrom snownlp import SnowNLPfrom pyecharts.charts import Pie, Bar, Map, WordCloud, Line, Graph, Scatterfrom pyecharts import options as optsimport random--- 1. 数据读取与预处理 ---def load_data():try:# 读取Excel文件df pd.read_excel(student_info.xls)print(✅ 成功读取 student_info.xls)except FileNotFoundError:print(⚠️ 未找到文件正在生成模拟数据用于演示...)# 模拟数据如果没有文件程序不会报错会生成假数据data {姓名: [f学生{i} for i in range(1, 41)],性别: [男, 女, 男, 女, 男] * 8,籍贯: [山东省, 山东省, 河南省, 江苏省, 山东省, 河北省, 山东省, 安徽省, 河南省, 江苏省] * 4,城市: [济南, 青岛, 郑州, 南京, 烟台, 石家庄, 临沂, 合肥, 开封, 苏州] * 4,签名: [开心每一天, 努力奋斗, 躺平, 好好学习, 无, 未来可期, 厚德载物, 自强不息, 爱吃火锅, 喜欢篮球] * 4,生日: [2004-03-12, 2004-05-23, 2003-11-02, 2004-01-15, 2004-07-30] * 8,# 假设Excel里没有成绩和宿舍我们在代码里模拟生成成绩: [random.randint(60, 100) for _ in range(40)],宿舍: [f{i//4 1}0{i%4 1} for i in range(40)]}df pd.DataFrame(data)return dfdf load_data()统一列名方便后续处理如果Excel列名不同请在这里修改假设Excel列名为姓名, 性别, 籍贯, 城市, 签名, 生日如果没有成绩和宿舍列我们刚才模拟生成了--- 2. 可视化函数定义 ---def plot_gender_pie(df):data df[性别].value_counts().items()pie (Pie().add(, data).set_global_opts(title_optsopts.TitleOpts(title班级性别比例)).set_series_opts(label_optsopts.LabelOpts(formatter{b}: {c}人 ({d}%))))pie.render(性别饼状图.html)print(✅ 生成性别饼状图.html)def plot_province_map(df):# 统计籍贯数量去掉省或市字适配地图名称province_data df[籍贯].apply(lambda x: x.replace(省, ).replace(市, )).value_counts().items()map_chart (Map().add(生源分布, province_data, china).set_global_opts(title_optsopts.TitleOpts(title学生籍贯分布),visualmap_optsopts.VisualMapOpts(max_max([i[1] for i in province_data]))))map_chart.render(籍贯地图.html)print(✅ 生成籍贯地图.html)def plot_city_bar(df):# 取前10个城市city_data df[城市].value_counts().head(10)bar (Bar().add_xaxis(city_data.index.tolist()).add_yaxis(人数, city_data.values.tolist()).set_global_opts(title_optsopts.TitleOpts(title学生来源城市TOP10)))bar.render(城市柱状图.html)print(✅ 生成城市柱状图.html)def plot_signature_wordcloud(df):# 简单的分词处理text .join(jieba.lcut( .join(df[签名].dropna().tolist())))words Counter(text.split())# 过滤掉单字和无意义的词data [(word, count) for word, count in words.items() if len(word) 1 and word not in [的, 了, 是, 我, 有, 和]]wc (WordCloud().add(, data, word_size_range[20, 100]).set_global_opts(title_optsopts.TitleOpts(title个性签名词云)))wc.render(签名词云.html)print(✅ 生成签名词云.html)# 情感分析拓展sentiments df[签名].apply(lambda x: SnowNLP(str(x)).sentiments if x else 0.5)avg_score sentiments.mean()print(f 签名情感分析平均情感得分 {avg_score:.2f} (0为消极, 1为积极))def plot_score_line(df):# 按成绩排序后画折线图展示分布趋势sorted_df df.sort_values(by成绩)line (Line().add_xaxis(sorted_df[姓名].tolist()).add_yaxis(成绩, sorted_df[成绩].tolist(), is_smoothTrue).set_global_opts(title_optsopts.TitleOpts(title学生成绩分布),xaxis_optsopts.AxisOpts(axislabel_opts{rotate:45})))line.render(成绩分布折线图.html)print(✅ 生成成绩分布折线图.html)def plot_dormitory_graph(df):# 宿舍关系图节点是学生连线表示同宿舍nodes []links []# 添加学生节点for index, row in df.iterrows():nodes.append({name: row[姓名], symbolSize: 20, category: row[性别]})# 简单的宿舍关联同一宿舍的学生互相连接这里为了图不乱只连接宿舍内前两人演示实际可用力导向图# 更好的方式是把宿舍作为中心节点学生连接宿舍dorm_groups df.groupby(宿舍)for dorm_name, group in dorm_groups:# 添加宿舍节点nodes.append({name: dorm_name, symbolSize: 50, category: 宿舍})# 学生连接宿舍for student_name in group[姓名]:links.append({source: student_name, target: dorm_name})categories [{name: 男}, {name: 女}, {name: 宿舍}]graph (Graph().add(, nodes, links, categoriescategories, repulsion8000, edge_symbol[none, arrow]).set_global_opts(title_optsopts.TitleOpts(title宿舍分布关系图)))graph.render(宿舍关系图.html)print(✅ 生成宿舍关系图.html)def plot_birthday_scatter(df):# 将生日转换为 月-日 格式并映射到坐标轴# X轴月份(1-12)Y轴日期(1-31)df[生日] pd.to_datetime(df[生日])months df[生日].dt.monthdays df[生日].dt.dayscatter (Scatter().add_xaxis(months.tolist()).add_yaxis(日期, days.tolist()).set_global_opts(title_optsopts.TitleOpts(title生日分布散点图),xaxis_optsopts.AxisOpts(name月份, min_1, max_12),yaxis_optsopts.AxisOpts(name日期, min_1, max_31)))scatter.render(生日散点图.html)print(✅ 生成生日散点图.html)--- 3. 执行分析 ---if name main:plot_gender_pie(df)plot_province_map(df)plot_city_bar(df)plot_signature_wordcloud(df)plot_score_line(df)plot_dormitory_graph(df)plot_birthday_scatter(df)数据分析报告与建议根据上述代码生成的可视化结果我们可以得出以下结论并提出建议1. 生源分析与招生建议* 现象通过籍贯地图和城市柱状图我们可以清晰地看到班级学生主要集中在哪些省份例如山东省。* 建议* 精准投放建议招生部门在生源大省如山东、河南加大宣传力度巩固优势。* 开拓市场对于地图上颜色较浅或无数据的省份可以分析是因为知名度不够还是录取分数门槛问题考虑是否需要制定针对性的跨省招生政策优化生源地理结构的多样性。2. 签名情感分析* 现象代码中使用了 SnowNLP 库对签名进行了情感极性分析。* 结果如果平均分接近 1说明班级整体氛围积极向上如果分数较低可能部分学生处于迷茫或消极状态。* 建议辅导员可以关注情感得分较低的同学进行心理疏导或谈心帮助其调整状态。3. 建议增加的学生属性为了让分析更全面建议在信息表中添加以下字段* 兴趣爱好标签化如“篮球”、“编程”、“阅读”。* 用途可以用于构建班级兴趣社群组织更有针对性的团建活动。* 高考成绩/生源地排名* 用途分析生源质量与大学成绩的相关性判断学生是否存在“高分低能”或“后劲不足”的现象。* 性格类型如MBTI* 用途在宿舍分配时可以考虑性格互补或相投减少宿舍矛盾在组建学习小组时也能更科学地搭配。* 家庭经济状况/生源地性质城市/农村* 用途帮助辅导员更精准地进行贫困生资助和学业帮扶。案例二:这是一份基于吴迪老师微信好友数据的深度分析与可视化教程。第一步环境准备与数据读取首先我们需要读取CSV文件并对数据进行清洗特别是处理缺失值和匿名用户。import pandas as pdimport refrom snownlp import SnowNLPfrom pyecharts.charts import Pie, Map, Geo, WordCloud, Liquidfrom pyecharts import options as optsfrom pyecharts.globals import ThemeTypeimport jiebafrom collections import Counter1. 读取数据假设文件名为 weixin_friends.csvdf pd.read_csv(我的微信好友信息.csv, encodingutf-8)2. 数据清洗过滤掉系统账号如附近的人、群聊等这里根据NickName判断df df[~df[NickName].str.contains(附近的人|漂流瓶|微信团队|文件传输助手, naFalse)]print(原始数据形状:, df.shape)print(前几行数据预览:n, df.head())第二步可视化图表生成我们将逐一完成题目要求的图表。1. 性别比例饼状图def gender_pie(data):# 映射性别数字到文字sex_map {1: 男, 2: 女, 0: 未知}data[SexText] data[Sex].map(sex_map)sex_count data[SexText].value_counts()pie (Pie(init_optsopts.InitOpts(themeThemeType.LIGHT, width800px, height500px)).add(, [list(z) for z in zip(sex_count.index, sex_count.values)]).set_global_opts(title_optsopts.TitleOpts(title吴迪老师微信好友性别分布)).set_series_opts(label_optsopts.LabelOpts(formatter{b}: {c}人 ({d}%))))pie.render(gender_pie.html)return piegender_pie(df)2. 省份分布中国地图def province_map(data):# 统计省份频次# 注意数据中Province列包含黑龙江、山东等但也有空值province_stat data[Province].value_counts().reset_index()province_stat.columns [Province, Count]map_chart (Map().add(好友数量, [list(z) for z in zip(province_stat[Province], province_stat[Count])], china)1.set_global_opts(title_optsopts.TitleOpts(title好友籍贯/所在地省份分布),visualmap_optsopts.VisualMapOpts(max_province_stat[Count].max()),))map_chart.render(province_map.html)return map_chartprovince_map(df)3. 城市地理信息图 (Geo)由于数据中大量城市集中在“齐齐哈尔”我们将重点展示黑龙江省或具体的城市点位。def city_geo(data):# 过滤掉城市为空的数据city_data data[data[City].notna() (data[City] ! )]city_stat city_data[City].value_counts().reset_index()city_stat.columns [City, Count]# 由于数据量小且集中我们使用散点图模式geo (Geo().add_schema(maptypechina)# 添加城市点.add(城市分布,[list(z) for z in zip(city_stat[City], city_stat[Count])],type_effectScatter, # 涟漪特效symbol_size10).set_series_opts(label_optsopts.LabelOpts(is_showFalse)).set_global_opts(title_optsopts.TitleOpts(title好友所在城市分布)))geo.render(city_geo.html)return geocity_geo(df)4. 签名情感分析与词云这里我们结合 SnowNLP 进行情感得分计算并生成词云。def signature_analysis(data):# 过滤掉签名为空的数据sig_data data[data[Signature].notna() (data[Signature] ! )]# 1. 情感极性分类def get_sentiment(text):try:s SnowNLP(text)return s.sentiments # 返回0-1的数值except:return 0.5sig_data[Sentiment] sig_data[Signature].apply(get_sentiment)# 简单分类积极(0.6), 中立(0.4-0.6), 消极( 1 and word.isalpha()]counter Counter(words)wordcloud_data [(k, v) for k, v in counter.most_common(50)]wc (WordCloud().add(, wordcloud_data, word_size_range[20, 100]).set_global_opts(title_optsopts.TitleOpts(title好友签名词云)))wc.render(signature_wordcloud.html)return wcsignature_analysis(df)5. 昵称广告统计 (水滴图)我们通过关键词如电话号码、微信号、公司名来判断是否为广告。def ad_lucky(data):# 简单的广告检测逻辑def is_ad(nickname, signature):text str(nickname) str(signature)# 检查是否包含手机号11位数字或常见广告词phone_pattern r1[3-9]d{9}|d{8,}if re.search(phone_pattern, text) or 微信 in text or 营销 in text or 推广 in text:return Truereturn Falsead_count 0for _, row in data.iterrows():if is_ad(row[NickName], row[Signature]):ad_count 1ad_ratio ad_count / len(data)# 水滴图 (Liquid)liquid (Liquid().add(广告占比, [ad_ratio, ad_ratio]).set_global_opts(title_optsopts.TitleOpts(titlef好友昵称/签名含广告概率: {ad_ratio:.2%})))liquid.render(ad_liquid.html)return liquidad_lucky(df)第三步分析结论与洞察运行上述代码后结合数据内容我们可以得出以下结论1. 判断吴迪老师的工作地点结论吴迪老师极大概率在黑龙江省齐齐哈尔市工作。数据支撑* 地域高度集中在98位好友中除去系统账号和未填写信息的绝大多数手动填写的城市信息都指向“齐齐哈尔”。* 职业线索* 数据中出现了 汇智机器人、开锁茂林、亲民农业 等具有明显地域特征的商业或教育机构名称。* 出现了 大学计算机、SPOC课程 等教育行业关键词。* 推断吴迪老师很可能在齐齐哈尔的一所高校如齐齐哈尔大学或齐齐哈尔工程学院担任计算机或相关课程的教师同时可能涉及机器人教育或编程培训因为其好友圈涵盖了大量本地教育机构如机器人老师、绘本馆长和学生/家长。2. 签名情感分析结果* 整体情绪从生成的词云和情感得分来看吴迪老师的好友圈整体情绪偏向中立与积极。* 关键词词云中高频词如“快乐”、“相信自己”、“正能量”、“随缘”表明这是一个心态较为平和、注重生活品质的社交圈。* 特殊群体数据中存在部分营销号如“财富管家”、“家庭保障规划”其签名往往带有强烈的营销色彩“平安”、“快乐”、“专业”这属于商业积极情绪。第四步拓展分析建议除了题目要求的数据结合这份样本我建议还可以分析以下维度1. 职业/身份标签聚类* 分析点通过 NickName 和 Signature 提取职业如“老师”、“校长”、“财务”、“机器人”。* 目的构建吴迪老师的“社会关系网络图”看他的人脉是偏重学术界、商业界还是学生群体。2. 手机号/微信号特征分析* 分析点从 Signature 或 NickName 中提取手机号。* 目的分析运营商分布移动/联通/电信或者通过手机号前三位判断是否为黑龙江本地号段这可以验证“本地生活圈”的紧密程度。3. 微信昵称风格分析* 分析点区分昵称是“真名”如吴振江、“网名”如沧海惊涛、还是“职务名”如BOOK亲子绘本馆馆长。* 目的判断吴迪老师社交的正式程度。数据显示其好友中有大量“职务名”说明这是一个工作属性很强的微信号工作号。4. 头像识别分析 (腾讯云)* 操作正如你所提到的可以下载头像使用腾讯云的人脸检测或图像标签 API。* 分析统计头像类型真人自拍、宠物、风景、动漫、Logo。如果大量头像是Logo或风景说明这是一个“弱关系”或“营销号”居多的圈子。关于腾讯云人脸识别的补充说明要实现“好友人脸头像识别”你需要1. 导出头像使用itchat或通过微信网页版API获取好友头像图片并保存到本地。2. 调用API使用腾讯云的 tencentcloud-sdk-python。3. 分析维度调用 DetectFace 接口分析头像中的人脸年龄、性别、表情喜怒哀乐、是否戴口罩等。4. 可视化将识别出的年龄分布绘制成直方图看吴迪老师的社交圈年龄段分布例如是年轻的大学生多还是中年的同行多。

更多文章