前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python 的练手项目有哪些值得推荐?

Python 的练手项目有哪些值得推荐?

原创
作者头像
知忆
修改2021-06-07 09:59:45
8250
修改2021-06-07 09:59:45
举报
文章被收录于专栏:linux百科小宇宙linux百科小宇宙

当前最高赞里的《500 Lines or Less》,确实是一本神书。

不过答主回答时该书还没完结,介绍得也不够详细准确,我来做下补充。

我是写成了荐书文章,再来答题的,所以还是贴上全文吧。

分割线后是正文

今天,猫哥要推荐一本非常著名的开源书籍:《500 Lines or Less》。

在开始正题之前,先介绍一下它所属的系列。该系列叫 AOSA,是“The Architecture of Open Source Applications”的简称,即“开源程序的体系结构”,目前有四本书,本期主角是最近的一本(发布于 2016.7.12)。

这个系列最初的目的是:研究那些优秀的开源项目,从中吸取精华的实践经验。

在前三本书中,研究对象已多达 50 几个,其中不乏名头响亮者,例如 Eclipse、Selenium、Git、matplotlib、nginx、Puppet、Pypy、SQLAlchemy 与 Twisted 等等。

每个章节的作者都是开源软件的核心参与者,介绍了项目是如何设计的、为什么这样设计、主要的组成部分是什么、各模块间如何互动、开发中的优秀成果有哪些……

这些书拆解了开源界的明星项目,通过阅读,你能了解到开源作者们的思考方式,了解到各类困难问题的解决方案,学习使用现成的轮子。所谓见多识广,学习吸取经验,有望“站在巨人的肩膀上”。

但是,这几本书主要偏向于架构和工程方面,项目代码量基本是几千上万行,对于初级程序员来说不够实用,想要吃透,挑战性太大。

针对这个问题,该系列新出了一本《500 Lines or Less》,专注于 500 行或更少代码的小型项目。

关注编写代码时所作出的设计决定与权衡 :

为什么要使用一些接口将应用程序分成不同的模块?为什么在这里使用继承,在别处使用封装?如何预测程序的扩展,如何让其他程序员轻松实现? 简而言之,这本书聚焦于一些相对较小但又很具代表性的课题,并通过 500 行以内的代码来实现它。

书中写了 22 个项目,下面逐一简介:

1、Blockcode: A visual programming toolkit(可视化编程工具包)

使用语言:HTML、CSS、JavaScript

该项目基于开源的 Waterbear 工具,提供可视化的操作界面,通过简单而直观的交互方式,实现图形编程。

2、A Continuous Integration System(持续集成系统)

使用语言:Python 2

CI 是软件开发中重要的持续集成系统,保障新功能的稳定实现。这个项目介绍了 CI 系统的工作原理,并尝试构建自己的 CI 系统,实现监听器、测样例调度器和测试运行器。

3、Clustering by Consensus(分布式系统)

使用语言:Python

探索如何实现一个网络协议,用于可靠的分布式计算。为了解决共识性问题,使用了 Paxos 算法的衍生 MultiPaxos。学习这个项目,能接触很多分布式的知识。

4、Contingent: A Fully Dynamic Build System(动态构建系统)

使用语言:Python

构建系统(build system)用于将源代码生成用户可用的目标(如库、可执行文件、脚本等),常见的有 GNU Make、CMake、Apache Ant 等。Python 中的 PyInstaller 也是构建系统的一种。本项目实现了一个构建系统,且试图对“动态交叉引用”问题提出一个解决方案。

5、A Web Crawler With asyncio Coroutines(使用协程实现的爬虫)

使用语言:Python

作者之一是 Python 之父(Guido van Rossum),使用标准库 asyncio 实现异步的网页爬虫。(学习爬虫者必看)

6、Dagoba: an inmemory graph database(内存中的图形数据库)

使用语言:JavaScript

图形数据库是 NoSQL 数据库的一种,使用图形理论来存储实体间的关系。这个项目介绍了图形数据库要解决的几个问题,然后将它实现。

7、DBDB: Dog Bed Database(狗床数据库)

使用语言:Python

用 Python 实现一个简单的键值对存储数据库(key/value database),其特点是在电脑崩溃或程序出错时,也能保证数据的安全。学习这个项目,可以掌握关于数据库的一些核心特性,例如原子性(atomicity)、一致性(consistency)、独立性(isolation)和持久性(durability)。

8、An EventDriven Web Framework(事件驱动的Web框架)

使用语言:Common Lisp

构建一个以事件驱动的 Web 框架,使用 HTTP 做通信协议。

9、A Flow Shop Scheduler(流水车间调度器)

使用语言:Python 2

流水车间调度问题是查找最优解问题的一种,本项目基于局部搜索(local search)方法,实现流水车间调度器。

10、An ArchaeologyInspired Database(受考古学启发的数据库)

使用语言:Clojure

主流的数据库是面向空间编程 (placeoriented programming),即在更新数据的时候,新数据会占据老数据的空间。本项目开了个脑洞,用考古学家的视角设计数据库,记录数据的所有变化轨迹,更新数据时并不删除老数据。最终实现代码仅 360 行,作者称这个数据库为CircleDB 。

11、Making Your Own Image Filters(图片滤镜)

使用语言:Java

Processing 是一种用 Java 构建的开发环境,本项目介绍了它的特性与配置,并最终实现自己的滤镜 APP。功能比较简单,但实现过程涉及很多图像处理的内容。

12、A Python Interpreter Written in Python(Python解释器)

使用语言:Python

它的结构跟 CPython 解释器差不多,作者命其名为 Byterun。 文中详细讲解了解释器的工作原理,跟着学习,将极有帮助。

13、A 3D Modeller(3D建模)

使用语言:Python

3D 图形化编程,使用到了 OpenGL 来渲染图形。

14、A Simple Object Model(对象模型)

使用语言:Python

当今最主流的编程范式依然是面向对象编程,而它的核心则是对象模型。编写一些简单的对象模型可以更好地理解现有语言的内部工作原理,并且深入地了解面向对象语言的设计理念。

15、Optical Character Recognition (OCR,光学字符识别)

使用语言:Python、JavaScript、HTML

基于人工神经网络(ANNs)实现的简单 OCR 系统,并设计了一个 Web 客户端。

16、A Pedometer in the Real World(现实计步器)

使用语言:Ruby

计步器的设计依据是什么,如何在现实世界中把它实现呢?该文回答了这个问题,它还设计了一个友好的 Web 界面。

17、The SameOrigin Policy(同源策略)

使用语言:Alloy

同源策略(SOP)是当今浏览器中安全机制的重要组成部分,用于控制浏览器中脚本间的通信。文中使用 Alloy(一种用于建模与分析软件设计的语言)来构建一个可执行的 SOP 模型。

18、A Rejection Sampler(采样器)

使用语言:Python

“采样”是指从一些概率分布中生成随机数,文中介绍了如何从非标准的概率分布里进行采样,以及如何计算样本在分布里对应的概率。

19、Web Spreadsheet(Web 电子表格)

使用语言:HTML、CSS、JS

电子表格是办公软件的必备,我们最熟知的是微软的 Excel。文中用 AngularJS 框架来实现一个简单的 Web 电子表格,所用代码仅 99 行。效果可在这查看:

20、Static Analysis(静态分析)

使用语言:Julia

“静态分析”指的是在不运行代码的情况下检查代码(类型、格式、编码规范等等),这项工作通常是由各种 IDE 编辑器来完成。本项目使用 Julia,实现了一些基本的静态分析功能。

21、A Template Engine(模板引擎)

使用语言:Python

“模板引擎”是 Web 开发中很重要的东西,支持将用户界面与实际业务数据分离,通过它可生成标准的 HTML 文档。文中所用的模板引擎语法基于 Django,总代码量仅 262 行。

22、A Simple Web Server(Web服务器)

使用语言:Python、HTML

实现了一个简单的 Web 服务器,主要使用了标准库中的 BaseHTTPServer 。另外,它还介绍了 CGI(通用网关接口) 协议,给服务器实现了运行外部程序的功能。

所有项目介绍完毕。可以看出,22 个项目中有 13 个使用了 Python,占60%,难怪网上有些不明真相的同学直呼它是“一本Python神书”。

有些项目初看的话,你难以想象只需不到 500 行代码就能实现,但是经过必要的问题裁剪,并使用恰当的现成轮子(开源库、工具、框架等),就能取得简单的成果。

与之相对的,不要以为 500 行以内的项目就很简单。每个项目的作者都大有来头(连 Python 之父都亲自上阵啦),文章中写到的技术背景、实现原理以及设计思路,全都值得仔细研读(很多还不一定能读懂)。

这本书是开源的,在官网上可以免费阅读。它还配套了 Github 仓库,存放了完整的项目代码,目前已经获得 20000 多颗星星啦。

Github 上有对它的中文翻译计划,但是翻译者寥寥,只有 10 几篇翻译了出来,翻译质量还不敢恭维。

不管如何,这么优质而诚意十足的开源书籍,非常值得推荐!作为咱们 Python 猫荐书系列的第八期,也非常合适。

最后附上该书在开篇中的寄语:

We hope that the experiences of the authors in this book will help you grow out of your comfort zone in your own programming practice. 我们希望本书作者的经验能够帮助您在自己的编程实践中成长。 相关链接:

书籍官网:

Github英:

Github中:

看到了这里,顺手点个赞吧~~

同时,公众号求波关注,谢谢!

公众号【Python猫】, 主要分享 Python基础、Python进阶、Python哲学、编程语言、书籍推荐等内容,另外还有官方 PEP 翻译与优质外文的翻译,值得关注一同学习。

网友回答:

看到Python相关的话题推送,忍不住来水个答案。

推销一些自己的小作品吧。

1.Python写小游戏 先上Github链接(图片与音频素材大部分源于网络,侵删):

CharlesPikachu/Games

里面大概有10几个小游戏,随便举几个例子吧:

(1)“塔防”小游戏

塔防 (2)滑雪小游戏

滑雪 (3)坦克大战v0.2

坦克大战 (4)推箱子

写的都比较糙,每个游戏都有优化和扩展空间~

2. AI自动玩游戏 还是先上Github链接:

CharlesPikachu/AIGames

(1)比如DQN玩TRex Run

(2)设计一个策略自动玩贪吃蛇

等等,更多内容可以看我给的Github链接。

3. 深度/机器学习? 在我公众号里分享的不多,上传到Github上的也不多,随手放两个吧:

(1)Faster RCNN算法复现

(2)FPN算法复现

(3)VGan生成短视频

CharlesPikachu/VideoGan

然后公众号里发过的一些:

(4)风格迁移

Python简单实现图像风格迁移 (5)颜值预测

Python实现颜值预测 (6)动漫头像生成

【Python】利用GAN生成动漫头像 等等...

4. 爬虫? 先放两个好久没更新的项目吧:

(1)音乐下载器

Github:CharlesPikachu/musicdl

(2)视频下载器

Github:CharlesPikachu/VideoDownloade

(4)个人开源的模拟登录库DecryptLogin

Github:

中文文档:

目前支持利用requests模拟登录以下网站:

库里还有很多简单的爬虫小例子:

(5)简单的数据爬取与分析

Python爬取QQ空间信息(下)Python简单分析微信好友Python爬取并简单分析知乎用户粉丝构成Python爬取并简单分析爱淘宝网商品数据 等等。

5. 其他打发时间的东西【Python】视频转字符动画Python仿制抖音表白小软件Python实现烟花特效 等等。

最后再推荐一下自己公众号: 欢迎搜索关注我的微信公众号:Charles的皮卡丘,不定期分享有趣好玩的Python项目以及大量的学习资源。

网友回答:

2020年6月16日更新:

重新检查整理了下面推荐的项目教程,有些版本老的、内容过期的都做了更新,现在推荐的都是保证可以使用在线环境完成的,大家可以选择自己感兴趣的练习。Learn by doing才是正确的技术学习姿势。

………………………………………………分隔线………………………………………………

最近几天刚好在整理Python项目,项目由易到难,代码量从几十行到几千行,在实验环境里保证可以全部完成。找到你认为有趣的去实现它,把项目做出来,知识才能变成自己的:)

(建议PC端访问,边看教程边在环境里动手实践,手机上仅可查看教程)

入门和进阶篇均为免费课程,可以免费使用在线练习环境。

入门篇

0. Python 新手入门

首先给完全没有编程基础的同学推荐下这个入门教程,做项目也要先上手基础语法,这份教程中的几个实验可以让完全零基础的同学在一下午时间入门 Linux、Python 基础和Github 常用命令,不信可以试试:)

1.Python Python 图片转字符画

50 行 Python 代码完成图片转字符画小工具。

2.Python 200行Python代码实现2048

仅用200行的python代码完成2048小游戏的编写。

3.Python 生成个性二维码

使用 Python 基于MyQR实现生成普通二维码,带图片的艺术二维码,动态二维码。

4.Python 实现文字聊天室

实现一个简单的图形界面聊天系统。我们可以通过图形客户端登录聊天室,并与其他成员进行聊天。

5.Python 全面解析PythonChallenge

本课程带领大家一步一步攻克Python Challenge中的难题,在一个又一个脑洞大开的 Python 问题中提升自己的 Python 水平。

6.使用 Python 创建照片马赛克

使用 Python 创建照片马赛克。我们将目标图像划分成较小图像的网格,并用适当的图像替换网格中的每一小块,创建原始图像的照片马赛克。

7.Python 基于 Python 的文件备份

Python 做个简单的备份脚本程序,可以备份主目录和系统文件等。

8.Python Python文本解析器使用Python来解析纯文本生成一个HTML页面的小程序。

9.Python Python 破解验证码通过一个简单的例子来讲解破解验证码的原理。

10.Python 用Python做2048游戏通过GUI来体验编程的乐趣。

11.Python Python实现简单的Web服务器使用 Python 语言实现一个 Web 服务器,探索 HTTP 协议和 Web 服务的基本原理。

进阶篇

12.Python Python3 色情图片识别

使用 Python3 去识别图片是否为色情图片,我们会使用到 PIL 这个图像处理库,会编写算法来完成对划分图像的皮肤区域。

13.Python Python实现3D建模工具

本课程将基于OpenGL实现一般CAD软件都会具备的基础功能:渲染显示3D空间的画面并可以操作3D空间中物体。

14. PyQt 实现简易浏览器

基于 Python 3.4 和 PyQt 5 来学习 GUI 编程,课程分为两次实验,第一次实验先简单了解 Qt 各个组件的使用方法,第二次课程将尝试实现一个浏览器。

15. Python基于共现提取《釜山行》人物关系

针对《釜山行》剧本的文本,使用python编写代码分析文本中人物的共现关系,完成对《釜山行》文本的人物关系提取,并利用Gephi软件对提取的人物关系绘制人物关系图。

16.Python Python实现Python解释器

从实现一个玩具解释器开始学习解释器基本知识,然后考察Python字节码进一步学习理解Python解释器的内部机制,最终实现一个500行以内的Python解释器。

17.Python 高德API+Python解决租房问题

编写Python脚本爬取某租房网站的房源信息,利用高德的 js API 在地图上标出房源地点,划出距离工作地点1小时内可到达的范围,附上公交路径规划功能查看不同路径的用时。

18.Python 基于Flask/RethinkDB/Backbone.js实现TODO List

使用 RethinkDB,Flask 与 Backbone.js 制作一个简单的 todo list。

19.Python 气象数据分析

对意大利北部沿海地区的气象数据进行分析与可视化。

20.NBA常规赛结果预测利用Python进行比赛数据分析

利用NBA在2015~2016年的比赛统计数据进行回归模型建立,最终在今年2016~2017的常规赛中预测每场比赛的输赢情况。

21.Django打造文件分享系统

介绍如何使用Django框架快速打造文件分享系统,实现搜索功能,分享功能,用户分享文件查询。

综合篇

以下项目都是比较综合、系统的,内容质量都不错,因这些项目需要联网实现或占用环境资源较大,现在是属于会员及训练营项目。

22. 基于 Django 实现问答社区

使用 Django 打造一个完整成熟的社区框架,实现了用户注册,发布讨论,回复讨论,站内搜索等主要功能。

23. 基于 React + Flask 打造私人专属网盘

使用 React 作为前端技术,Python Flask 作为后端技术,实现一个小型的私人网盘应用。

24. Python 实现搜索引擎

首先会讲解爬虫基础并利用 Python 异步特性实现异步爬虫系统,而后会一步一步地将构建索引、索引压缩、排名算法等步骤讲解清楚并编码实现,最后利用异步 web 框架 sanic 构建后端实现一个完整的垂直搜索引擎站点。

25. 基于 Django 实现 Upwork 众包网站

使用 Django 框架实现了世界最大的外包网站 Upwork。在实现过程中,将其分为三大应用模块:用户模块,任务模块,私信消息模块。每个模块都严格按照 Django 框架中的 MTV (ModelTemplateView) 模式完成。

26. Python 使用机器学习玩转 Flappy Bird 游戏

通过学习使用纯人工操作,传统计算机视觉,深度学习这三种不同的方式来玩转 pygame 版的 flappy bird 游戏。

27. Python 利用 itchat 进行好友分析和生成好友点赞屏保

使用 itchat 获取微信好友相关数据,利用 pyecharts 进行可视化分析生成微信好友性别比例图、好友省级分布图以及好友城市分布 Top10 柱状图,最后使用 pillow 库对微信好友的头像进行拼接生成屏保。

28. 使用 Python3 编写 Github 自动周报生成器

使用 Python 从 Github 中获取对应代码仓库的贡献度(Commit 信息)及活跃度(Issue 评论内容)等。

29. Python 实现简单邮件客户端

利用 python 标准库实现一个简单邮件客户端,实现对 qq 邮箱的登陆,发送格式简单的邮件,以及接收邮件。

30. 仿 StackOverflow 开发在线问答系统

使用Python Flask Web开发框架实现类似StackOverflow的在线问答平台LouQA,具备提问,回答,评论等功能。学习数据库设计,Python Web 开发相关知识。

31. Python 实现中文错别字高亮系统

上线一个错别字高亮系统,输入我们的 MarkDown 文档,输出一个高亮过疑似错别字的HTML文件。

32. Python 二手房信息爬取与数据呈现

使用python爬取二手房信息,并且使用matplotlib 绘图包对爬取的信息进行分析,绘制简单的图表。

33. 基于Pygame开发贪吃蛇和俄罗斯方块

基于Pygame开发贪吃蛇和俄罗斯方块,通过逐步学习Pygame基础知识,到从零开始实现游戏开发

34. Python实现简易局域网视频聊天工具

Python基于OpenCV和PyAudio实现的局域网内视频聊天工具,支持IPv6。优点是校园网/IPv6下不走流量。

35. Twitter数据情感分析

使用Spark MLlib对Twitter上的流数据进行情感分析,并且利用Python的工具包basemap可视化美国不同的州对于曾经的总统候选人希拉里及川普的情感分析结果,通过地理信息可视化我们可直观的感受到这两位候选人的受欢迎程度。

36. Python3 实现火车票查询工具

使用 Python3 抓取 12306 网站信息提供一个命令行的火车票查询工具。通过该项目的实现,可以熟悉 Python3 基础及网络编程,以及 docopt,requests,prettytable 等库的使用。

37. 基于 Flask 与 MySQL 实现番剧推荐系统

基于 Python 的 Flask 框架和 MySQL 实现的简单的番剧推荐系统。将学到如何用 Python 连接 MySQL 数据库,如何查询和展示数据及设计推荐算法等知识。

网友回答:

最近,有一份机器人Python代码合集登陆GitHub,并受到了用户的热烈标星。

自主导航看这里

来自日本的坂井敦,是一个玩机器人的工程师 他和小伙伴们,为了能让更多的机器人,在地球上自如地游走,便为广大同行做了一次这样的Python代码汇总,大类如下——

· Localization (定位)· Mapping (地图构建)· SLAM· Path Planning (路径规划)· Path Tracking (路径追踪) 不难看出,这份合集非常在意,机器人的自主导航能力。

第一个登场的,是“定位”分类下的扩展卡尔曼滤波器 (EKF) 。?

这是一个传感器融合的定位方法。蓝线是真实轨迹,黑线是用航位推测法 (Dead Reckoning) 推定的轨迹。绿点是位置数据 (比如GPS) ,红线是EKF估计出的轨迹。红色椭圆是EKF估计的协方差。 就像这样,每个词条下面都配了一张动图,还有动图的详解。

坂井说,这样观众就可以更加直观地理解,各种方法背后的思路。

果然是温柔的程序猿。

赏心悦目的集合 各种方法的代码都可以免费自取,又有美味的动图,指引前路,还是很幸福吧。

所以,一起来品尝几幅动图——

这是A星算法。

这是势场 (Potential Field) 算法。

这是均匀极性采样 (Uniform Polar Sampling) 。

这是Voronoi路线图法。

以上作品来自路径规划章节,也是最丰盛的一章,有这么长——

里面分15个子类,包括了动态窗口法 (Dynamic Window Approach) ,如基于网格的搜索 (Grid Based Search) 算法等等。

子类还有自己的子类。

帮助机器人定制路线,躲避障碍,当事无巨细。

想必,大家会用餐愉快的。

喝前摇一摇 想要更好地用这份合集,来投喂机器人,你需要以下工具:

· Python 3.6.x· Numpy· Scipy· Matplotlib· Pandas· Cvxpy 0.4.x 祝各位的机器人茁壮成长。

并在此献上传送门:

想了解更多,请关注我们的知乎号:量子位

网友回答:

打算做出一个目录集合,将我做过的有意思的适合新人练手的Python小项目在此保持长期更新。(最新的项目置顶)

github:Flowingsun007/littleSpiders 求点赞+点Star!!! 谢谢:)

Lyon:Python图片文本识别—基于tesseract和百度实现 (更新于18.4.15)

Lyon: Python实现微信查天气+火车+飞机+快递 (更新于18.3.7)

Lyon:Python—itchat下载拼接微信好友头像图 (更新于18.3.6)

Lyon:Python—itchat实现微信自动回复(更新于18.3.5)

Lyon: Python命令行实现—查全国7天天气

Lyon: Python命令行查询12306火车票 (更新于18.2.19)

Lyon: Python—一行代码情人节画爱心表白 (更新于18.2.14)

Lyon: Python多线程threading—图片下载 (更新于18.2.5)

Lyon:Python—10行代码查快递 (更新于18.2.2)

Lyon:用Python发邮件(更新于18.1.23)

Lyon:Python爬虫入门—图片下载

Lyon:用Python实现—携程机票查询

Lyon:智联Python相关职位的数据分析及可视化Pandas&Matplotlib篇

Lyon:Python—一行代码情人节画爱心表白 情人节快到了,怎么表白?受到几个小例子告诉你, 一行Python代码能干哪些事

的启发,我决定用Python写一段?? 的话来表白(装X)。原文是一行代码实现输出爱心图:

print('\n'.join([''.join([('Love'[(xy) % len('Love')] if ((x*0.05)**2+(y*0.1)**21)**3(x*0.05)**2*(y*0.1)**3 <= 0 else ' ') for x in range(30, 30)]) for y in range(30, 30, 1)])) 效果如下:

但是,有点太单调了点,来,让我撸起袖子搞点事情,将代码简单改造一下,实现动态输出心形的一段话的效果:

改造以后,看上去不错了!效果如下:

代码如下,喜欢请点赞哦,谢谢??!:

import time

words = input('Please input the words you want to say!:')

for item in words.split():

print('\n'.join([''.join([(item[(xy) % len(item)] if ((x*0.05)**2+(y*0.1)**21)**3(x*0.05)**2*(y*0.1)**3 <= 0 else ' ') for x in range(30, 30)]) for y in range(12, 12, 1)]))

time.sleep(1.5); 其实,像?? 这样类型的颜文字其实也是可以输出的,不过格式不是标准的心型,需要自行调节,大家可以自己尝试下^_^!

Lyon:用Python发邮件 本次,我们发邮件用到的Python库是smtplib和email。简单来说,smtplib库主要是用于负责和邮件服务器进行通讯,email库则主要用于规定编写邮件的头、主体、内容、附件等。

发邮件之前我们需要用Python登录smtp服务器,这样才能有发送权限,所以,我们需要去邮箱手动开启smtp服务,然后记住服务器授权码(授权码意思是,你可以不用我的网页邮箱或者邮箱app登录,你可以用邮箱账号+授权码在后台来获取邮箱服务器的内容)

(二维码自动识别)

由于本次我们用QQ邮箱发送,你也可以用网易邮箱或者其他邮箱发送,原理都是类似~

如何开启QQ邮箱smtp服务器和获取授权码:

很多场合都会用到邮箱授权码进行邮件的收取,现在讲一下如何QQ邮箱的授权码获取方式,网易邮箱的也差不多哦~

获取好服务器授权码后,我们就可以写代码了,本次发送一个简单的文字邮件,然后添加一张可爱猪的图片作为附件:

程序运行结果:

代码如下:

import smtplibfrom email import encodersfrom email.mime.text import MIMETextfrom email.mime.base import MIMEBasefrom email.mime.multipart import MIMEMultipart#sender是邮件发送人邮箱,passWord是服务器授权码,mail_host是服务器地址(这里是QQsmtp服务器)sender = 'xxxxxxx@qq.com'#passWord = 'xxx'mail_host = 'smtp.qq.com'#receivers是邮件接收人,用列表保存,可以添加多个receivers = ['aaa@qq.com','bbb@163.com']#设置email信息msg = MIMEMultipart()#邮件主题msg['Subject'] = input(f"{'请输入邮件主题:'}")#发送方信息msg['From'] = sender#邮件正文是MIMEText:msg_content = input(f"{'请输入邮件主内容:'}")msg.attach(MIMEText(msg_content, 'plain', 'utf8'))# 添加附件就是加上一个MIMEBase,从本地读取一个图片:with open('/Users/xxx/1.jpg', 'rb') as f: # 设置附件的MIME和文件名,这里是jpg类型,可以换png或其他类型: mime = MIMEBase('image', 'jpg', filename='Lyon.png') # 加上必要的头信息: mime.add_header('ContentDisposition', 'attachment', filename='Lyon.png') mime.add_header('ContentID', '<0>') mime.add_header('XAttachmentId', '0') # 把附件的内容读进来: mime.set_payload(f.read()) # 用Base64编码: encoders.encode_base64(mime) # 添加到MIMEMultipart: msg.attach(mime)#登录并发送邮件try: #QQsmtp服务器的端口号为465或587 s = smtplib.SMTP_SSL(", 465) s.set_debuglevel(1) s.login(sender,passWord) #给receivers列表中的联系人逐个发送邮件 for i in range(len(receivers)): to = receivers[i] msg['To'] = to s.sendmail(sender,to,msg.as_string()) print('Success!') s.quit() print ("All emails have been sent over!")except smtplib.SMTPException as e: print ("Falied,%s",e)

更新:没想到,会火,40000+关注的问题果然流量够大~

再增加一个Python爬图片,下载到本地的小项目!

Lyon:Python爬虫入门—图片下载 这次决定写一个爬虫程序来爬精美的壁纸图,壁纸网站看了知乎网友的推荐,选择的是:

Awesome Wallpapers wallhaven.cc 此程序支持输入关键词,根据查询结果返回图片总数、然后在本地新建文件夹、字典下载图片到文件夹中。

效果如下:

代码如下:

#_*_ coding:utf8 _* _

#__author__='阳光流淌007'

#__date__='20180121'

#爬取wallhaven上的的图片,支持自定义搜索关键词,自动爬取并该关键词下所有图片并存入本地电脑。

import os

import requests

import time

import random

from lxml import etree

keyWord = input('Please input the keywords that you want to download :')

class Spider():

#初始化参数

def __init__(self):

#headers是请求头,"UserAgent"、"Accept"等字段都是通过谷歌Chrome浏览器查找的!

self.headers = {

"UserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36",

}

#filePath是自定义的,本次程序运行后创建的文件夹路径,存放各种需要下载的对象。

self.filePath = ('/users/zhaoluyang/小Python程序集合/桌面壁纸/'+ keyWord + '/')

def creat_File(self):

#新建本地的文件夹路径,用于存储网页、图片等数据!

filePath = self.filePath

if not os.path.exists(filePath):

os.makedirs(filePath)

def get_pageNum(self):

#用来获取搜索关键词得到的结果总页面数,用totalPagenum记录。由于数字是夹在形如:1,985 Wallpapers found for “dog”的string中,

#所以需要用个小函数,提取字符串中的数字保存到列表numlist中,再逐个拼接成完整数字。。。

total = ""

url = ("

html = requests.get(url)

selector = etree.HTML(html.text)

pageInfo = selector.xpath('//header[@class="listingheader"]/h1[1]/text()')

string = str(pageInfo[0])

numlist = list(filter(str.isdigit,string))

for item in numlist:

total += item

totalPagenum = int(total)

return totalPagenum

def main_fuction(self):

#count是总图片数,times是总页面数

self.creat_File()

count = self.get_pageNum()

print("We have found:{} images!".format(count))

times = int(count/24 + 1)

j = 1

for i in range(times):

pic_Urls = self.getLinks(i+1)

for item in pic_Urls:

self.download(item,j)

j += 1

def getLinks(self,number):

#此函数可以获取给定numvber的页面中所有图片的链接,用List形式返回

url = (",number)

try:

html = requests.get(url)

selector = etree.HTML(html.text)

pic_Linklist = selector.xpath('//a[@class="jsAnchor thumbtagstoggle tagged"]/@href')

except Exception as e:

print(repr(e))

return pic_Linklist

def download(self,url,count):

#此函数用于图片下载。其中参数url是形如:

#616442是图片编号,我们需要用strip()得到此编号,然后构造html,html是图片的最终直接下载网址。

string = url.strip('/thumbTags').strip('

html = ' + string + '.jpg'

pic_path = (self.filePath + keyWord + str(count) + '.jpg' )

try:

pic = requests.get(html,headers = self.headers)

f = open(pic_path,'wb')

f.write(pic.content)

f.close()

print("Image:{} has been downloaded!".format(count))

time.sleep(random.uniform(0,2))

except Exception as e:

print(repr(e))

spider = Spider()

spider.main_fuction()

注意:

图片虽好,可是下载速度挺慢的,可能和网站服务器有关~没有验证过网站是否有反爬虫机制,加了time.sleep(random.uniform(0,2))让图片下载完后停顿0~2秒,1来防止给服务器带来过大压力,2来也怕被爬虫机制检测~

Lyon:用Python实现—携程机票查询 以前参考别人的代码,用Python做了一个12306命令行式的火车票查询工具,感觉还挺有意思的!于是自己又做了一个类似的——携程机票查询器。

携程官网查询的效果是这样的:

Python命令行界面查询的效果是这样的:

输入出发地、目的地、乘机日期,即可看到可选的航班、机场、出发到达时间、票价等信息。

视频演示效果如下:

程序的源码如下:

1.air_stations.py

2.airline_ticket.py

#1.air_stations.py

import re

import os

import json

import requests

from pprint import pprint

url = '

response = requests.get(url,verify=False)

station = re.findall(u'([\u4e00\u9fa5]+)\(([AZ]+)\)', response.text)

stations = dict(station)

pprint(stations,indent = 4)

2.airline_ticket.py

#此程序可用于查询携程机票,查询需要指定出发日期、出发城市、目的城市!(模仿了上一个12306火车订票查询程序)

import requests,json,os

from docopt import docopt

from prettytable import PrettyTable

from colorama import init,Fore

from air_stations import stations

fromCity = input('Please input the city you want leave :')

toCity = input('Please input the city you will arrive :')

tripDate = input('Please input the date(Example:20170927) :')

init()

class TrainsCollection:

header = '航空公司 航班 机场 时间 机票价格 机场建设费'.split()

def __init__(self,airline_tickets):

self.airline_tickets = airline_tickets

@property

def plains(self):

#航空公司的总表没有找到,但是常见航空公司也不是很多就暂时用这个dict{air_company}来收集!

#如果strs没有查询成功,则会返回一个KeyError,表示此dict中未找到目标航空公司,则会用其英文代码显示!

air_company = {"G5":"华夏航空","9C":"春秋航空","MU":"东方航空","NS":"河北航空","HU":"海南航空","HO":"吉祥航空","CZ":"南方航空","FM":"上海航空","ZH":"深圳航空","MF":"厦门航空","CA":"中国国航","KN":"中国联航"}

for item in self.airline_tickets:

try:

strs = air_company[item['alc']]

except KeyError:

strs = item['alc']

airline_data = [

Fore.BLUE + strs + Fore.RESET,

Fore.BLUE + item['fn'] + Fore.RESET,

'\n'.join([Fore.YELLOW + item['dpbn'] + Fore.RESET,

Fore.CYAN + item['apbn'] + Fore.RESET]),

'\n'.join([Fore.YELLOW + item['dt'] + Fore.RESET,

Fore.CYAN + item['at'] + Fore.RESET]),

item['lp'],

item['tax'],

]

yield airline_data

def pretty_print(self):

#PrettyTable()用于在屏幕上将查询到的航班信息表逐行打印到终端

pt = PrettyTable()

pt._set_field_names(self.header)

for airline_data in self.plains:

pt.add_row(airline_data)

print(pt)

def doit():

headers = {

"Cookie":"自定义",

"UserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36",

}

arguments = {

'from':fromCity,

'to':toCity,

'date':tripDate

}

DCity1 = stations[arguments['from']]

ACity1 = stations[arguments['to']]

DDate1 = arguments['date']

url = (",ACity1,DDate1)

try:

r = requests.get(url,headers = headers,verify=False)

except:

print("Some Error shows in requests.get(url)")

exit(0)

print(url)

airline_tickets = r.json()['fis']

TrainsCollection(airline_tickets).pretty_print()

if __name__ == '__main__':

doit()

其实,此小程序还可以拓展,譬如将查询记录存到本地电脑(txt格式、或者存到数据库里)或者更厉害的还可以设置定时自动查询;还可以设置查询到自动发邮箱提醒;还可以用Python的GUI库将此程序做成桌面软件的形式。。。。

Lyon:智联Python相关职位的数据分析及可视化Pandas&Matplotlib篇 20170912,by—阳光流淌

上一篇,我用了Excel对爬虫采集到的智联招聘数据进行了数据分析及可视化,用到软件是Excel, 这一篇,我们打算完全用Python来做同样的事。用到的库有Pandas、Matplotlib。np、pd、plt分别是numpy、pandas、matplotlib.pyplot的常用缩写。 Numpy(Numerical Python的简称)是Python科学计算的基础包。它提供了以下功能:

快速高效的多维数组对象ndarray。用于对数组执行元素级计算以及直接对数组执行数学运算的函数。用于读写硬盘上基于数组的数据集的工具。线性代数运算、傅里叶变换,以及随机数生成。用于将C、C++、Fortran代码集成到Python的工具。 除了为Python提供快速的数组处理能力,Numpy在数据分析方面还有另外一个主要作用,即作为在算法之间传递数据的容器。对于数值型数据,Numpy数组在存储和处理数据时要比内置的Python数据结构高效的多。此外,由低级语言(比如C和Fortran)编写的库可以直接操作Numpy数组中的数据,无需进行任何数据复制工作。

Pandas这个名字本身源于panel data(面板数据,这是计量经济学中关于多维结构化数据集的一个术语)以及Python data analysis。pandas提供了使我们能够快速便捷地处理结构化数据的大量数据结构和函数。Pandas中用的最多的是DataFrame,它是一个面向列的二维表结构,且含有行标和列标。pandas兼具numpy高性能的数组计算功能以及电子表格和关系型数据库(如SQL)灵活的数据处理功能。它提供了复杂精细的索引功能,以便更为便捷地完成重塑、切片和切块、聚合以及选取数据子集等操作。

Matplotlib是Python中常用的可视化绘图库,可以通过简单的几行代码生成直方图,功率谱,条形图,错误图,散点图等。Seaborn、ggplot、等诸多Python可视化库均是在此基础上开发的,所以学会matplotlib的基础操作还是很有必要的!它和Ipython结合的很好,提供了一种非常好用的交互式数据绘图环境。绘制的图表也是交互式的,你可以利用绘图窗口中的工具栏放大图表中的某个区域或对整个图表进行平移浏览。

数据来源: Python爬虫爬取了智联招聘关键词:【Python】、全国30个主要城市的搜索结果,总职位条数:18326条(行),其中包括【职位月薪】、【公司链接】、【工作地点】、 【岗位职责描述】等14个字段列,和一个索引列【ZL_Job_id】共计15列。数据存储在本地MySql服务器上,从服务器上导出json格式的文件,再用Python进行数据读取分析和可视化。

数据简单清洗: 1.首先在终端中打开输入ipython pylab。在Ipython的shell界面里导入常用的包numpy、pandas、matplotlib.pyplot。用pandas的read_json()方法读取json文件,并转化为用df命名的DataFrame格式文件。(DataFrame格式是Pandas中非常常用且重要的一种数据存储格式、类似于Mysql和Excel中的表。)

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

df = pd.read_json('/Users/zhaoluyang/Desktop/Python_全国JSON.json')

#查看df的信息

df.info()

df.columns 可以看到读取的df格式文件共有15列,18326行,pandas默认分配了索引值从0~18325。还有一点值得注意的:全部的15列都有18326个非空值,因为当初写爬虫代码时设置了, 如果是空值,譬如:有一条招聘信息其中【福利标签】空着没写,那么就用字符串代替,如“found no element”。

2.读取JSON文件时pandas默认分配了从0开始的索引,由于文件'ZL_Job_id'列中自带索引,故将其替换!替换后,用sort_index()给索引重新排列。

df.index = df['ZL_Job_id']#索引列用'ZL_Job_id'列替换。

del(df['ZL_Job_id'])#删除原文件中'ZL_Job_id'列。

df_sort = df.sort_index()#给索引列重新排序。

df = df_sort

df[['工作地点','职位月薪']].head(10) 3.下面,将进行【职位月薪】列的分列操作,新增三列【bottom】、【top】、【average】分别存放最低月薪、最高月薪和平均月薪。 其中try语句执行的是绝大多数情况:职位月薪格式如:800010000元/月,为此需要对【职位月薪】列用正则表达式逐个处理,并存放至三个新列中。 处理后bottom = 8000,top = 10000,average = 9000. 其中不同语句用于处理不同的情况,譬如【职位月薪】=‘面议’、‘found no element’等。对于字符形式的‘面议’、‘found no element’ 处理后保持原字符不变,即bottom = top = average = 职位月薪。q1,q2,q3,q4用来统计各个语句执行次数.其中q1统计职位月薪形如‘60008000元/月’的次数;q2统计形如月收入‘10000元/月以下’;q3代表其他情况如‘found no element’,‘面议’的次数;q4统计失败的特殊情况。

import re

df['bottom'] = df['top'] = df['average'] = df['职位月薪']

pattern = re.compile('([09]+)')

q1=q2=q3=q4=0

for i in range(len(df['职位月薪'])):

item = df['职位月薪'].iloc[i].strip()

result = re.findall(pattern,item)

try:

if result:

try:

#此语句执行成功则表示result[0],result[1]都存在,即职位月薪形如‘60008000元/月’

df['bottom'].iloc[i],df['top'].iloc[i] = result[0],result[1]

df['average'].iloc[i] = str((int(result[0])+int(result[1]))/2)

q1+=1

except:

#此语句执行成功则表示result[0]存在,result[1]不存在,职位月薪形如‘10000元/月以下’

df['bottom'].iloc[i] = df['top'].iloc[i] = result[0]

df['average'].iloc[i] = str((int(result[0])+int(result[0]))/2)

q2+=1

else:

#此语句执行成功则表示【职位月薪】中并无数字形式存在,可能是‘面议’、‘found no element’

df['bottom'].iloc[i] = df['top'].iloc[i] = df['average'].iloc[i] = item

q3+=1

except Exception as e:

q4+=1

print(q4,item,repr(e))

for i in range(100):#测试一下看看职位月薪和bottom、top是否对的上号

print(df.iloc[i][['职位月薪','bottom','top','average']])#或者df[['职位月薪','bottom','top','average']].iloc[i]也可

df[['职位月薪','bottom','top','average']].head(10)

经过检查,可以发现【职位月薪】和新增的bottom、top、average列是能对的上。其中形如‘60008000元/月’的有16905条、形如‘10000元以下’的 有61条、'found no element'和'面议'加起来有1360条,总数18326条,可见是正确的。

4.进行【工作地点】列的处理,新增【工作城市】列,将工作地点中如‘苏州姑苏区’、‘苏州工业园区’等统统转化为‘苏州’存放在【工作城市】列。

df['工作城市'] = df['工作地点']

pattern2 = re.compile('(.*?)(\)')

df_city = df['工作地点'].copy()

for i in range(len(df_city)):

item = df_city.iloc[i].strip()

result = re.search(pattern2,item)

if result:

print(result.group(1).strip())

df_city.iloc[i] = result.group(1).strip()

else:

print(item.strip())

df_city.iloc[i] = item.strip()

df['工作城市'] = df_city

df[['工作地点','工作城市']].head(20)

检查一下,没有错误,可以进行下一步的操作了!

数据分析和可视化 从可读性来看,应该是先进行数据清洗,然后进行分析及可视化,但是实际过程中,往往是交织在一起的, 所有下面让我们一步步来,完成所有的清洗、分析和可视化工作。除了具体的公司和职位名称以外,我们还比较关心几个关键词: 平均月薪、工作经验、工作城市、最低学历和岗位职责描述,这里岗位职责描述以后会用python分词做词云图,所以目前筛选出 【平均月薪】、【工作经验】、【工作城市】、【最低学历】这四个标签,这些标签可以两两组合产生各种数据。譬如我想知道各个城市的招聘数量分布情况, 会不会大部分的工作机会都集中在北上广深?是不是北上广深的平均工资也高于其他城市?我想知道Python这个关键词的18000多条招聘数据中 对学历的要求和对工作经验的要求,以及它们分别占比多少?我还想知道平均月薪和工作经验的关系?最低学历和平均月薪的关系? 和上一篇(Execel篇)类似,不同的是,这次我们完全用Python实现同样的操作。

1.各个城市职位数量及分布 根据猜想,北上广深,一定占据了Python这个关键词下大部分的工作机会,会不会符合28定律?20%的城市占据了80%的岗位? 有可能!我们先用df.工作城市.value_counts()看一下究竟有多少个城市,以及他们各自有多少条工作数据?

df.工作城市.value_counts()#等价于df['工作城市'].value_counts()

#再用count()来看一下统计出来的城市数量

df.工作城市.value_counts().count()

type(df.工作城市.value_counts())#用type()查看下类型。 可以看到,明明设置的是搜索30个城市,怎么变成了40?像延边、珲春、白山。。。。是什么鬼?想了一下,这些城市是搜索关键词城市‘吉林市’时,自动冒出来的;还有95个‘found no element’,是这些职位链接本身就没有填写工作城市,为了避免干扰,要把他们统统替换成空值。用df_工作城市 = df['工作城市'].replace()

#将原来df['工作城市']列中选定的字段替换成空值nan

df_工作城市 = df['工作城市'].replace(['found no element','松原','辽源','珲春','白山','公主岭','白城','延边','四平','通化'],np.nan)

#查看替换后各个城市职位计数

df_工作城市.value_counts()

#查看替换后城市所包含的职位总数;查看替换后的城市数量,是否等于30.

df_工作城市

#将新的[df_工作城市]列添加到df表中,留作备用

df['df_工作城市'] = df_工作城市

看了一下,没有问题,现在df_工作城市中筛选出了30个城市,合计18211条职位数据。 为了数据完整性,df表保持原样,我们用df_工作城市直接操作,进行下一步的可视化。先直接上代码和图,再一一解释下。

fig1 = plt.figure(1,facecolor = 'black')#设置视图画布1

ax1 = fig1.add_subplot(2,1,1,facecolor='#4f4f4f',alpha=0.3)#在视图1中设置子图1,背景色灰色,透明度0.3(figure.add_subplot 和plt.suplot都行)

plt.tick_params(colors='white')#设置轴的颜色为白色

df_工作城市.value_counts().plot(kind='bar',rot=0,color='#ef9d9a')#画直方图图

#设置图标题,x和y轴标题

title = plt.title('城市——职位数分布图',fontsize=18,color='yellow')#设置标题

xlabel = plt.xlabel('城市',fontsize=14,color='yellow')#设置X轴轴标题

ylabel = plt.ylabel('职位数量',fontsize=14,color='yellow')#设置Y轴轴标题

#设置说明,位置在图的右上角

text1 = ax1.text(25,4500,'城市总数:30(个)',fontsize=12, color='cyan')#设置说明,位置在图的右上角

text2 = ax1.text(25,4000,'职位总数:18326(条)',fontsize=12, color='cyan')

text3 = ax1.text(25,3500,'有效职位:18211(条)',fontsize=12, color='red')

#添加每一个城市的坐标值

for i in range(len(list_1)):

ax1.text(i0.3,list_1[i],str(list_1[i]),color='yellow')

#可以用plt.grid(True)添加栅格线

#可以用下面语句添加注释箭头。指向上海,xy为坐标值、xytext为注释坐标值,facecolor为箭头颜色。

#arrow = plt.annotate('职位数:3107', xy=(1,3107), xytext=(3, 4000),color='blue',arrowprops=dict(facecolor='blue', shrink=0.05))

ax2 = fig1.add_subplot(2,1,2)#设置子图2,是位于子图1下面的饼状图

#为了方便,显示前8个城市的城市名称和比例、其余的不显示,用空字符列表替代,为此需要构造列表label_list和一个空字符列表['']*23。

x = df_工作城市.value_counts().values#x是数值列表,pie图的比例根据数值占整体的比例而划分

label_list = []#label_list是构造的列表,装的是前8个城市的名称+职位占比。

for i in range(8):

t = df_工作城市.value_counts().values[i]/df_工作城市.value_counts().sum()*100

city = df_工作城市.value_counts().index[i]

percent = str('%.1f%%'%t)

label_list.append(city+percent)

#labels参数原本是与数值对应的标签列表,此处30个城市过多,所以只取了前8个城市显示。

#explode即饼图中分裂的效果explode=(0.1,1,1,。。)表示第一块图片显示为分裂效果

labels = label_list + ['']*22

explode = tuple([0.1]+[0]*29)

plt.pie(x,explode=explode,labels=labels,textprops={'color':'yellow'})

#可加参数autopct='%1.1f%%'来显示饼图中每一块的比例,但是此处30个城市,如果全显示的话会非常拥挤不美观,所以只能手动通过labels参数来构造。

#若要显示标准圆形,可以添加:plt.axis('equal')

可以看见,这个曲线下降的弧度还是挺美的,北上深杭广5个城市占据了超过60%以上的职位数。其中北京当之无愧的占据了四分之一的Python工作数量,不愧为帝都。 上海以3107条职位排名第二,可见上海虽然经济超越北京,在互联网环境和工作机遇方面还需努力!深圳作为中国的科技中心,排名第三我是没疑问的,杭州竟然超过广州排名第四!不过也可以想到,阿里巴巴、百草味等等电商产业带动了整个杭州的互联网文化!【北上深杭广】+成都、南京、郑州,这8个城市占据了全国30座城市中,近80%的工作机会!剩下的22个城市合起来只占据了20%,果然,是基本符合28定律的。。。

2.工作经验职位数量及分布 Python虽然是一名比较老的语言,但是在人们的印象中火起来也就最近几年,Python相关的工作对于【工作经验】是怎样要求的呢?让我们来看看!

df.工作经验.value_counts()#统计【工作经验】下各个字段的累计和

可以看见出现了一些很数字少量的字段譬如“5年以上”,“2年以上”,“12年”,“1年以上”等,这些标签下职位的数量都在10以内,不太具备统计意义,所以我们作图的时候不想让他们出现,必须筛选掉。 下面我们还是通过同样的步骤来清除掉此类数据。

= df['工作经验'].replace(['found no element','3年以上','1年以上','5年以上','2年以上','12年'],np.nan)

df_工作经验.value_counts()

df_工作经验.value_counts().sum()

现在,可以进行下一步可视化了,还是做2张图:直方图和饼图。通过这两张图可以直观地看到这么多职位中对不同工作经验的要求占比,好做到心里有数!

fig2 = plt.figure(2,facecolor = 'black')

ax2_1 = fig2.add_subplot(2,1,1,facecolor='#4f4f4f',alpha=0.3)

plt.tick_params(colors='white')

df_工作经验.value_counts().plot(kind = 'bar',rot = 0,color='#7fc8ff')

title = plt.title('工作经验——职位数分布图',fontsize = 18,color = 'yellow')

xlabel = plt.xlabel('工作经验',fontsize = 14,color = 'yellow')

ylabel = plt.ylabel('职位数量',fontsize = 14,color = 'yellow')

plt.grid(True)

text1_ = ax2_1.text(5,5600,'城市总数:30(个)',fontsize=12, color='yellow')

text2 = ax2_1.text(5,4850,'职位总数:18326(条)',fontsize=12, color='yellow')

text3 = ax2_1.text(5,4100,'有效职位:18215(条)',fontsize=12, color='cyan')

#设置子图2,是位于子图1下面的饼状图

ax2_2 = fig2.add_subplot(2,1,2)

#x是数值列表,pie图的比例根据数值占整体的比例而划分

x2 = df_工作经验.value_counts().values

labels = list(df_工作经验.value_counts().index[:5])+ ['']*2

explode = tuple([0.1,0.1,0.1,0.1,0.1,0.1,0.1])

plt.pie(x2,explode=explode,labels=labels,autopct='%1.1f%%',textprops={'color':'yellow'})

plt.axis('equal')#显示为等比例圆形

#设置图例,方位为右下角

legend = ax2_2.legend(loc='lower right',shadow=True,fontsize=12,edgecolor='cyan')

总共得到18215条职位。从直方图里可以明显看出工作机会集中在'不限'、'13年'、'35年', 其中工作经验要求3年以下的(【无经验】+【不限】+【1年以下】+【13年】)合计11501条职位,占比超过63%,看来即使是初入门者,大家的机会也还是有不少的! (PS:最后,在df表中添加一列'df_工作经验',以后筛选时就可以直接用了,df['df_工作经验']=df_工作经验)

3.工作经验平均月薪 这个嘛,大家闭着眼都能想到!肯定是工作经验越久的拿钱越多了!再猜猜?无经验的和510年经验的收入差距有多大?这个,嘿嘿就不好猜了,让我们来看看吧!

1.第一步,要想统计工作经验和平均月薪的关系,那么我们先看看df中对应的列df.工作经验和df.average。之前我们构造了一列df_工作经验,把df.工作经验中几个样本容量小于10的值和‘found no element’全筛选掉了,故df_工作经验还能继续使用。现在,让我们看看df.average的信息。

df.average.value_counts()

可以看到,其中有1265个值是‘面议’,有95个值是‘found no element’,这些值需要替换成空值,不然会影响下一步工资的计算。

df_平均月薪 = df['average'].replace(['面议','found no element'],np.nan)

2.好了,第一步的简单数据清洗完成了,我们可以思考下一步了,现在我们想要得到的是不同工作经验字段下的平均月薪

A. 首先我需要把df_工作经验和df_平均月薪这两列元素放在一起,构造一个DataFrame用于存放df_工作经验和df_平均月薪这两列元素,且方便进一步的groupby操作。B. 其次我需要把df_平均月薪列根据df_工作经验进行分组(用groupby),分组后我可以求得df_工作经验下各个字段的月薪的计数、最大值最小值、累加和、平均值等一系列数据。C. 当然此处我只需要平均值。对分组后的grouped用mean()方法,就可以轻松统计分组内各项的平均值了。

df3=pd.DataFrame(data={'工作经验':df['df_工作经验'],'平均月薪':df_平均月薪})

df3.info()

grouped3 = df3['平均月薪'].groupby(df3['工作经验'])

grouped3.mean()

在进行grouped3.mean()时,我们发现报错了:DataError: No numeric types to aggregate,看一下,原来df_平均月薪列里的值都是字符型str,并不是数值型的float,因为前面的步骤没有做好,留下了这个bug,无奈我们需要对值类型做个转换。

#构造一个listi存放转化后float型的‘平均月薪’

import re

pattern = re.compile('([09]+)')

listi = []

for i in range(len(df.average)):

item = df.average.iloc[i].strip()

result = re.findall(pattern,item)

try:

if result:

listi.append(float(result[0]))

elif (item.strip()=='found no element' or item.strip()=='面议'):

listi.append(np.nan)

else:

print(item)

except Exception as e:

print(item,type(item),repr(e))

#将df3.平均月薪列替换掉,同时给df新增一列'df_平均月薪'做备用。

df3['平均月薪'] = listi

df['df_平均月薪'] = df3['平均月薪']

#看看更新后的数据是否正确

df3['平均月薪'].value_counts()#统计每个月薪字段的个数

df3['平均月薪'][:10]#查看前10个值

type(df3['平均月薪'][1])#看看现在月薪的类型是不是浮点型

df3['平均月薪'].value_counts().sum()#看看月薪样本总数

df3['平均月薪'].mean()#看看这16966个月薪样本的平均值是多少?

可以看到,替换后的df3['平均月薪']值从str变为了可以计算的float,月薪样本总数16966个,样本的平均月薪14197元。好,现在终于OK了,让我们再回到之前的步骤:

grouped3 = df3['平均月薪'].groupby(df3['工作经验'])

grouped3.mean()

好了,完美,格式对了,数据有了,现在可以来画图了!但是再看看,还不是那么完美,数据大小排列很乱,而且小数点那么多。。。好吧,让我们再简单处理下

#新增一个平均值,即所有非空df3['平均月薪']的平均值

s3 = pd.Series(data = {'平均值':df3['平均月薪'].mean()})

result3 = grouped3.mean().append(s3)

#sort_values()方法可以对值进行排序,默认按照升序,round(1)表示小数点后保留1位小数。

result3.sort_values(ascending=False).round(1)

3.数据可视化

这次我们画一个躺倒的柱状图(barh),用ggplot的风格来画。

matplotlib.style.use('ggplot')

fig3 = plt.figure(3,facecolor = 'black')

ax3 = fig3.add_subplot(1,1,1,facecolor='#4f4f4f',alpha=0.3)

result3.sort_values(ascending=False).round(1).plot(kind='barh',rot=0)

#设置标题、x轴、y轴的标签文本

title = plt.title('工作经验——平均月薪分布图',fontsize = 18,color = 'yellow')

xlabel= plt.xlabel('平均月薪',fontsize = 14,color = 'yellow')

ylabel = plt.ylabel('工作经验',fontsize = 14,color = 'yellow')

#添加值标签

list3 = result3.sort_values(ascending=False).values

for i in range(len(list3)):

ax3.text(list3[i],i,str(int(list3[i])),color='yellow')

#设置标识箭头

arrow = plt.annotate('Python平均月薪:14197元/月', xy=(14197,3.25), xytext=(20000,4.05),color='yellow',fontsize=16,arrowprops=dict(facecolor='cyan', shrink=0.05))

#设置图例注释(16966来源:df2['平均月薪'].value_counts().sum())

text= ax3.text(27500,6.05,'月薪样本数:16966(个)',fontsize=16, color='cyan')

#设置轴刻度文字颜色为白色

plt.tick_params(colors='white')

通过图表,我们可以直观地看到,Python关键词下的职位月薪是随着工作经验增长而递增的(这不是说了一句废话么?!囧) 其中【无经验】的平均月薪最低,只有5842,相比之下【10年以上】经验的,平均月薪达到了恐怖的34890,约达到了【无经验】月薪的6倍之多!!! 【1年以下】的平均月薪7579,还勉强凑合,【13年】的已经破万了,达到了近12000元/月的水准。最后让我们看看平均值吧,由于‘被平均’的缘故,16966条月薪样本的均值是14197元,有没有让你满意呢?

4.工作城市平均月薪 对了,刚才说到北上广深占据了全国大部分的工作机会,那么北上广深的平均月薪如何呢?会不会也碾压小城市?让我们来看看! 和之前的套路一样,我们还是要构造一个DataFrame,包含两列,一列是【平均月薪】,一列是【工作城市】,然后对df4进行groupby操作,还是很简单的!不过,经过上次的教训,平均月薪一定要是数值型的,str型的计算不了。

#此处df['df_工作城市']是之前经过筛选后的30个城市数据

df4=pd.DataFrame(data={'工作城市':df['df_工作城市'],'平均月薪':df['df_平均月薪']})

df4.info()

grouped4 = df4['平均月薪'].groupby(df4['工作城市'])

grouped4.mean()#查看对30个城市分组后,各个城市月薪的平均值

grouped4.count().sum()#查看对30个城市分组后筛选出的平均月薪样本数

#新增一个平均值,即所有非空df2['平均月薪']的平均值

s4 = pd.Series(data = {'平均值':df['df_平均月薪'].mean()})

result4 = grouped4.mean().append(s4)

#sort_values()方法可以对值进行排序,默认按照升序,round(1)表示小数点后保留1位小数。

result4.sort_values(ascending=False).round(1)

数据构造好了,进行下一步,可视化。

#可以通过style.available查看可用的绘图风格,总有一款适合你

matplotlib.style.use('dark_background')

fig4 = plt.figure(4)

ax4 = fig4.add_subplot(1,1,1)#可选facecolor='#4f4f4f',alpha=0.3,设置子图,背景色灰色,透明度0.3

result4.sort_values(ascending=False).round(1).plot(kind='bar',rot=30)#可选color='#ef9d9a'

#设置图标题,x和y轴标题

title = plt.title(u'城市——平均月薪分布图',fontsize=18,color='yellow')#设置标题

xlabel = plt.xlabel(u'城市',fontsize=14,color='yellow')#设置X轴轴标题

ylabel = plt.ylabel(u'平均月薪',fontsize=14,color='yellow')#设置Y轴轴标题

#设置说明,位置在图的右上角

text1 = ax4.text(25,16250,u'城市总数:30(个)',fontsize=12, color='#FF00FF')#设置说明,位置在图的右上角

text2 = ax4.text(25,15100,u'月薪样本数:16946(条)',fontsize=12, color='#FF00FF')

#添加每一个城市的坐标值

list_4 = result4.sort_values(ascending=False).values

for i in range(len(list_4)):

ax4.text(i0.5,list_4[i],int(list_4[i]),color='yellow')

#设置箭头注释

arrow = plt.annotate(u'全国月薪平均值:14197元/月', xy=(4.5,14197), xytext=(7,15000),color='#9B30FF',fontsize=14,arrowprops=dict(facecolor='#FF00FF', shrink=0.05))

#设置轴刻度文字颜色为粉色

plt.tick_params(colors='pink')

可以看见,Python这个关键词下,全国16946条样本的月薪平均值为14197元/月,平均月薪排名前5的城市分别是:北京、上海、深圳、杭州、广州。哎,记得之前城市—职位数分布图么?全国30个城市中,职位数排名前5 的也是这5座城市!看来北上广深杭不仅集中了全国大部分的职位数量、连平均工资也是领跑全国的!不禁让人觉得越大越强!但是在超级大城市奋斗,买房总是遥遥无期,房子在中国人的概念里,有着特殊的情节,意味着家,老小妻儿生活的地方,给人一种安全感!我们可以看到还有不少城市的平均月薪也破万了,在这些相对小点的城市中挑一个,工作安家,买房还是有希望的,哈哈!譬如南京、武汉、苏州、大连、厦门都挺好的!

5.学历职位数量 直觉来看Python这类工作职位,应该是本科及以上经验要求居多吧?那么工作经验【不限】和【大专】的机会占比多少呢?让我们来看看! 首先,还是用df['最低学历'].value_counts()来看一下有哪些字段,以及各个字段的统计值。

df['最低学历'].value_counts()

df_最低学历=df['最低学历'].replace(['中技','其他','高中','found no element'],np.nan)

df_最低学历.value_counts()

df_最低学历.value_counts().sum()

df['df_最低学历'] = df_最低学历 #留作备用

可以看到对于学历要求,最多的集中在大专、本科、硕士、不限还有较少量的博士和中专学历,至于中技、其他、高中则连10个都不到, 对于这些10个都不到的字段,我们还是照旧用replace语句将其排除(并没有歧视低学历的意思啊囧!)可以看到排除后还剩余6个字段,共计18119个职位,下一步,还是来经典的条形分布图和饼图!

fig5 = plt.figure(5)

ax5_1 = fig5.add_subplot(2,1,1) #可选facecolor='#4f4f4f',alpha=0.3

df_最低学历.value_counts().plot(kind = 'bar',rot=0) #color='#7fc8ff'

#设置标题、x轴和y轴标题、图例文字

title = plt.title(u'最低学历——职位数分布图',fontsize = 18,color = 'yellow')

xlabel = plt.xlabel(u'最低学历',fontsize = 14,color = 'yellow')

ylabel = plt.ylabel(u'职位数量',fontsize = 14,color = 'yellow')

text1 = ax5_1.text(4.4,8200,u'职位总数:18119(条)',fontsize=14, color='#B452CD')

#设置坐标轴的的颜色和文字大小

plt.tick_params(colors='#9F79EE',labelsize=13)

#设置坐标值文字

list5 = df_最低学历.value_counts().values

for i in range(len(list5)):

ax5_1.text(i0.1,list5[i],int(list5[i]),color='yellow')

ax5_2=fig5.add_subplot(2,1,2)

xl = df_最低学历.value_counts().values

labels = list(df_最低学历.value_counts().index)

explode = tuple([0.1,0,0,0,0,0])

plt.pie(xl,explode=explode,labels=labels,autopct='%1.1f%%',textprops={'color':'#B452CD'})

plt.axis('equal')

legend = ax5_2.legend(loc='lower right',shadow=True,fontsize=12,edgecolor='#B452CD')

plt.tick_params(colors='#9F79EE',labelsize=13)

可见【本科】独占鳌头,占据了超过50%的市场!【不限】和【大专】也合计占比38%不容小觑!看起来,只要技术过硬,学历从来都不是问题!!!作为对比【硕士】占比6%,【博士】更是少到只有1%,果然稀缺到百里挑一!

6.最低学历平均月薪 按道理学历越高,平均月薪越高,类似工作经验一样都是正相关,到底是不是呢?来看一下!构造一个DataFrame(df6), 包含两列最低学历和平均月薪,我们直接用之前构造好的df中的【df_最低学历】和【df_平均月薪】即可,然后还是熟悉的groupby(df_最低学历)

df6=pd.DataFrame(data={'最低学历':df['df_最低学历'],'平均月薪':df['df_平均月薪']})

df6.info()

grouped6 = df6['平均月薪'].groupby(df6['最低学历'])

#查看grouped6的信息

grouped6.mean()

grouped6.count()

grouped6.count().sum()

matplotlib.style.use('ggplot')

fig6 = plt.figure(6,facecolor = 'black')

ax6 = fig6.add_subplot(1,1,1,facecolor='#4f4f4f',alpha=0.3)

grouped6.mean().round(1).sort_values().plot(color = 'cyan')#在条形图上叠加一个折线图

grouped6.mean().round(1).sort_values().plot(kind='bar',rot=0)

#设置标题、x轴、y轴的标签文本

title = plt.title(u'最低学历——平均月薪分布图',fontsize = 18,color = 'yellow')

xlabel= plt.xlabel(u'最低学历',fontsize = 14,color = 'yellow')

ylabel = plt.ylabel(u'平均月薪',fontsize = 14,color = 'yellow')

#添加值标签(坐标值文字)

list6 = grouped6.mean().round(1).sort_values().values

for i in range(len(list6)):

ax6.text(i0.1,list6[i],int(list6[i]),color='yellow')

#设置图例注释

text= ax6.text(0,27000,u'月薪样本数:16956(个)',fontsize=16, color='cyan')

#设置轴刻度的文字颜色

plt.tick_params(colors='#9F79EE')

平均月薪14139元,可以看到学历越高果然工资越高,博士级别的更是碾压,达到了29562元。只要学历在【大专】以上,那么平均月薪都已经过万了。 BUT,重点来了,学历并不是万能的,一个【中专】学历,有超过5年经验的,工资一定超过【本科】毕业无工作经验的。所以大家看看就好,不要当真,哈哈!

7.最低学历工作经验平均月薪 看了前面的图表,大家都知道了,学历越高平均月薪越高,工作经验越高平均月薪越高,但是我想要看看更细粒度的情形呢? 譬如我想知道【大学+无经验】和【大学+13年】工资的差别,我想看看【大专+35年】和【硕士+无经验】工资的对比究竟谁高? 现在,我不知道,但是接下来让我们把这些情况用图表呈现出来,大家就会一目了然!

df7 = pd.DataFrame(data = {'平均月薪':df['df_平均月薪'],'最低学历':df['df_最低学历'],'工作经验':df['df_工作经验']})

df7.info()

grouped7 = df7['平均月薪'].groupby([df7['最低学历'],df7['工作经验']])

#查看grouped7的信息

grouped7.mean().round(1)

grouped7.count()

grouped7.count().sum()

其实我们输入type(grouped7.mean()),会发现它是一个包含了层次化索引的Series结构。其中第一层索引是【最低学历】 第二层索引是【工作经验】,数值列【平均月薪】被这两层索引所分配!下面我们开始准备可视化,还是画一个bar柱状图,不过这次画的是多列一起呈现的形式,Y轴表示职位月薪、X轴表示最低学历,在每个学历字段下,又分别添加不同工作经验的列!

grouped7.mean().round(1)[:,'13年']

grouped7.mean().round(1)[:,'13年'].sort_values()

xlist = list(grouped7.mean().round(1)[:,'13年'].sort_values().index)

grouped7.mean().round(1)[:,'13年'].reindex(xlist)

print(xlist)

grouped7.mean()将会显示各组的平均值,round(1)表示小数点保留1位。[:,'13年']是对层次化索引的一种操作,表示选取 grouped7.mean()中索引名字为'工作经验'下'13年字段'的所有值。此处构造了列表xlist,值是筛选后的'最低学历'索引, xlist将用于画条形图时X轴坐标的标签文本(表示最低学历),Y轴相对应的是平均月薪。工作经验则用条形图和图例展示。

#开始画图,设置基本参数

matplotlib.style.use('dark_background')

fig7 = plt.figure(7,facecolor = 'black')

ax7 = fig7.add_subplot(1,1,1,facecolor='#4f4f4f',alpha=0.3)

title = plt.title(u'最低学历工作经验平均月薪分布图',fontsize = 18,color = 'yellow')

xlabel = plt.xlabel(u'最低学历',fontsize = 14,color = 'yellow')

ylabel = plt.ylabel(u'平均月薪',fontsize = 14,color = 'yellow')

plt.tick_params(colors='cyan')

#ylist1~7分别是7种条形图的Y值列表

ylist1 = grouped7.mean().round(1)[:,'无经验'].reindex(xlist).values

ylist2 = grouped7.mean().round(1)[:,'1年以下'].reindex(xlist).values

ylist3 = grouped7.mean().round(1)[:,'不限'].reindex(xlist).values

ylist4 = grouped7.mean().round(1)[:,'13年'].reindex(xlist).values

ylist5 = grouped7.mean().round(1)[:,'35年'].reindex(xlist).values

ylist6 = grouped7.mean().round(1)[:,'510年'].reindex(xlist).values

ylist7 = grouped7.mean().round(1)[:,'10年以上'].reindex(xlist).values

#img1~img7分别表示7种条形图

ind = np.arange(6)#ind为x轴宽度,用numpy的array形式表示

width = 0.1#条形图的宽度,要合理设置否则太宽会摆不下

img1 = ax7.bar(ind,ylist1,width)

img2 = ax7.bar(ind+width,ylist2,width)

img3 = ax7.bar(ind+width*2,ylist3,width)

img4 = ax7.bar(ind+width*3,ylist4,width)

img5 = ax7.bar(ind+width*4,ylist5,width)

img6 = ax7.bar(ind+width*5,ylist6,width)

img7 = ax7.bar(ind+width*6,ylist7,width)

#设置X轴文本和位置调整

ax7.set_xticklabels(xlist)

ax7.set_xticks(ind + width / 2)

#设置文字说明

text1 = ax7.text(4.05,52100,u'数据来源:智联招聘',fontsize=13, color='#9F79EE')

text2 = ax7.text(4.05,50200,u'职位关键词:Python',fontsize=13, color='#9F79EE')

text3 = ax7.text(4.05,48200,u'工作城市:全国30座城市',fontsize=13, color='#9F79EE')

text4 = ax7.text(4.05,46200,u'职位数量:共计16956(条)',fontsize=13, color='#9F79EE')

#设置图例

ax7.legend((img1[0],img2[0],img3[0],img4[0],img5[0],img6[0],img7[0]), (u'无经验',u'1年以下',u'不限',u'13年',u'35年',u'510年',u'10年以上'),fontsize=13,facecolor='black')

#设置栅格

plt.grid(True)

最后,上一张简单词云图给大家看看,用的BDP傻瓜式制作,看看就好!

其实展开了还可以分析的东西有不少,譬如Pandas、Matplotlib的用法,譬如更多维度的分析和两两组合! 好了,整体的先暂时分析到这,总结一下呢就是:Python+工作经验+学历+大城市 = 高薪!但是,工作经验、学历和城市其实并没那么重要, 关键要看自己的Python用的6不6,关键在于你知道自己想做什么,知道自己能做什么,知道自己做出了什么!哈哈,当你知道越来越接近这些问题的答案呢,那么我相信,薪水对你来说已经不那么重要了!(当然,高薪是必须有的!) 人生苦短,我用Python!

最后,插播一条小广告,个人创建了Python、Java的专栏:

Java、Python和数据分析Java从入门到实践 欢迎Python和Java爱好者、初学者关注,一起学习共同进步~

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com