2019-05-14 20:49:54 xiaohuimary 阅读数 65
  • Python数据分析课程

    通过学习此课程,可以掌握Python的大数据分析。语法规则、常见通用库的使用,并在老师的带领下做出自己的智能语音机器人。在积累了一定的语言基础上具备成为专业Python工程师的能力。并可以深入全面学习Python爬虫及Flask的核心知识,包括常用网络库、分析库、Selenium、Scrapy等框架,Flask基础知识、Restful API、模板、表单等。 您观看课程学习后 免费入群领取【超全Python资料包+17本学习电子书】

    1884 人正在学习 去看看 王稳

python数据分析

python数据分析是目前python最火的方向之一,为了解目前市场对该职位的需求,我们爬取了拉钩上对pythons数据分析的招聘信息。

环境

系统:windows7

python版本:3.7.1

爬虫分析

1.谷歌浏览器打开拉钩官网https://www.lagou.com/,搜索框中输入要查询的职位,右键点击检查,找到名为position
Ajax.json?needAddtionalResult=false的链接,这就是我们要重点分析的地方。

图片
抱着侥幸心理我们将链接https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false输入浏览器中,
发现提示:{“status”:false,“msg”:“您操作太频繁,请稍后再访问”,“clientIp”:“113.57.183.6”,“state”:2402}
可见想要获取信息不是那么简单。

2.分析报文

首先发送get请求,获取session

图片

session更新,发送post请求

图片

图片

比较发现get请求和pos请求参数一致,这无疑减少了我们的工作量

图片

图片

图片

分析翻页,点击下一页则会新增一天get请求,并且Form Data中的pn则会加1,这是翻页的关键

图片

图片

分析数据结构,选择需要存储的信息

图片

分析完报文后就理清了我们的爬虫思路,首先构造get请求获取session;;更新session,发送post请求;通过改变Form Data中的pn值
实现翻页循环;获取并存储数据

代码实现

1.构造get请求

def get_json(url, data):
    # 构造随机请求头
    for i in range(100):
        ua = UserAgent()
        # print(ua.random)

    my_headers = {
        # "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
        # "Chrome/67.0.3396.99 Safari/537.36",
        "User-Agent": "ua.random",
        "Referer": "https://www.lagou.com/jobs/list_python%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90"
                   "?city=%E5%85%A8%E5%9B%BD&cl=false&fromSearch=true&labelWords=&suginput=",
        "Content-Type": "application/json;charset=UTF-8"}

get请求主要由User_Agent, Referer和Content-Type组成,其中后两者可从上文报文中获取,为减少爬虫次数过多而被封,我们可通过
UserAgent构造随机请求头。UserAgent可通过pip install fake_useragent获得。下图是随机生成的请求头。

图片

2.获取并更新session,发送post请求

 # 获取session
    session = requests.session()
    # 更新
    session.headers.update(my_headers)
    session.get(
        "https://www.lagou.com/jobs/list_python%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90"
        "?city=%E5%85%A8%E5%9B%BD&cl=false&fromSearch=true&labelWords=&suginput=")
    content = session.post(url=url, data=data)

3.构造翻页

    for num in range(1, page + 1):
        url = 'https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false'
        data = {
            'first': 'false',
            'pg': num,
            'kd': 'python数据分析',
        }

4.存储数据

# 创建workbook,即excel
        workbook = xlwt.Workbook(encoding='utf-8')
        # 创建表,第二参数用于确认同一个cell单元是否可以重设值
        worksheet = workbook.add_sheet('python数据分析', cell_overwrite_ok=True)
        for i, row in enumerate(info_result):
            # print(row)
            for j, col in enumerate(row):
                # print(col)
                worksheet.write(i, j, col)
        workbook.save('python数据分析.xls')

以上就是爬虫总体代码思路,完整代码如下:

#!/usr/bin/env python
# encoding: utf-8
"""
@author: xiaohui
@contact: xiaohui1295371450@163.com
@file: crawl.py
@time: 2019-05-14 10:44
@desc: crawl data on lagou
"""
import json
import requests
import xlwt
import time
from fake_useragent import UserAgent

# 获取存储职位信息的json对象,遍历获得城市、公司名称、工作地点、学历要求、职位名称、薪资、工作年限


def get_json(url, data):
    # 构造随机请求头
    for i in range(100):
        ua = UserAgent()
        print(ua.random)

    my_headers = {
        # "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
        # "Chrome/67.0.3396.99 Safari/537.36",
        "User-Agent": "ua.random",
        "Referer": "https://www.lagou.com/jobs/list_python%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90"
                   "?city=%E5%85%A8%E5%9B%BD&cl=false&fromSearch=true&labelWords=&suginput=",
        "Content-Type": "application/json;charset=UTF-8"}
    time.sleep(5)
    # 获取session
    session = requests.session()
    # 更新
    session.headers.update(my_headers)
    session.get(
        "https://www.lagou.com/jobs/list_python%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90"
        "?city=%E5%85%A8%E5%9B%BD&cl=false&fromSearch=true&labelWords=&suginput=")
    content = session.post(url=url, data=data)
    result = content.json()
    info = result['content']['positionResult']['result']
    info_list = []
    information = []
    for job in info:
        # 城市
        information.append(job['city'])
        # 公司全名
        information.append(job['companyFullName'])
        # 工作地点
        information.append(job['district'])
        # 学历要求
        information.append(job['education'])
        # 职位名称
        information.append(job['positionName'])
        # 薪资
        information.append(job['salary'])
        # 工作年限
        information.append(job['workYear'])
        info_list.append(information)
    return info_list


def main():
    page = int(input('输入爬取的页码总数:'))
    info_result = []
    title = ['城市', '公司全名', '工作地点', '学历要求', '职位名称', '薪资', '工作年限']
    info_result.append(title)
    for num in range(1, page + 1):
        url = 'https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false'
        data = {
            'first': 'false',
            'pg': num,
            'kd': 'python数据分析',
        }
        try:
            info = get_json(url, data)
            info_result = info_result + info
            print("第%s页爬取成功" % num)
        except Exception as msg:
            print("第%s页爬取失败" % num)

        # 创建workbook,即excel
        workbook = xlwt.Workbook(encoding='utf-8')
        # 创建表,第二参数用于确认同一个cell单元是否可以重设值
        worksheet = workbook.add_sheet('python数据分析', cell_overwrite_ok=True)
        for i, row in enumerate(info_result):
            # print(row)
            for j, col in enumerate(row):
                # print(col)
                worksheet.write(i, j, col)
        workbook.save('python数据分析.xls')


if __name__ == '__main__':
    main()

分析我们获得的excel数据,主要招聘地依旧集中在北京、上海和广州,薪资集中在15k-30k之间,可以说情景不错。
这不失为度过目前互联网寒冬的一种选择。

附:完整代码和爬虫数据结果
提取码:n9d9

2018-07-18 22:47:50 qq_41199755 阅读数 1587
  • Python数据分析课程

    通过学习此课程,可以掌握Python的大数据分析。语法规则、常见通用库的使用,并在老师的带领下做出自己的智能语音机器人。在积累了一定的语言基础上具备成为专业Python工程师的能力。并可以深入全面学习Python爬虫及Flask的核心知识,包括常用网络库、分析库、Selenium、Scrapy等框架,Flask基础知识、Restful API、模板、表单等。 您观看课程学习后 免费入群领取【超全Python资料包+17本学习电子书】

    1884 人正在学习 去看看 王稳

1.待分析的数据

是从智联招聘平台上手动爬取的python数据分析职位的相关信息,表的关键字分别为“薪金”、“学历”、“经验”。为后续数据分析做准备。数据部分截图,所示

智联招聘平台爬取‘python数据分析’职位,记录总共有500多条,其中包括一小部分重复发布的记录。考虑到数据量本身比较小,在此不对重复数据进行筛选。对关键字“学历”、“经验”,分别进行统计,发现其对应频率分别如下:

发现学历一栏“不限”和“中专”相对比较少,打印出内容,发现学历为“不限”的工资与学历“本科”比较接近,“中专”工资与“大专”比较接近,并无多大区别,因此修改dataframe中,将”不限”修改为“本科”,“中专”修改为“大专”。调用pandas的replace()函数

details.replace({'education': '不限'}, '本科', inplace=True)
details.replace({'education': '中专'}, '大专', inplace=True)

details为原始数据表。注意,如果不想建立dataframe副本,可以设置inplace=True,直接修改原始dataframe.

同样道理,“无经验”,”1年以下“的工资和经验"不限”接近,同样可以合并。

details.replace({'experience': '无经验'}, '不限', inplace=True)
# 可以这样做,因为不影响数据使用
details.replace({'experience': '1年以下'}, '不限', inplace=True)

“10年以上”,在本记录中只有一条数据,而且工资与其他差别很大,若将其并入“5-10”年,会直接拉高平均记录值,因此将其舍弃。

2.数据处理。

数据处理主要是分离将工资一栏分离得到,最低工资,最高工资,并分别将最低工资平均值,最高工资平均值,添加到学历,经验要求相同,工资为“面议”。为后续进行工资与学历,经验的关系做准备。

先把同等学历,经验要求的数据分开,代码如下:

# data_whole 是根据学历,经验筛选出的数据

# data_salary则是给出实际工资的数据

# data_negia是工资为“面议”的数据

data_whole = data[(data['experience'] == experience) & (data['education'] == education)]
data_salary = data_whole[~ data_whole['salary'].isin(['面议'])]
data_negia = data_whole[data_whole['salary'].isin(['面议'])]

这里在爬取数据时有一点需要注意的地方,我们在爬取数据时,往往需要用到python自带的一个小函数strip(),用于去掉字符串首尾的空格或者换行符,注意只能是首尾,不可以去除字符串中间空格。str.strip(). 原因是,我在抓取工资时,“面议“后面跟着一个空格,也就是我抓取的数据是”面议 ”,而不是"面议”。因此,我在判断isin(["面议“])

以下代码应根据具体爬取的数据分类讨论,我这里的数据,同一组条件,一定会出现给出工资的记录,但是不一定会出现工资为"面议”的记录,因此判断逻辑如下:

if len(data_salary) > 0:
    data_salary.reset_index(drop=True, inplace=True)
    low_salary, high_salary = split_salary(data_salary['salary'].apply(get_salary))
    data_salary.insert(3, 'low_salary', low_salary)
    data_salary.insert(4, 'high_salary', high_salary)
    salary = data_salary.drop('salary', axis=1)
    # 如果面议表中有数据
    if len(data_negia) > 0 :
        data_negia.reset_index(drop=True, inplace=True)
        data_negia.insert(3, 'low_salary', round(low_salary.mean()))
        data_negia.insert(4, 'high_salary', round(high_salary.mean()))
        salary = pd.concat([data_salary, data_negia], axis=0, ignore_index=True)
        salary.drop('salary', inplace=True, axis=1)

重要:data_salary.reset_index(drop=True, inplace=True)这句代码很重要,如果不重新对data_salary()索引进行排序,data_salary是从data_whole分离得到,索引并不会从0重新分布,而是保留data_whole的索引。如果不重新排列索引,在将最低工资,最高工资新插入data_salary,因为最低(高)工资的索引是从0开始,与data_salary索引不一致,因此会插入失败。个人理解,dataframe.insert()必须两者索引严格保持一致才可以插入列成功。

# split_salary()函数,是分别得到最低工资,最高工资

 # get_salary()是获取具体的最低工资,最高工资金额。代码如下:

def get_salary(value):
    index_sep = value.find('-')
    index_end = value.find('元')
    return int(value[0:index_sep]), int(value[index_sep+1:index_end])
ef split_salary(tuple_list):
    try:
        if len(tuple_list) > 0:
            low_list = []
            high_list = []
            for tup in tuple_list:
                low = tup[0]
                high = tup[1]
                low_list.append(low)
                high_list.append(high)
        return pd.Series(low_list), pd.Series(high_list)
    except Exception:
        print('分离得到最低最高公资时出错')

3.完整代码

import pandas as pd

def read_csv(filename):
    details = pd.read_csv(filename, sep=',', encoding='gb18030')
    details.replace({'experience': '无经验'}, '不限', inplace=True)
    # 可以这样做,因为不影响数据使用
    details.replace({'experience': '1年以下'}, '不限', inplace=True)
    # 已经查看数据,并无区别
    details.replace({'education': '不限'}, '本科', inplace=True)
    details.replace({'education': '中专'}, '大专', inplace=True)
    # 3-5年都有面议
    salart_3to5 = pd.concat([handle_no_salary(details, '3-5年', '本科'), handle_no_salary(details, '3-5年', '硕士'),
                             handle_no_salary(details, '3-5年', '大专')], axis=0,ignore_index=True)
    # 经验不限的无面议
    salart_noexper = pd.concat([handle_no_salary(details, '不限', '本科'), handle_no_salary(details, '不限', '硕士'),
                                handle_no_salary(details, '不限', '大专')], axis=0, ignore_index=True)

    # 5-10年,没有硕士
    salary_5to10 = handle_no_salary(details, '5-10年', '本科')

    # 1-3年,都有面议
    salary_1to3 = pd.concat([handle_no_salary(details, '1-3年', '本科'), handle_no_salary(details, '1-3年', '硕士'),
                             handle_no_salary(details, '1-3年', '大专')], axis=0,ignore_index=True)

    salary_all = pd.concat([salart_3to5, salart_noexper, salary_5to10, salary_1to3], axis=0, ignore_index=True)
    print(len(salary_all))
    # 把最低,最高公资填进去,并且把平均工资填进面议一栏


def get_salary(value):
    index_sep = value.find('-')
    index_end = value.find('元')
    return int(value[0:index_sep]), int(value[index_sep+1:index_end])


def split_salary(tuple_list):
    try:
        if len(tuple_list) > 0:
            low_list = []
            high_list = []
            for tup in tuple_list:
                low = tup[0]
                high = tup[1]
                low_list.append(low)
                high_list.append(high)
        return pd.Series(low_list), pd.Series(high_list)
    except Exception:
        print('分离得到最低最高公资时出错')


def handle_no_salary(data, experience, education):
    data_whole = data[(data['experience'] == experience) & (data['education'] == education)]
    # 剔除面议的工资,填进去
    data_salary = data_whole[~ data_whole['salary'].isin(['面议'])]
    data_negia = data_whole[data_whole['salary'].isin(['面议'])]
    if len(data_salary) > 0:
        data_salary.reset_index(drop=True, inplace=True)
        low_salary, high_salary = split_salary(data_salary['salary'].apply(get_salary))
        data_salary.insert(3, 'low_salary', low_salary)
        data_salary.insert(4, 'high_salary', high_salary)
        salary = data_salary.drop('salary', axis=1)
        # 如果面议表中有数据
        if len(data_negia) > 0 :
            data_negia.reset_index(drop=True, inplace=True)
            data_negia.insert(3, 'low_salary', round(low_salary.mean()))
            data_negia.insert(4, 'high_salary', round(high_salary.mean()))
            salary = pd.concat([data_salary, data_negia], axis=0, ignore_index=True)
            salary.drop('salary', inplace=True, axis=1)
    # axis = 0, 按照列对齐,ignore_index=True, 忽略两列表之前的索引,重新设置从0开始的索引
    # 在某些函数,必须指定axis, 否则就会找不到一些索引而报错
        print(experience, len(data_whole), len(data_salary), len(data_negia), len(salary))
        return salary

if __name__ == '__main__':
    read_csv("relation.csv")

4.我是数据分析小白,入手简单项目,围绕项目学习知识,是编程的最有效的途径。会遇到各种各样的问题,比如,因为事先不知道数据的分布特征,“本科”,“硕士”,“不限”,“中专”,”大专“,只理所当然考虑了”本科“,”硕士“这两种情况。因此,在进行数据处理前,最好利用value_counts()函数,看一下,每一列不同取值的大概分布。第一篇,内容估计有点乱,不过也算是往前迈了一大步。

2018-12-20 16:02:29 zwx19921215 阅读数 653
  • Python数据分析课程

    通过学习此课程,可以掌握Python的大数据分析。语法规则、常见通用库的使用,并在老师的带领下做出自己的智能语音机器人。在积累了一定的语言基础上具备成为专业Python工程师的能力。并可以深入全面学习Python爬虫及Flask的核心知识,包括常用网络库、分析库、Selenium、Scrapy等框架,Flask基础知识、Restful API、模板、表单等。 您观看课程学习后 免费入群领取【超全Python资料包+17本学习电子书】

    1884 人正在学习 去看看 王稳

python数据分析入门,作为入门文章系列主要包含以下几个内容:

1.数据的来源(本案例采用的数据来自于上一篇文章中爬取的智联招聘信息):读取数据库数据、数据写入csv文件、读取csv文件等

2.数据的处理:对载入到内存的数据进行一系列的操作(处理总共包含清洗、过滤、分组、统计、排序、计算平均数等一系列操作,本文只简单涉及了其中某几个)

3.对处理后的数据进行可视化分析等

# !/usr/bin/env python
# -*-coding:utf-8-*-
"""
@Author  : xiaofeng
@Time    : 2018/12/19 15:23
@Desc : Less interests,More interest.(数据分析入门)
@Project : python_appliction
@FileName: analysis1.py
@Software: PyCharm
@Blog    :https://blog.csdn.net/zwx19921215
"""
import pymysql as db
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib as mpl
import matplotlib.pyplot as plt

# mysql config
mysql_config = {
    'host': '110.0.2.130',
    'user': 'test',
    'password': 'test',
    'database': 'xiaofeng',
    'charset': 'utf8'
}

"""
read data from mysql and write to local file
(从数据库中读取数据写入本地文件)
@:param page_no
@:param page_size
@:param path 文件写入路径
"""


def read_to_csv(page_no, page_size, path):
    # read from database
    database = db.connect(**mysql_config)
    if page_no > 1:
        page_no = (page_no - 1) * page_size
    else:
        page_no = 0
    sql = 'select * from zhilian limit ' + str(page_no) + ',' + str(page_size) + ''
    df = pd.read_sql(sql, database)
    print(df)
    database.close()
    # write to csv
    local = path
    df.to_csv(local, encoding='gbk')


"""
read data from remote address or local address
(读取文件从远程地址或者本地)
"""


def read_from_csv(path):
    # remote address
    # data_url = 'https://xxxx/zhilian.csv'
    # local address
    # data_url = 'G:/zhilian.csv'
    df = pd.read_csv(path, encoding='gbk')
    return df


"""
数据集的简单(过滤、分组、排序)处理
"""


def simple_op(path):
    df = read_from_csv(path)
    # top 10 :获取前10行
    print('--------------top 10-----------')
    top = df.head(10)
    print(top)
    # tail 10:获取后10行
    print('------------tail 10------------')
    tail = df.tail(10)
    print(tail)
    # filter:根据指定条件过滤
    print('-------------filter----------')
    special_jobid = df[df.JobID == 595950]
    print(special_jobid)
    special = df[(df.id >= 110) & (df.PublishDate == '2018-12-18')]
    print(special)
    # check :检查各列缺失情况
    print('-------------check----------------')
    check = df.info()
    print(check)
    print('--------------data describe-----------')
    # count,平均数,标准差,中位数,最小值,最大值,25 % 分位数,75 % 分位数
    describe = df.describe()
    print(describe)
    # 添加新列
    df2 = df.copy()
    df2['AnnualSalaryAvg'] = (df['AnnualSalaryMax'] + df['AnnualSalaryMin']) / 2
    # 重新排列指定列
    columns = ['JobID', 'JobTitle', 'CompanyName', 'AnnualSalaryMin', 'AnnualSalaryMax', 'AnnualSalaryAvg']
    df = pd.DataFrame(df2, columns=columns)
    print(df)


"""
可视化分析
"""


def visualized_analysis(path):
    df = read_from_csv(path)
    df_post_count = df.groupby('JobLactionStr')['AnnualSalaryMax'].count().to_frame().reset_index()
    # subplots(1, 1) 表示1x1个子图,figsize=(25, 8) 子图的宽度和高度
    # f, [ax1,ax2] = plt.subplots(1, 2, figsize=(25, 8)) 表示1x2个子图
    f, ax2 = plt.subplots(1, 1, figsize=(25, 8))

    sns.barplot(x='JobLactionStr', y='AnnualSalaryMax', palette='Greens_d', data=df_post_count, ax=ax2)
    ax2.set_title('各城市职位数量对比', fontsize=15)
    ax2.set_xlabel('城市')
    ax2.set_ylabel('数量')
    # 用来正常显示中文标签
    plt.rcParams['font.sans-serif'] = ['SimHei']
    # 用来正常显示负号
    plt.rcParams['axes.unicode_minus'] = False
    plt.show()


if __name__ == '__main__':
    path = 'G:/zhilian.csv'
    read_to_csv(0, 100, path)
    df = read_from_csv(path)
    simple_op(path)
    visualized_analysis(path)

控制台输出如下:

 

写入本地csv文件效果如下:

 

可视化效果如下:

 

注:由于是入门文章第一篇,所以并没有对数据分析做过深的探索,更深层次的研究将会在后续系列中呈现!

2019-12-11 09:40:22 qq_45503162 阅读数 226
  • Python数据分析课程

    通过学习此课程,可以掌握Python的大数据分析。语法规则、常见通用库的使用,并在老师的带领下做出自己的智能语音机器人。在积累了一定的语言基础上具备成为专业Python工程师的能力。并可以深入全面学习Python爬虫及Flask的核心知识,包括常用网络库、分析库、Selenium、Scrapy等框架,Flask基础知识、Restful API、模板、表单等。 您观看课程学习后 免费入群领取【超全Python资料包+17本学习电子书】

    1884 人正在学习 去看看 王稳

现在Python数据分析是这个方向越来越受到重视,一般的大型互联网公司都会有这个岗位,毕竟在互联网的世界里数据是基础,所以,很多人看好Python数据分析师这个岗位,想从事数据分析,那么数据分析都需要有什么基础呢?
首先,我们以企业对应的岗位JD来作为学习的向导,应该是最准确的。我们来看看某招聘网站上的岗位要求:

我们来总结一下:
分析工具:一般要求SPSS/SAS/R/Python等分析工具至少会一种,会两种以上加分,有的企业因内部需求,会指定的一种;


数据库:绝大会要求会SQL,部分要求SQL/NoSQL会一种,高级的分析师或者大型企业要求能够处理大数据,需要Hive(较少的需要Hadoop/Spark);


统计学:若无相关专业背景,需要具备相应的统计学、概率论等基础知识;


数据挖掘:少部分要求会建模,了解基本的算法模型,能够做数据预测,即便不要求,算法也是加分项;


结果输出:Excel/PPT/Tableau。Excel和PPT要求的比较多,主要用作常规的数据呈现,与业务部门沟通等,Tableau一般作为可视化或者分析工具的加分项或者要求之一;


业务/思维:对某个领域(如电商、金融等)相关业务的了解或具有产品、运营方向的分析经验,有自己的数据分析的方法论和项目经验,具备Data Sence。


如果说真正当一个初级数据分析,起码你要会熟练运用用Excel,掌握Python中numpy、pandas和matplotlib的一些基本操作,可以做基本的数据分析处理和可视化,进行探索性的数据分析,观察数据分布、计算各种统计量,得出一些基本的结论,最最基础的还是统计学知识。
统计学在大学中一般都会有相应课程,一定要好好学习,如果是已经毕业的人员,那么就赶紧复习去吧。

零基础系统的学习路线大刚内容可以点击有道云笔记链接了解:

http://note.youdao.com/noteshare?id=e4fa02e7b56d7909a27674cdb3da08aa

 

2019-12-28 18:07:32 weixin_45221012 阅读数 7
  • Python数据分析课程

    通过学习此课程,可以掌握Python的大数据分析。语法规则、常见通用库的使用,并在老师的带领下做出自己的智能语音机器人。在积累了一定的语言基础上具备成为专业Python工程师的能力。并可以深入全面学习Python爬虫及Flask的核心知识,包括常用网络库、分析库、Selenium、Scrapy等框架,Flask基础知识、Restful API、模板、表单等。 您观看课程学习后 免费入群领取【超全Python资料包+17本学习电子书】

    1884 人正在学习 去看看 王稳

职位分析

链接个人博客(有效期至2020年6月)可以看到更好的可视化效果。

加载并探索数据

import pandas as pd
import sqlite3

conn = sqlite3.connect('recruit.db')
job_df = pd.read_sql('select * from recruit',conn)

基本信息:

(1)welfare和address有缺失
(2)数据类型为object

job_df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 95647 entries, 0 to 95646
Data columns (total 12 columns):
id              95647 non-null int64
info_source     95647 non-null object
job_name        95647 non-null object
min_salary      95647 non-null object
max_salary      95647 non-null object
city            95647 non-null object
compnay_name    95647 non-null object
welfare         92713 non-null object
work_years      95647 non-null object
education       95647 non-null object
address         94534 non-null object
job_detail      95647 non-null object
dtypes: int64(1), object(11)
memory usage: 4.7+ MB
job_df.head(5)
id info_source job_name min_salary max_salary city compnay_name welfare work_years education address job_detail
0 1665 1 Python开发工程师 15000.0 20000.0 北京-海淀区 融捷教育科技有限公司 无工作经验 招1人 北京市海淀区清华科技园科技大厦B座 1.精通Python,有python web开发经验,熟练使用Flask开发框架,掌握主流关...
1 1666 1 高级测试工程师 4500.0 6000.0 中山 房源控股 带薪年假,专业培训,绩效奖金,全勤奖,年底分红,五险一金,节日福利,交通补贴,通讯补贴,弹性工作 3-4年经验 大专 火炬开发区创意港B1702楼 招聘城市:深圳,广州,中山\n【岗位职责】:\n1、负责移动端及网站产品的功能测试;\n2、...
2 1667 1 技术支持工程师(运维) 3500.0 4500.0 河源 北京海鑫科金高科技股份有限公司 五险一金,补充医疗保险,交通补贴,餐饮补贴,通讯补贴,绩效奖金,定期体检,年终奖金 1年经验 大专 河源市区 岗位职责:\n1. 负责系统安装、调试与维护;\n2. 负责系统日常监控、数据备份与恢复;\...
3 1668 1 网络安全工程师(应届毕业生) 7000.0 9000.0 东莞-虎门镇 东莞沛顿科技有限公司 五险一金,专业培训,年终奖金 无工作经验 本科 赤岗社区骏马路2号中国电子产业园深科技园区 1. 网络及信息安全体系的策略制定;\n2. 网络及信息安全文档编写及体系推进;\n3. 网...
4 1669 1 软件测试 4000.0 6000.0 汕头 阿米巴网络科技有限公司 五险,餐饮补贴,年终奖金,全勤奖,定期体检,弹性工作,专业培训,绩效奖金 3-4年经验 大专 汕头市龙湖区奋发园主楼501 岗位职责:\n1、根据软件设计需求制定测试计划,分析需求,设计测试数据和测试用例;\n2、有...
job_df.tail(3)
id info_source job_name min_salary max_salary city compnay_name welfare work_years education address job_detail
95644 104924 3 测试经理 10000 15000 武汉 中诚信征信有限公司 五险一金,年底双薪,定期体检,节日礼物 3年以上 本科及以上 礼士胡同54号 岗位职责:,1. 负责测试团队建设,测试技能、自动化工具的不断完善,提高团队专业能力...
95645 104925 3 供需管理 8333 10000 武汉 每日优鲜 2018互联网300强,国家高新技术企业认定,独角兽,2018中国创新成长百强,2018德勤... 2年以上 统招本科 花样年喜年中心 职责描述:,1. 基于历史数据,通过对时间、天气和促销等内外因素分析,建立数据模型,对单仓单...
95646 104926 3 XMC -- 数据分析工程师(J10622) 8333 15000 武汉 武汉新芯集成电路制造有限公司 带薪年假,午餐补助,定期体检,免费班车,技能培训,五险一金,生育补贴,子女福利,发展空间大,... 3年以上 本科及以上 武汉市东湖新技术开发区高新四路18号 工作职责:,1.\t负责生产数据分析相关系统开发及维护。,2.\t通过业务数据分析,发掘用户...

不同学历职位分布

job_df.loc[:, ['education']].groupby('education').size()
education
12-30发布        1
中专           229
中技            17
其他             2
初中及以下          6
博士           482
博士后           33
大专         13648
大专及以上       3594
学历不限        3605
招10人         123
招11人           1
招12人           6
招15人          14
招1人         2103
招20人          16
招25人           1
招2人         1061
招30人           3
招3人          414
招41人           1
招4人          101
招50人           9
招5人          240
招6人           40
招77人           1
招7人            5
招8人           18
招9人            1
招若干人        1748
本科         35782
本科及以上      16756
硕士          3649
硕士及以上       2784
统招本科        9127
高中            26
dtype: int64

按学历规约

博士:博士、博士及以上;
硕士: 硕士、硕士及以上;
本科:本科、本科及以上、统招本科;
大专:大专、大专及以上;
中专:中专、中技、高中;
其他:发布、招

job_df.loc[job_df['education'] == '博士后', 'education'] = '博士'
job_df.loc[job_df['education'] == '硕士及以上', 'education'] = '硕士'
job_df.loc[job_df['education'] == '本科及以上', 'education'] = '本科'
job_df.loc[job_df['education'] == '统招本科', 'education'] = '本科'
job_df.loc[job_df['education'] == '大专及以上', 'education'] = '大专'
job_df.loc[job_df['education'] == '中技', 'education'] = '中专'
job_df.loc[job_df['education'] == '高中', 'education'] = '中专'
job_df.loc[job_df['education'].str.contains('招') | job_df['education'].str.contains('发布') | job_df['education'].str.contains('初中'), 'education'] = '其他'

按学历规约后

education_size = job_df.loc[:, ['education']].groupby('education').size()
education_size
education
中专        272
其他       5915
博士        515
大专      17242
学历不限     3605
本科      61665
硕士       6433
dtype: int64
dct = dict(education_size)
lst = [[dt, int(dct[dt])] for dt in dct]
lst
[['中专', 272],
 ['其他', 5915],
 ['博士', 515],
 ['大专', 17242],
 ['学历不限', 3605],
 ['本科', 61665],
 ['硕士', 6433]]
from pyecharts.charts import Pie
from pyecharts import options as opts


def pie_rich_label(lt) -> Pie:
    c = (
        Pie()
        .add(
            "",
            lt,
            radius=["40%", "55%"],
            label_opts=opts.LabelOpts(
                position="outside",
                formatter="{a|{a}}{abg|}\n{hr|}\n {b|{b}: }{c}  {per|{d}%}  ",
                background_color="#eee",
                border_color="#aaa",
                border_width=1,
                border_radius=4,
                rich={
                    "a": {"color": "#999", "lineHeight": 22, "align": "center"},
                    "abg": {
                        "backgroundColor": "#e3e3e3",
                        "width": "100%",
                        "align": "right",
                        "height": 22,
                        "borderRadius": [4, 4, 0, 0],
                    },
                    "hr": {
                        "borderColor": "#aaa",
                        "width": "100%",
                        "borderWidth": 0.5,
                        "height": 0,
                    },
                    "b": {"fontSize": 16, "lineHeight": 33},
                    "per": {
                        "color": "#eee",
                        "backgroundColor": "#334455",
                        "padding": [2, 4],
                        "borderRadius": 2,
                    },
                },
            ),
        )
        .set_global_opts(title_opts=opts.TitleOpts(title="不同学历岗位数量"))
    )
    return c
pie_rich_label(lst).render_notebook()
    <div id="5075c1172b694c7295266f95df2e0b4c" style="width:900px; height:500px;"></div>

本科是python语言就业的主力军,正如各行各业大量的工程师成就了中国制造大国和基建狂魔的地位,中国也逐步成为互联网大国。

统计不同学历下薪资待遇

最低薪水

(1)里面的“面议”用中位数median代替

job_df['min_salary'].unique()
array(['15000.0', '4500.0', '3500.0', '7000.0', '4000.0', '14000.0',
       '3000.0', '10000.0', '6000.0', '9000.0', '20000.0', '8000.0',
       '100000.0', '2000.0', '5000.0', '200000.0', '50000.0', '150000.0',
       '13000.0', '12000.0', '1500.0', '16000.0', '1000.0', '120000.0',
       '600000.0', '25000.0', '30000.0', '1000000.0', '18000.0',
       '180000.0', '500000.0', '400000.0', '40000.0', '80000.0',
       '11000.0', '2500.0', '300000.0', '4200.0', '250000.0', '186000.0',
       '5500.0', '17000.0', '70000.0', '60000.0', '160000.0', '35000.0',
       '240000.0', '350000.0', '800000.0', '2800.0', '28000.0', '1600.0',
       '90000.0', '130000.0', '5200.0', '96000.0', '1800.0', '3300.0',
       '220000.0', '140000.0', '199000.0', '110000.0', '2400.0',
       '104000.0', '156000.0', '78000.0', '3200.0', '37000.0', '21000.0',
       '22000.0', '5800.0', '1500000.0', '230000.0', '6100.0', '3800.0',
       '26000.0', '45000.0', '450000.0', '390000.0', '270000.0',
       '29000.0', '190000.0', '72000.0', '3400.0', '27000.0', '6500.0',
       '7500.0', '4800.0', '65000.0', '2100.0', '170000.0', '2300.0',
       '7900.0', '1200.0', '19000.0', '2600.0', '23000.0', '2200.0',
       '24000.0', '196000.0', '3000000.0', '280000.0', '210000.0',
       '370000.0', '6700.0', '36000.0', '330000.0', '3900.0', '4900.0',
       '3600.0', '4100.0', '6400.0', '5300.0', '10000', '面议', '10001',
       '20000', '5000', '8000', '6001', '2001', '7000', '12000', '1000',
       '6000', '15001', '4001', '13000', '4000', '8001', '3000', '30000',
       '15000', '3500', '30001', '20001', '25000', '17000', '9000',
       '11000', '5500', '5999', '22000', '7500', '18000', '50001', '2000',
       '4800', '4500', '2800', '16000', '8200', '14000', '5900', '28000',
       '100001', '4600', '13500', '6500', '12500', '3800', '24000',
       '12800', '70001', '19000', '2600', '27000', '50000', '1500',
       '23000', '2500', '8333', '3501', '5950', '35000', '40000', '4200',
       '1800', '4300', '3300', '4999', '11666', '8500', '100000', '16600',
       '6600', '29000', '26000', '4700', '1200', '6100', '16666', '32500',
       '8400', '4166', '18333', '17500', '6666', '19166', '10833', '5833',
       '13333', '22500', '9166', '21666', '14166', '70000', '38333',
       '23333', '3333', '44166', '66666', '20833', '28333', '15833',
       '25833', '65000', '26666', '80000', '31666', '1666', '29166',
       '45000', '27500', '37500', '33333', '833', '58333', '137500',
       '55000', '43333', '83333', '41666', '40833', '46666', '24166',
       '87500', '840000', '54166', '125000', '34166', '1250', '2083',
       '52500', '56666', '60000', '75000', '35833', '53333'], dtype=object)

最低薪资

min_salary_other = job_df[job_df['min_salary'] != '面议']['min_salary'].apply(lambda x:float(x))  # 对不是“面议”的转浮点数
job_df.loc[job_df['min_salary'] == '面议', 'min_salary'] = min_salary_other.median()  # 将中位数赋值给“面议”
job_df['min_salary'] = job_df['min_salary'].apply(lambda x:float(x))  # 转浮点数

最高薪资

max_salary_other = job_df[job_df['max_salary'] != '面议']['max_salary'].apply(lambda x:float(x))  # 对不是“面议”的转浮点数
job_df.loc[job_df['max_salary'] == '面议', 'max_salary'] = max_salary_other.median()  # 将中位数赋值给“面议”
job_df['max_salary'] = job_df['max_salary'].apply(lambda x:float(x))  # 转浮点数

按不同学历分组,并求平均薪资

education_salary = job_df.loc[:, ['education', 'min_salary', 'max_salary']].groupby('education').mean()
education_salary
min_salary max_salary
education
中专 6559.702206 9985.294118
其他 20836.348267 33832.527473
博士 48622.669903 83772.464078
大专 10063.286104 16614.739531
学历不限 10691.994730 17626.093759
本科 16470.918090 27518.902278
硕士 25675.378983 44168.505674

薪资转整数

min_list = [int(i) for i in list(education_salary.min_salary)]
min_list
[6559, 20836, 48622, 10063, 10691, 16470, 25675]
max_list = [int(i) for i in list(education_salary.max_salary)]
max_list
[9985, 33832, 83772, 16614, 17626, 27518, 44168]
from pyecharts.charts import Bar


def bar_base() -> Bar:
    c = (
        Bar()
        .add_xaxis(list(education_salary.index))
        .add_yaxis("min_salary", min_list)
        .add_yaxis("max_salary", max_list)
        .set_global_opts(title_opts=opts.TitleOpts(title="不同学历薪水分布", subtitle="工资(元)"))
    )
    return c
bar_base().render_notebook()
    <div id="172f1a71f57d4b4ea547b8dc75539e70" style="width:900px; height:500px;"></div>

结论:

(1)高一级学历的最低工资相当于低一级学历的最高工资。对于大多数人来说,学历是改变人生的硬核之一。
(2)同一学历的最高工资约为最低工资的1.6倍,能力和努力也很重要。

岗位详情生成词云

import jieba
stop_word = [word.strip() for word in open('stop_word.txt',encoding='utf-8').readlines()]
stop_word.extend(['.', ' ', '\n', '\xa0', ',', '有'])
stop_word
['———',
 '》),',
 ')÷(1-',
 '”,',
 ')、',
 '=(',
 ':',
 '→',
 '℃',
 '&',
 '*',
 '一一',
 '~~~~',
 '’',
 '.',
 '『',
 '.一',
 './',
 '--',
 '』',
 '=″',
 '【',
 '[*]',
 '}>',
 '[⑤]]',
 '[①D]',
 'c]',
 'ng昉',
 '*',
 '//',
 '[',
 ']',
 '[②e]',
 '[②g]',
 '={',
 '}',
 ',也',
 '‘',
 'A',
 '[①⑥]',
 '[②B]',
 '[①a]',
 '[④a]',
 '[①③]',
 '[③h]',
 '③]',
 '1.',
 '--',
 '[②b]',
 '’‘',
 '×××',
 '[①⑧]',
 '0:2',
 '=[',
 '[⑤b]',
 '[②c]',
 '[④b]',
 '[②③]',
 '[③a]',
 '[④c]',
 '[①⑤]',
 '[①⑦]',
 '[①g]',
 '∈[',
 '[①⑨]',
 '[①④]',
 '[①c]',
 '[②f]',
 '[②⑧]',
 '[②①]',
 '[①C]',
 '[③c]',
 '[③g]',
 '[②⑤]',
 '[②②]',
 '一.',
 '[①h]',
 '.数',
 '[]',
 '[①B]',
 '数/',
 '[①i]',
 '[③e]',
 '[①①]',
 '[④d]',
 '[④e]',
 '[③b]',
 '[⑤a]',
 '[①A]',
 '[②⑧]',
 '[②⑦]',
 '[①d]',
 '[②j]',
 '〕〔',
 '][',
 '://',
 '′∈',
 '[②④',
 '[⑤e]',
 '12%',
 'b]',
 '...',
 '...................',
 '…………………………………………………③',
 'ZXFITL',
 '[③F]',
 '」',
 '[①o]',
 ']∧′=[',
 '∪φ∈',
 '′|',
 '{-',
 '②c',
 '}',
 '[③①]',
 'R.L.',
 '[①E]',
 'Ψ',
 '-[*]-',
 '↑',
 '.日',
 '[②d]',
 '[②',
 '[②⑦]',
 '[②②]',
 '[③e]',
 '[①i]',
 '[①B]',
 '[①h]',
 '[①d]',
 '[①g]',
 '[①②]',
 '[②a]',
 'f]',
 '[⑩]',
 'a]',
 '[①e]',
 '[②h]',
 '[②⑥]',
 '[③d]',
 '[②⑩]',
 'e]',
 '〉',
 '】',
 '元/吨',
 '[②⑩]',
 '2.3%',
 '5:0',
 '[①]',
 '::',
 '[②]',
 '[③]',
 '[④]',
 '[⑤]',
 '[⑥]',
 '[⑦]',
 '[⑧]',
 '[⑨]',
 '……',
 '——',
 '?',
 '、',
 '。',
 '“',
 '”',
 '《',
 '》',
 '!',
 ',',
 ':',
 ';',
 '?',
 '.',
 ',',
 '.',
 "'",
 '?',
 '·',
 '———',
 '──',
 '?',
 '—',
 '<',
 '>',
 '(',
 ')',
 '〔',
 '〕',
 '[',
 ']',
 '【',
 '】',
 '(',
 ')',
 '-',
 '+',
 '~',
 '×',
 '/',
 '/',
 '①',
 '②',
 '③',
 '④',
 '⑤',
 '⑥',
 '⑦',
 '⑧',
 '⑨',
 '⑩',
 'Ⅲ',
 'В',
 '"',
 ';',
 '#',
 '@',
 'γ',
 'μ',
 'φ',
 'φ.',
 '×',
 'Δ',
 '■',
 '▲',
 'sub',
 'exp',
 'sup',
 'sub',
 'Lex',
 '#',
 '%',
 '&',
 ''',
 '+',
 '+ξ',
 '++',
 '-',
 '-β',
 '<',
 '<±',
 '<Δ',
 '<λ',
 '<φ',
 '<<',
 '=',
 '=',
 '=☆',
 '=-',
 '>',
 '>λ',
 '_',
 '~±',
 '~+',
 '[⑤f]',
 '[⑤d]',
 '[②i]',
 '≈',
 '[②G]',
 '[①f]',
 'LI',
 '㈧',
 '[-',
 '......',
 '〉',
 '[③⑩]',
 '第二',
 '一番',
 '一直',
 '一个',
 '一些',
 '许多',
 '种',
 '有的是',
 '也就是说',
 '末##末',
 '啊',
 '阿',
 '哎',
 '哎呀',
 '哎哟',
 '唉',
 '俺',
 '俺们',
 '按',
 '按照',
 '吧',
 '吧哒',
 '把',
 '罢了',
 '被',
 '本',
 '本着',
 '比',
 '比方',
 '比如',
 '鄙人',
 '彼',
 '彼此',
 '边',
 '别',
 '别的',
 '别说',
 '并',
 '并且',
 '不比',
 '不成',
 '不单',
 '不但',
 '不独',
 '不管',
 '不光',
 '不过',
 '不仅',
 '不拘',
 '不论',
 '不怕',
 '不然',
 '不如',
 '不特',
 '不惟',
 '不问',
 '不只',
 '朝',
 '朝着',
 '趁',
 '趁着',
 '乘',
 '冲',
 '除',
 '除此之外',
 '除非',
 '除了',
 '此',
 '此间',
 '此外',
 '从',
 '从而',
 '打',
 '待',
 '但',
 '但是',
 '当',
 '当着',
 '到',
 '得',
 '的',
 '的话',
 '等',
 '等等',
 '地',
 '第',
 '叮咚',
 '对',
 '对于',
 '多',
 '多少',
 '而',
 '而况',
 '而且',
 '而是',
 '而外',
 '而言',
 '而已',
 '尔后',
 '反过来',
 '反过来说',
 '反之',
 '非但',
 '非徒',
 '否则',
 '嘎',
 '嘎登',
 '该',
 '赶',
 '个',
 '各',
 '各个',
 '各位',
 '各种',
 '各自',
 '给',
 '根据',
 '跟',
 '故',
 '故此',
 '固然',
 '关于',
 '管',
 '归',
 '果然',
 '果真',
 '过',
 '哈',
 '哈哈',
 '呵',
 '和',
 '何',
 '何处',
 '何况',
 '何时',
 '嘿',
 '哼',
 '哼唷',
 '呼哧',
 '乎',
 '哗',
 '还是',
 '还有',
 '换句话说',
 '换言之',
 '或',
 '或是',
 '或者',
 '极了',
 '及',
 '及其',
 '及至',
 '即',
 '即便',
 '即或',
 '即令',
 '即若',
 '即使',
 '几',
 '几时',
 '己',
 '既',
 '既然',
 '既是',
 '继而',
 '加之',
 '假如',
 '假若',
 '假使',
 '鉴于',
 '将',
 '较',
 '较之',
 '叫',
 '接着',
 '结果',
 '借',
 '紧接着',
 '进而',
 '尽',
 '尽管',
 '经',
 '经过',
 '就',
 '就是',
 '就是说',
 '据',
 '具体地说',
 '具体说来',
 '开始',
 '开外',
 '靠',
 '咳',
 '可',
 '可见',
 '可是',
 '可以',
 '况且',
 '啦',
 '来',
 '来着',
 '离',
 '例如',
 '哩',
 '连',
 '连同',
 '两者',
 '了',
 '临',
 '另',
 '另外',
 '另一方面',
 '论',
 '嘛',
 '吗',
 '慢说',
 '漫说',
 '冒',
 '么',
 '每',
 '每当',
 '们',
 '莫若',
 '某',
 '某个',
 '某些',
 '拿',
 '哪',
 '哪边',
 '哪儿',
 '哪个',
 '哪里',
 '哪年',
 '哪怕',
 '哪天',
 '哪些',
 '哪样',
 '那',
 '那边',
 '那儿',
 '那个',
 '那会儿',
 '那里',
 '那么',
 '那么些',
 '那么样',
 '那时',
 '那些',
 '那样',
 '乃',
 '乃至',
 '呢',
 '能',
 '你',
 '你们',
 '您',
 '宁',
 '宁可',
 '宁肯',
 '宁愿',
 '哦',
 '呕',
 '啪达',
 '旁人',
 '呸',
 '凭',
 '凭借',
 '其',
 '其次',
 '其二',
 '其他',
 '其它',
 '其一',
 '其余',
 '其中',
 '起',
 '起见',
 '起见',
 '岂但',
 '恰恰相反',
 '前后',
 '前者',
 '且',
 '然而',
 '然后',
 '然则',
 '让',
 '人家',
 '任',
 '任何',
 '任凭',
 '如',
 '如此',
 '如果',
 '如何',
 '如其',
 '如若',
 '如上所述',
 '若',
 '若非',
 '若是',
 '啥',
 '上下',
 '尚且',
 '设若',
 '设使',
 '甚而',
 '甚么',
 '甚至',
 '省得',
 '时候',
 '什么',
 '什么样',
 '使得',
 '是',
 '是的',
 '首先',
 '谁',
 '谁知',
 '顺',
 '顺着',
 '似的',
 '虽',
 '虽然',
 '虽说',
 '虽则',
 '随',
 '随着',
 '所',
 '所以',
 '他',
 '他们',
 '他人',
 '它',
 '它们',
 '她',
 '她们',
 '倘',
 '倘或',
 '倘然',
 '倘若',
 '倘使',
 '腾',
 '替',
 '通过',
 '同',
 '同时',
 '哇',
 '万一',
 '往',
 '望',
 '为',
 '为何',
 '为了',
 '为什么',
 '为着',
 '喂',
 '嗡嗡',
 '我',
 '我们',
 '呜',
 '呜呼',
 '乌乎',
 '无论',
 '无宁',
 '毋宁',
 '嘻',
 '吓',
 '相对而言',
 '像',
 '向',
 '向着',
 '嘘',
 '呀',
 '焉',
 '沿',
 '沿着',
 '要',
 '要不',
 '要不然',
 '要不是',
 '要么',
 '要是',
 '也',
 '也罢',
 '也好',
 '一',
 '一般',
 '一旦',
 '一方面',
 '一来',
 '一切',
 '一样',
 '一则',
 '依',
 '依照',
 '矣',
 '以',
 '以便',
 '以及',
 '以免',
 '以至',
 '以至于',
 '以致',
 '抑或',
 '因',
 '因此',
 '因而',
 '因为',
 '哟',
 '用',
 '由',
 '由此可见',
 '由于',
 '有',
 '有的',
 '有关',
 '有些',
 '又',
 '于',
 '于是',
 '于是乎',
 '与',
 '与此同时',
 '与否',
 '与其',
 '越是',
 '云云',
 '哉',
 '再说',
 '再者',
 '在',
 '在下',
 '咱',
 '咱们',
 '则',
 '怎',
 '怎么',
 '怎么办',
 '怎么样',
 '怎样',
 '咋',
 '照',
 '照着',
 '者',
 '这',
 '这边',
 '这儿',
 '这个',
 '这会儿',
 '这就是说',
 '这里',
 '这么',
 '这么点儿',
 '这么些',
 '这么样',
 '这时',
 '这些',
 '这样',
 '正如',
 '吱',
 '之',
 '之类',
 '之所以',
 '之一',
 '只是',
 '只限',
 '只要',
 '只有',
 '至',
 '至于',
 '诸位',
 '着',
 '着呢',
 '自',
 '自从',
 '自个儿',
 '自各儿',
 '自己',
 '自家',
 '自身',
 '综上所述',
 '总的来看',
 '总的来说',
 '总的说来',
 '总而言之',
 '总之',
 '纵',
 '纵令',
 '纵然',
 '纵使',
 '遵照',
 '作为',
 '兮',
 '呃',
 '呗',
 '咚',
 '咦',
 '喏',
 '啐',
 '喔唷',
 '嗬',
 '嗯',
 '嗳',
 '.',
 ' ',
 '\n',
 '\xa0',
 ',',
 '有']
result_word = {}
for word_str in job_df['job_detail'][0:5]:  # 仅用前5条数据,节约时间
    for word in jieba.cut(word_str):
        if word not in stop_word:
            if word not in result_word:
                result_word[word] = 1
            else:
                result_word[word] += 1
list_word = sorted(result_word.items(), key=lambda dt:dt[1], reverse=True)[0:200]
list_word
Building prefix dict from the default dictionary ...
Loading model from cache C:\Users\13721\AppData\Local\Temp\jieba.cache
Loading model cost 3.256 seconds.
Prefix dict has been built successfully.





[('测试', 16),
 ('工作', 16),
 ('熟悉', 14),
 ('1', 12),
 ('优先', 12),
 ('2', 11),
 ('3', 10),
 ('4', 10),
 ('能力', 9),
 ('经验', 8),
 ('负责', 8),
 ('5', 7),
 ('公司', 7),
 ('开发', 6),
 ('相关', 6),
 ('问题', 6),
 ('使用', 5),
 ('产品', 5),
 ('项目', 5),
 ('需求', 5),
 ('良好', 5),
 ('系统', 5),
 ('精通', 4),
 ('熟练', 4),
 ('数据库', 4),
 ('文档', 4),
 ('编写', 4),
 ('测试用例', 4),
 ('推动', 4),
 ('及时', 4),
 ('6', 4),
 ('7', 4),
 ('专业', 4),
 ('测试工具', 4),
 ('性能', 4),
 ('Linux', 4),
 ('具有', 4),
 ('提供', 4),
 ('安装', 4),
 ('网络', 4),
 ('Python', 3),
 ('Windows', 3),
 ('下', 3),
 ('岗位职责', 3),
 ('合理', 3),
 ('解决', 3),
 ('计算机', 3),
 ('以上学历', 3),
 ('以上', 3),
 ('软件测试', 3),
 ('一种', 3),
 ('操作', 3),
 ('自动化', 3),
 ('维护', 3),
 ('团队', 3),
 ('协调', 3),
 ('培训', 3),
 ('带薪', 3),
 ('技术支持', 3),
 ('完成', 3),
 ('信息安全', 3),
 ('分析', 3),
 ('环境', 3),
 ('python', 2),
 ('掌握', 2),
 ('主流', 2),
 ('关系', 2),
 ('功能', 2),
 ('C', 2),
 ('C++', 2),
 ('平台', 2),
 ('测试数据', 2),
 ('执行', 2),
 ('跟踪', 2),
 ('用户', 2),
 ('安全', 2),
 ('方面', 2),
 ('测试报告', 2),
 ('任职', 2),
 ('要求', 2),
 ('三年', 2),
 ('至少', 2),
 ('SQL', 2),
 ('MySql', 2),
 ('定位', 2),
 ('8', 2),
 ('编程', 2),
 ('9', 2),
 ('10', 2),
 ('具备', 2),
 ('意识', 2),
 ('自我', 2),
 ('11', 2),
 ('协作', 2),
 ('沟通', 2),
 ('较强', 2),
 ('福利', 2),
 ('定期', 2),
 ('五险', 2),
 ('年', 2),
 ('收集', 2),
 ('客户', 2),
 ('完善', 2),
 ('安排', 2),
 ('配置', 2),
 ('了解', 2),
 ('脚本语言', 2),
 ('体系', 2),
 ('制定', 2),
 ('设计', 2),
 ('bug', 2),
 ('准确', 2),
 ('电商', 2),
 ('进行', 2),
 ('接口', 2),
 ('每年', 2),
 ('机会', 2),
 ('管理', 2),
 ('节日', 2),
 ('春节', 2),
 ('web', 1),
 ('Flask', 1),
 ('框架', 1),
 ('与非', 1),
 ('型', 1),
 ('HTML5', 1),
 ('CSS3', 1),
 ('JS', 1),
 ('ReactJS', 1),
 ('VueJS', 1),
 ('前端', 1),
 ('页面', 1),
 ('linux', 1),
 ('熟练者', 1),
 ('PDF', 1),
 ('Office', 1),
 ('格式', 1),
 ('有大', 1),
 ('数据处理', 1),
 ('招聘', 1),
 ('城市', 1),
 ('深圳', 1),
 ('广州', 1),
 ('中山', 1),
 ('移动', 1),
 ('端及', 1),
 ('网站', 1),
 ('功能测试', 1),
 ('独立', 1),
 ('准备', 1),
 ('研发部门', 1),
 ('紧密配合', 1),
 ('顺利进行', 1),
 ('统计', 1),
 ('分析测试', 1),
 ('提高', 1),
 ('效率', 1),
 ('质量', 1),
 ('线上', 1),
 ('参与', 1),
 ('评审', 1),
 ('站', 1),
 ('角度', 1),
 ('针对', 1),
 ('逻辑', 1),
 ('完整', 1),
 ('易用性', 1),
 ('提出', 1),
 ('建议', 1),
 ('形成', 1),
 ('专科', 1),
 ('互联网', 1),
 ('Web', 1),
 ('Wap', 1),
 ('App', 1),
 ('理论', 1),
 ('流程', 1),
 ('测试方法', 1),
 ('Bugfree', 1),
 ('禅道', 1),
 ('JIRA', 1),
 ('常用', 1),
 ('管理工具', 1),
 ('语句', 1),
 ('一定', 1),
 ('追踪', 1),
 ('selenium', 1),
 ('appium', 1),
 ('LoadRunner', 1),
 ('Jmeter', 1),
 ('WebpageTest', 1),
 ('Shell', 1),
 ('Perl', 1),
 ('脚本', 1),
 ('辅助工具', 1),
 ('系统配置', 1),
 ('包括', 1),
 ('测试环境', 1),
 ('搭建', 1),
 ('质量保证', 1)]
from pyecharts.charts import Page, WordCloud
from pyecharts.globals import SymbolType


def wordcloud_diamond(words) -> WordCloud:
    c = (
        WordCloud()
        .add("", words, word_size_range=[20, 100], shape=SymbolType.DIAMOND)
        .set_global_opts(title_opts=opts.TitleOpts(title="岗位详情词云"))
    )
    return c
wordcloud_diamond(list_word).render_notebook()
    <div id="3d76487621024382b9d885cb1e817cd8" style="width:900px; height:500px;"></div>

岗位要求:

(1)熟悉相关算法,具备数据分析能力;
(2)具有项目开发经验;
(3)团队意识和学习能力。

不同就业方向的分布(web,爬虫,数据分析,自动化测试,自动化运维,嵌入式,机器学习,讲师)

# 增加一列就业方向,初始化为“其他”
job_df['job_direction'] = '其他就业方向'
job_df.loc[job_df['job_detail'].str.contains('web') | job_df['job_detail'].str.contains('flask') | job_df['job_detail'].str.contains('django') | job_df['job_detail'].str.contains('JQuery') | job_df['job_detail'].str.contains('JavaScript') | job_df['job_detail'].str.contains('Bootstrap') | job_df['job_detail'].str.contains('js'), 'job_direction'] = 'web'
job_df.loc[job_df['job_detail'].str.contains('爬虫') | job_df['job_detail'].str.contains('反爬') | job_df['job_detail'].str.contains('抓取') | job_df['job_detail'].str.contains('爬取') | job_df['job_detail'].str.contains('scrapy'), 'job_direction'] = '爬虫'
job_df.loc[job_df['job_detail'].str.contains('运维') | job_df['job_detail'].str.contains('维护'), 'job_direction'] = '自动化运维'
job_df.loc[job_df['job_detail'].str.contains('测试') | job_df['job_name'].str.contains('测试') | job_df['job_detail'].str.contains('验证'), 'job_direction'] = '自动化测试'
job_df.loc[job_df['job_detail'].str.contains('嵌入式') | job_df['job_detail'].str.contains('机电') | job_df['job_detail'].str.contains('电子'), 'job_direction'] = '嵌入式'
job_df.loc[job_df['job_detail'].str.contains('数据分析') | job_df['job_detail'].str.contains('数据挖掘') | job_df['job_detail'].str.contains('数据清洗') | job_df['job_detail'].str.contains('数学'), 'job_direction'] = '数据分析'
job_df.loc[job_df['job_detail'].str.contains('机器学习') | job_df['job_detail'].str.contains('人工智能') | job_df['job_name'].str.contains('人工智能') | job_df['job_detail'].str.contains('深度学习') | job_df['job_detail'].str.contains('神经网络'), 'job_direction'] = '机器学习'
job_df.loc[job_df['job_detail'].str.contains('讲师') | job_df['job_detail'].str.contains('授课'), 'job_direction'] = '讲师'

job_df.loc[job_df['job_direction'] == '其他就业方向', ['job_name', 'job_detail']].groupby('job_name').size()
job_name
 Analysis and Data Reporting                1
 Cyberport Network Engineer                 7
 DBA                                        1
 IAAS 研发工程师                                 6
 IT Specialist                              1
                                           ..
(急聘)Python开发工程师                             1
(接受转行)python工程师助理/python开发学徒/python程序员      2
(烟台)C++/JAVA/C中高级软件开发(职位编号:QDXS-0005)       1
(烟台)中高级软件开发工程师                              1
(补贴+包住宿)python工程师助理/python开发学徒/python程序员    2
Length: 7574, dtype: int64

规约后不同就业方向分布

direction_size = job_df.loc[:, ['job_direction']].groupby('job_direction').size()
direction_size
job_direction
web        3907
其他就业方向    17953
嵌入式        5065
数据分析      12579
机器学习      18301
爬虫          635
自动化测试     20079
自动化运维     15879
讲师         1249
dtype: int64
dct_direction = dict(direction_size)
from pyecharts.charts import Funnel, Page


def funnel_sort_ascending(dct) -> Funnel:
    c = (
        Funnel()
        .add(
            "岗位数量",
            [(key, int(value)) for key, value in dct.items()],
            sort_="ascending",
            label_opts=opts.LabelOpts(position="outside"),
        )
        .set_global_opts(title_opts=opts.TitleOpts(title="不同就业方向岗位数量"), legend_opts=opts.LegendOpts(pos_left="right", pos_top="5%"))
    )
    return c
funnel_sort_ascending(dct_direction).render_notebook()
    <div id="7431dfea634c41baae8587215a6aa1d4" style="width:900px; height:500px;"></div>

结论:

(1)python胶水语言的特性,非常适合自动化测试和自动化运维。
(2)python语言因其数据精度高、简单易学和丰富的第三方库,成为数据分析和机器学习的主流语言,人工智能和python互相成就。
(3)讲师方面的岗位不多,但随着国家对人工智能和编程教育的重视,预期会有一定增长。

不同信息来源的薪资情况

1-51job, 2-智联, 3-猎聘

job_df.loc[:, ['info_source', 'min_salary', 'max_salary']].groupby('info_source').mean()
min_salary max_salary
info_source
1 22930.457482 37947.202312
2 9456.515411 15534.609265
3 14748.898628 25187.899997

不同城市的招聘规模

job_df.loc[job_df['city'].str.contains('上海'), 'city'] = '上海'
job_df.loc[job_df['city'].str.contains('北京'), 'city'] = '北京'
job_df.loc[job_df['city'].str.contains('广州'), 'city'] = '广州'
job_df.loc[job_df['city'].str.contains('深圳'), 'city'] = '深圳'
job_df.loc[job_df['city'].str.contains('杭州'), 'city'] = '杭州'
job_df.loc[job_df['city'].str.contains('天津'), 'city'] = '天津'
job_df.loc[job_df['city'].str.contains('重庆'), 'city'] = '重庆'
job_df.loc[job_df['city'].str.contains('成都'), 'city'] = '成都'
job_df.loc[job_df['city'].str.contains('武汉'), 'city'] = '武汉'
job_df.loc[job_df['city'].str.contains('郑州'), 'city'] = '郑州'
job_df.loc[job_df['city'].str.contains('西安'), 'city'] = '西安'
job_df.loc[job_df['city'].str.contains('南京'), 'city'] = '南京'
job_df.loc[job_df['city'].str.contains('青岛'), 'city'] = '青岛'
job_df.loc[job_df['city'].str.contains('东莞'), 'city'] = '东莞'
job_df.loc[job_df['city'].str.contains('中山'), 'city'] = '中山'
job_df.loc[job_df['city'].str.contains('佛山'), 'city'] = '佛山'
job_df.loc[job_df['city'].str.contains('长沙'), 'city'] = '长沙'
job_df.loc[job_df['city'].str.contains('乌鲁木齐'), 'city'] = '乌鲁木齐'
job_df.loc[job_df['city'].str.contains('济南'), 'city'] = '济南'
job_df.loc[job_df['city'].str.contains('宁波'), 'city'] = '宁波'
job_df.loc[job_df['city'].str.contains('苏州'), 'city'] = '苏州'
job_df.loc[job_df['city'].str.contains('沈阳'), 'city'] = '沈阳'
job_df.loc[job_df['city'].str.contains('福州'), 'city'] = '福州'
job_df.loc[job_df['city'].str.contains('合肥'), 'city'] = '合肥'
job_df.loc[job_df['city'].str.contains('兰州'), 'city'] = '兰州'
job_df.loc[job_df['city'].str.contains('南宁'), 'city'] = '南宁'
job_df.loc[job_df['city'].str.contains('南昌'), 'city'] = '南昌'
job_df.loc[job_df['city'].str.contains('绍兴'), 'city'] = '绍兴'
job_df.loc[job_df['city'].str.contains('厦门'), 'city'] = '厦门'
job_df.loc[job_df['city'].str.contains('泉州'), 'city'] = '泉州'
job_df.loc[job_df['city'].str.contains('常州'), 'city'] = '常州'
job_df.loc[job_df['city'].str.contains('南通'), 'city'] = '南通'
job_df.loc[job_df['city'].str.contains('哈尔滨'), 'city'] = '哈尔滨'
job_df.loc[job_df['city'].str.contains('嘉兴'), 'city'] = '嘉兴'
job_df.loc[job_df['city'].str.contains('大连'), 'city'] = '大连'
job_df.loc[job_df['city'].str.contains('太原'), 'city'] = '太原'
job_df.loc[job_df['city'].str.contains('徐州'), 'city'] = '徐州'
job_df.loc[job_df['city'].str.contains('无锡'), 'city'] = '无锡'
job_df.loc[job_df['city'].str.contains('昆明'), 'city'] = '昆明'
job_df.loc[job_df['city'].str.contains('石家庄'), 'city'] = '石家庄'
job_df.loc[job_df['city'].str.contains('贵阳'), 'city'] = '贵阳'
job_df.loc[job_df['city'].str.contains('长春'), 'city'] = '长春'
job_df.loc[job_df['city'].str.contains('洛阳'), 'city'] = '洛阳'
job_df.loc[job_df['city'].str.contains('烟台'), 'city'] = '烟台'
job_df.loc[job_df['city'].str.contains('珠海'), 'city'] = '珠海'
dct_city = dict(job_df.loc[:, ['city']].groupby('city').size())
lst_city = [[key, value] for key, value in dct_city.items()]
lst_city.sort(key=lambda lt:lt[1], reverse=True)
lst_city[0:20]
[['深圳', 16242],
 ['广州', 9410],
 ['上海', 9159],
 ['杭州', 8096],
 ['成都', 6758],
 ['南京', 6565],
 ['北京', 5789],
 ['武汉', 4042],
 ['苏州', 2988],
 ['西安', 2463],
 ['郑州', 1959],
 ['济南', 1516],
 ['长沙', 1463],
 ['厦门', 1386],
 ['合肥', 1338],
 ['福州', 1330],
 ['大连', 1221],
 ['青岛', 1050],
 ['无锡', 978],
 ['沈阳', 818]]

主要城市薪水中位数

for lt in lst_city[0:20]:
    lt.append(job_df.loc[job_df['city'] == lt[0],'min_salary'].median())
    lt.append(job_df.loc[job_df['city'] == lt[0],'max_salary'].median())
lst_city[0:20]
[['深圳', 16242, 13000.0, 20000.0],
 ['广州', 9410, 10000.0, 20000.0],
 ['上海', 9159, 13000.0, 20000.0],
 ['杭州', 8096, 12000.0, 20000.0],
 ['成都', 6758, 10000.0, 18000.0],
 ['南京', 6565, 10000.0, 20000.0],
 ['北京', 5789, 15000.0, 20000.0],
 ['武汉', 4042, 9166.0, 15000.0],
 ['苏州', 2988, 10000.0, 18333.0],
 ['西安', 2463, 8333.0, 15000.0],
 ['郑州', 1959, 8001.0, 13333.0],
 ['济南', 1516, 8001.0, 15000.0],
 ['长沙', 1463, 8000.0, 14000.0],
 ['厦门', 1386, 10000.0, 16000.0],
 ['合肥', 1338, 8000.0, 15000.0],
 ['福州', 1330, 8000.0, 15000.0],
 ['大连', 1221, 8333.0, 15000.0],
 ['青岛', 1050, 8333.0, 15000.0],
 ['无锡', 978, 8333.0, 15000.0],
 ['沈阳', 818, 6001.0, 10000.0]]
from pyecharts.charts import Line


def line_base(lst) -> Line:
    c = (
        Line()
        .add_xaxis([lt[0] for lt in lst])
        .add_yaxis('岗位数',[int(lt[1]) for lt in lst])
        .add_yaxis("最低工资中位数", [lt[2] for lt in lst])
        .add_yaxis("最高工资中位数", [lt[3] for lt in lst])
        .set_global_opts(title_opts=opts.TitleOpts(title="主要城市岗位数量和薪水"))
    )
    return c
line_base(lst_city[0:20]).render_notebook()
    <div id="3561af09170744e7a88c0a010b404131" style="width:900px; height:500px;"></div>

结论:

(1)互联网行业主要集中在一线城市,招聘数量最多的是深圳,其数量是排名20的沈阳招聘数量的20倍。
(2)北京的招聘数量并不多,但工资较高,符合北京的城市定位和人口限制政策。
(3)二线城市中,杭州和成都紧追一线城市;武汉、郑州的互联网行业暂未发展起来,工资相对较低;而苏州、厦门招聘数量虽不多,但工资水平与其房价水平匹配。

不同城市招聘方向的分布,及相关方向的平均薪资

不同城市招聘方向的分布

job_df.loc[:, ['city', 'job_direction']].groupby(['city', 'job_direction']).size()
city  job_direction
      嵌入式              5
三亚    web              1
      其他就业方向           1
      机器学习             2
      自动化测试            3
                      ..
齐齐哈尔  嵌入式              3
龙岩    其他就业方向           1
      数据分析             2
      机器学习             2
      自动化测试            5
Length: 1111, dtype: int64

不同城市相关方向平均薪资

job_df.loc[:, ['city', 'job_direction', 'min_salary', 'max_salary']].groupby(['city', 'job_direction']).mean()
min_salary max_salary
city job_direction
嵌入式 10000.000000 15000.000000
三亚 web 6000.000000 25000.000000
其他就业方向 6000.000000 7000.000000
机器学习 6000.000000 7000.000000
自动化测试 4666.666667 6666.666667
... ... ... ...
齐齐哈尔 嵌入式 3500.000000 7000.000000
龙岩 其他就业方向 4000.000000 8000.000000
数据分析 15000.000000 20000.000000
机器学习 15000.000000 25000.000000
自动化测试 9300.800000 12400.000000

1111 rows × 2 columns

以郑州为例_不同方向岗位数

job_df.loc[job_df['city'] == '郑州', ['city', 'job_direction']].groupby(['job_direction']).size()
job_direction
web        72
其他就业方向    270
嵌入式       105
数据分析      250
机器学习      477
爬虫         18
自动化测试     391
自动化运维     346
讲师         30
dtype: int64
dct_zz_job_direction = dict(job_df.loc[job_df['city'] == '郑州', ['city', 'job_direction']].groupby(['job_direction']).size())
dct_zz_job_direction
{'web': 72,
 '其他就业方向': 270,
 '嵌入式': 105,
 '数据分析': 250,
 '机器学习': 477,
 '爬虫': 18,
 '自动化测试': 391,
 '自动化运维': 346,
 '讲师': 30}
from pyecharts.charts import Bar
from pyecharts.commons.utils import JsCode

def bar_border_radius(dct):
    c = (
        Bar()
        .add_xaxis([key for key, value in dct.items()])
        .add_yaxis("不同就业方向", [int(value) for key, value in dct.items()], category_gap="60%")
        .set_series_opts(
            xaxis_opts={
               "interval":0,
               "rotate":40
            },
            itemstyle_opts={
            "normal": {
                "color": JsCode("""new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
                    offset: 0,
                    color: 'rgba(0, 244, 255, 1)'
                }, {
                    offset: 1,
                    color: 'rgba(0, 77, 167, 1)'
                }], false)"""),
                "barBorderRadius": [30, 30, 30, 30],
                "shadowColor": 'rgb(0, 160, 221)',
            }})
        .set_global_opts(title_opts=opts.TitleOpts(title="郑州python不同就业方向岗位数量"), xaxis_opts=opts.AxisOpts(interval=0, name_rotate=40))
    )
    return c
bar_border_radius(dct_zz_job_direction).render_notebook()
    <div id="22f3b4c7e1b54a36b082a47181bdbd4c" style="width:900px; height:500px;"></div>

以郑州为例_不同方向工资中位数

job_df.loc[job_df['city'] == '郑州', ['city', 'job_direction', 'min_salary', 'max_salary']].groupby(['job_direction']).median()
min_salary max_salary
job_direction
web 7000.0 10000.0
其他就业方向 8001.0 13166.5
嵌入式 8000.0 14000.0
数据分析 8333.0 14000.0
机器学习 10000.0 15000.0
爬虫 6500.0 10000.0
自动化测试 8000.0 12000.0
自动化运维 8001.0 15000.0
讲师 8000.0 12000.0

不同方向需要的工作经验分布

按工作经验规约

经验不限:无经验、无工作经验;

job_df.loc[job_df['work_years'] == '无经验', 'work_years'] = '经验不限'
job_df.loc[job_df['work_years'] == '无工作经验', 'work_years'] = '经验不限'
job_df.loc[job_df['work_years'] == '招3人', 'work_years'] = '经验不限'
job_df.loc[job_df['work_years'] == '1年以下', 'work_years'] = '经验不限'
job_df.loc[job_df['work_years'].str.contains('1年'), 'work_years'] = '1年'
job_df.loc[job_df['work_years'] == '1-3年', 'work_years'] = '1年'
job_df.loc[job_df['work_years'].str.contains('2年'), 'work_years'] = '2年'
job_df.loc[job_df['work_years'].str.contains('3年'), 'work_years'] = '3年'
job_df.loc[job_df['work_years'] == '3-4年经验', 'work_years'] = '3年'
job_df.loc[job_df['work_years'] == '3-5年', 'work_years'] = '3年'
job_df.loc[job_df['work_years'].str.contains('4年'), 'work_years'] = '4年'
job_df.loc[job_df['work_years'].str.contains('5年'), 'work_years'] = '5年'
job_df.loc[job_df['work_years'] == '5-7年经验', 'work_years'] = '5年'
job_df.loc[job_df['work_years'] == '5-10年', 'work_years'] = '5年'
job_df.loc[job_df['work_years'].str.contains('6年'), 'work_years'] = '6年'
job_df.loc[job_df['work_years'].str.contains('7年'), 'work_years'] = '7年'
job_df.loc[job_df['work_years'].str.contains('8年'), 'work_years'] = '8年'
job_df.loc[job_df['work_years'] == '8-9年经验', 'work_years'] = '8年'
job_df.loc[job_df['work_years'].str.contains('10年'), 'work_years'] = '10年'
job_df.loc[job_df['work_years'].str.contains('12年'), 'work_years'] = '12年'
job_df.loc[job_df['work_years'].str.contains('15年'), 'work_years'] = '15年'
job_df.loc[:, ['job_direction', 'work_years']].groupby(['job_direction', 'work_years']).size()
job_direction  work_years
web            10年              9
               1年             690
               2年             429
               3年            1437
               5年             548
                             ... 
讲师             2年              50
               3年             262
               5年              76
               8年               3
               经验不限           528
Length: 80, dtype: int64

以郑州数据分析师为例

dct_zz_work_years = dict(job_df.loc[(job_df['city'] == '郑州') & ((job_df['job_direction'] == '数据分析') | (job_df['job_direction'] == '机器学习')), ['job_direction', 'work_years']].groupby(['work_years']).size())
dct_zz_work_years
{'1年': 132, '2年': 89, '3年': 175, '4年': 7, '5年': 99, '8年': 5, '经验不限': 220}
from pyecharts.charts import EffectScatter
from pyecharts.globals import SymbolType


def effectscatter_symbol(dct) -> EffectScatter:
    c = (
        EffectScatter()
        .add_xaxis([key for key, value in dct.items()])
        .add_yaxis("", [int(value) for key, value in dct.items()], symbol=SymbolType.ARROW)
    ).set_global_opts(title_opts=opts.TitleOpts(title="郑州机器学习和数据分析——工作经验要求"))
    return c
effectscatter_symbol(dct_zz_work_years).render_notebook()
    <div id="b43ab93440904788ad4ca1db561039b6" style="width:900px; height:500px;"></div>
dct_zz_education = dict(job_df.loc[(job_df['city'] == '郑州') & ((job_df['job_direction'] == '数据分析') | (job_df['job_direction'] == '机器学习')), ['job_direction', 'education']].groupby(['education']).size())
dct_zz_education
{'中专': 2, '其他': 14, '博士': 2, '大专': 208, '学历不限': 50, '本科': 412, '硕士': 39}
from pyecharts.charts import Scatter


def scatter_spliteline(dct) -> Scatter:
    c = (
        Scatter()
        .add_xaxis([key for key, value in dct.items()])
        .add_yaxis("学历", [int(value) for key, value in dct.items()])
        .set_global_opts(
            title_opts=opts.TitleOpts(title="郑州机器学习和数据分析——学历要求"),
            xaxis_opts=opts.AxisOpts(splitline_opts=opts.SplitLineOpts(is_show=True)),
            yaxis_opts=opts.AxisOpts(splitline_opts=opts.SplitLineOpts(is_show=True)),
        )
    )
    return c
scatter_spliteline(dct_zz_education).render_notebook()
    <div id="9d2f0454ad0e4aa79849929c273d2691" style="width:900px; height:500px;"></div>

郑州数据分析或机器学习工资中位数

job_df.loc[(job_df['city'] == '郑州') & ((job_df['job_direction'] == '数据分析') | (job_df['job_direction'] == '机器学习')), 'min_salary'].median()
9166.0
job_df.loc[(job_df['city'] == '郑州') & ((job_df['job_direction'] == '数据分析') | (job_df['job_direction'] == '机器学习')), 'max_salary'].median()
15000.0

结论:

(1)在郑州,python就业于机器学习和数据分析的职位不少,有700多个需求。
(2)学历要求以本科为主,工作经验要求并不高,高于3年的占20%左右。
(3)数据分析和机器学习方向工资中位数9166~15000万元/月。

没有更多推荐了,返回首页