初学者数据分析——Python职位全链路分析

最近在做Python职位分析的项目,做这件事的背景是因为接触Python这么久,还没有对Python职位有一个全貌的了解。所以想通过本次分析了解Python相关的职位有哪些、在不同城市的需求量有何差异、薪资怎么样以及对工作经验有什么要求等等。分析的链路包括:

  • 数据采集

  • 数据清洗

  1. 异常的创建时间
  2. 异常的薪资水平
  3. 异常的工作经验
  • 统计分析
  1. 大盘数据
  2. 单维度分析
  3. 二维交叉分析
  4. 多维钻取
  • 文本分析
  1. 文本预处理
  2. 词云
  3. FP-Growth关联分析
  4. LDA主题模型分析

分为上下两篇文章。上篇介绍前三部分内容,下篇重点介绍文本分析。

0. 数据采集

巧妇难为无米之炊,我们做数据分析大部分情况是用公司的业务数据,因此就不需要关心数据采集的问题。然而我们自己业余时间做的一些数据探索更多的需要自己采集数据,常用的数据采集技术就是爬虫

本次分享所用的数据是我从拉勾网爬取的,主要分为三部分,确定如何抓取数据、编写爬虫抓取数据、将抓取的数据格式化并保存至MongoDB。关于数据采集这部分内容我之前有一篇文章单独介绍过,源码也开放了,这里我就不再赘述了,想了解的朋友可以翻看之前那篇文章《Python爬职位》

1. 数据清洗

有了数据后,先不要着急分析。我们需要对数据先有个大概的了解,并在这个过程中剔除一些异常的记录,防止它们影响后续的统计结果。

举个例子,假设有101个职位,其中100个的薪资是正常值10k,而另外一个薪资是异常值1000k,如果算上异常值计算的平均薪资是29.7k,而剔除异常值计算的平均薪资是10k,二者差了将近3倍。

所以我们在作分析前要关注数据质量,尤其数据量比较少的情况。本次分析的职位数有1w条左右,属于比较小的数据量,所以在数据清洗这一步花了比较多的时间。

下面我们就从数据清洗开始,进入编码阶段

1.0 筛选python相关的职位

导入常用库

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pymongo import MongoClient

from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']  #解决seaborn中文字体显示问题
%matplotlib inline
复制代码

MongoDB读取数据

mongoConn = MongoClient(host='192.168.29.132', port=27017)
db = mongoConn.get_database('lagou')
mon_data = db.py_positions.find()
# json转DataFrame
jobs = pd.json_normalize([record for record in mon_data])
复制代码

预览数据

jobs.head(4)
复制代码

打印出jobs的行列信息

jobs.info()
复制代码

一共读取了1.9w个岗位,但这些岗位里并不都是跟Python相关的。所以我们首先要做的就是筛选Python相关的职位,采用的规则是职位标题或正文包含python字符串

# 抽取职位名称或者职位正文里包含 python 的
py_jobs = jobs[(jobs['pName'].str.lower().str.contains("python")) | (jobs['pDetail'].str.lower().str.contains("python"))]

py_jobs.info()
复制代码

筛选后,只剩下10705个岗位,我们继续对这部分岗位进行清洗。

1.1 按照创建时间清洗异常值

对 “职位创建时间” 维度清洗主要是为了防止有些创建时间特别离谱的岗位混进来,比如:出现了2000年招聘的岗位。

# 创建一个函数将职位创建时间戳转为月份
import time
def timestamp_to_date(ts):
    ts = ts / 1000
    time_local = time.localtime(ts)
    return time.strftime("%Y-%m", time_local)
    
# 增加'职位创建月份'一列
py_jobs['createMon'] = py_jobs['createTime'].map(timestamp_to_date)

# 按照职位id、创建月份分组计数
py_jobs[['pId', 'createMon']].groupby('createMon').count()
复制代码

不同月的职位

创建timestamp_to_date 函数将“职位创建时间”转为“职位创建月份”,然后按“职位创建月份”分组计数。从结果上看,职位创建的时间没有特别离谱的,也就是说没有异常值。即便如此,我仍然对职位创建时间进行了筛选,只保留了10、11、12三个月的数据,因为这三个月的职位占了大头,并且我只想关注新职位。

# 只看近三个月的职位
py_jobs_mon = py_jobs[py_jobs['createMon'] > '2020-09']
复制代码

1.2 按照薪资清洗异常值

对薪资进行清洗主要是防止某些职位的薪资特别离谱。这块主要考察3个特征:薪资高的离群点、薪资低的离群点和薪资跨度较大的。

首先,列出所有的薪资

py_jobs_mon[['pId', 'salary']].groupby('salary').count().index.values
复制代码

以薪资高的离群点为例,观察是否有异常值

# 薪资高的离群值
py_jobs_mon[py_jobs_mon['salary'].isin(['150k-200k
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值