Python数据分析十三课:数据分析实战

一个专业的数据分析,他的定位应该是一个“谋士”,所谓谋士,应该运筹帷幄,决胜千里,不出五尺书堂,便知天下大势。

我们现在已经从IT(Information Technology)时代进入了DT(Data Technology)时代。我们有能力低成本的收集和存储大量的数据,从而衍生出数据分析这个行业。

数据分析最重要的作用是从数据里面寻求真正有价值的信息,并帮助我们作出合理的决策。

为了更好的了解数据分析师这个岗位,本节课我们将以某招聘网站的2017年数据分析师职位数据为基础,进行数据分析。

一、数据基本情况

我们先了解一下数据的基本信息:

因为csv文件中带有中文字符而产生字符编码错误,造成读取文件错误,在这个时候,我们可以尝试将pd.read_csv()函数的encoding参数设置为"gbk"。

%matplotlib inline
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

# 导入数据
path = r'C:\Users\lin-a\Desktop\data\analyse_spider.csv'
data = pd.read_csv(path,encoding='GBK')
# 查看数据基本情况
print(data.shape)
data.head()
(6876, 14)
city companyId companySize businessZones firstType secondType education industryField positionId positionAdvantage positionName positionLables salary workYear
0 上海 8581 2000人以上 ['张江'] 技术 数据开发 硕士 移动互联网 2537336 知名平台 数据分析师 ['分析师', '数据分析', '数据挖掘', '数据'] 7k-9k 应届毕业生
1 上海 23177 500-2000人 ['五里桥', '打浦桥', '制造局路'] 技术 数据开发 本科 金融 2427485 挑战机会,团队好,与大牛合作,工作环境好 数据分析师-CR2017-SH2909 ['分析师', '数据分析', '数据挖掘', '数据'] 10k-15k 应届毕业生
2 上海 57561 50-150人 ['打浦桥'] 设计 数据分析 本科 移动互联网 2511252 时间自由,领导nic 数据分析师 ['分析师', '数据分析', '数据'] 4k-6k 应届毕业生
3 上海 7502 150-500人 ['龙华', '上海体育场', '万体馆'] 市场与销售 数据分析 本科 企业服务,数据服务 2427530 五险一金 绩效奖金 带薪年假 节日福利 大数据业务分析师【数云校招】 ['商业', '分析师', '大数据', '数据'] 6k-8k 应届毕业生
4 上海 130876 15-50人 ['上海影城', '新华路', '虹桥'] 技术 软件开发 本科 其他 2245819 在大牛下指导 BI开发/数据分析师 ['分析师', '数据分析', '数据', 'BI'] 2k-3k 应届毕业生

数据共包含14列,先看一下每一列的含义:

  • city:城市
  • companyId:公司ID
  • companySize:公司规模
  • CbusinessZones:公司所在商圈
  • firstType:职位所属一级类目
  • secondType:职业所属二级类目
  • education:学历要求
  • industryField:公司所属领域
  • positionId:职位ID
  • positionAdvantage:职位福利
  • positionName:职位名称
  • positionLables:职位标签
  • salary:薪水
  • workYear:工作年限要求

查看数据的具体情况:

# 查看数据具体情况
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 6876 entries, 0 to 6875
Data columns (total 14 columns):
 #   Column             Non-Null Count  Dtype 
---  ------             --------------  ----- 
 0   city               6876 non-null   object
 1   companyId          6876 non-null   int64 
 2   companySize        6876 non-null   object
 3   businessZones      4853 non-null   object
 4   firstType          6869 non-null   object
 5   secondType         6870 non-null   object
 6   education          6876 non-null   object
 7   industryField      6876 non-null   object
 8   positionId         6876 non-null   int64 
 9   positionAdvantage  6876 non-null   object
 10  positionName       6876 non-null   object
 11  positionLables     6844 non-null   object
 12  salary             6876 non-null   object
 13  workYear           6876 non-null   object
dtypes: int64(2), object(12)
memory usage: 752.2+ KB

二、数据分析目标

数据分析的大忌是不知道分析方向和目的,拿着一堆数据不知所措。一切数据分析都是以业务为核心目的,而不是以数据为目的。

所以,我们应该先定分析的目标,然后再处理数据。

我们本案例的目标很简单,就是根据该数据,分析影响薪资的因素:

  • 地区对数据分析师的薪酬的影响;
  • 学历对数据分析师的薪酬的影响;
  • 工作年限对数据分析师的薪酬的影响。

三、数据清洗

缺失值

数据的缺失值在很大程度上会影响数据的分析结果,如果某一个字段缺失值超过一半的时候,我们就可以将这个字段删除了,因为缺失过多就没有业务意义了。

注意:并不是,只要含有有缺失值的时候,我们就要将数据删除,如果数据量比较少、缺失值不多,并且对我们的分析指标没有实际影响时,我们就可以将其保留。

# 查看数据具体情况
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 6876 entries, 0 to 6875
Data columns (total 14 columns):
 #   Column             Non-Null Count  Dtype 
---  ------             --------------  ----- 
 0   city               6876 non-null   object
 1   companyId          6876 non-null   int64 
 2   companySize        6876 non-null   object
 3   businessZones      4853 non-null   object
 4   firstType          6869 non-null   object
 5   secondType         6870 non-null   object
 6   education          6876 non-null   object
 7   industryField      6876 non-null   object
 8   positionId         6876 non-null   int64 
 9   positionAdvantage  6876 non-null   object
 10  positionName       6876 non-null   object
 11  positionLables     6844 non-null   object
 12  salary             6876 non-null   object
 13  workYear           6876 non-null   object
dtypes: int64(2), object(12)
memory usage: 752.2+ KB

通过结果我们可以看出:一共有6876个数据,其中businessZones、firstType、secondType,positionLables都存在为空的情况。companyId和positionId为数字,其他都是字符串。

从数量上可以看出,businessZones列的数据缺失量比较大,需要将该列数据删除。

其他三列的缺失值的总数量为45,并不会影响整体分析效果,我们可以删除这45条数据。

%matplotlib inline
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

# 导入数据
path = r'C:\Users\lin-a\Desktop\data\analyse_spider.csv'
data = pd.read_csv(path,encoding='GBK')

# 删除缺失值的数据列businessZones
data.drop(columns='businessZones',axis=1,inplace=True)
# 同时删除缺失值的行
data.dropna(inplace=True)
data.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 6837 entries, 0 to 6875
Data columns (total 13 columns):
 #   Column             Non-Null Count  Dtype 
---  ------             --------------  ----- 
 0   city               6837 non-null   object
 1   companyId          6837 non-null   int64 
 2   companySize        6837 non-null   object
 3   firstType          6837 non-null   object
 4   secondType         6837 non-null   object
 5   education          6837 non-null   object
 6   industryField      6837 non-null   object
 7   positionId         6837 non-null   int64 
 8   positionAdvantage  6837 non-null   object
 9   positionName       6837 non-null   object
 10  positionLables     6837 non-null   object
 11  salary             6837 non-null   object
 12  workYear           6837 non-null   object
dtypes: int64(2), object(11)
memory usage: 747.8+ KB

处理完空值之后,数据还剩6837条,13列。

重复值

处理完空值以后,我们还需要注意另外一个会影响我们分析结果的因素,就是重复值。

我们来看一下计算一下重复的数据,并将其删除。

使用data.duplicated()方法判断每一行是否重复,然后使用data.duplicated()[data.duplicated()==True]取出重复行,最后使用len()计算重复的数据。

%matplotlib inline
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

# 导入数据
path = r'C:\Users\lin-a\Desktop\data\analyse_spider.csv'
data = pd.read_csv(path,encoding='GBK')

# 删除缺失值的数据列businessZones
data.drop(columns='businessZones',axis=1,inplace=True)
# 同时删除缺失值的行
data.dropna(inplace=True)

# 计算重复的数据数量
print(len(data.duplicated()[data.duplicated()==True]))
# 删除重复数据
data.drop_duplicates(inplace=True)
data.info()
1830
<class 'pandas.core.frame.DataFrame'>
Int64Index: 5007 entries, 0 to 6766
Data columns (total 13 columns):
 #   Column             Non-Null Count  Dtype 
---  ------             --------------  ----- 
 0   city               5007 non-null   object
 1   companyId          5007 non-null   int64 
 2   companySize        5007 non-null   object
 3   firstType          5007 non-null   object
 4   secondType         5007 non-null   object
 5   education          5007 non-null   object
 6   industryField      5007 non-null   object
 7   positionId         5007 non-null   int64 
 8   positionAdvantage  5007 non-null   object
 9   positionName       5007 non-null   object
 10  positionLables     5007 non-null   object
 11  salary             5007 non-null   object
 12  workYear           5007 non-null   object
dtypes: int64(2), object(11)
memory usage: 547.6+ KB

共有1830条重复的数据,使用data.drop_duplicates()删除后,还剩5007条数据。

数据的缺失值和重复值,是我们在分析之前必须要做,因为,他们的存在会很大程度上影响我们的分析结果。

四、整理和数据分析

我们的第一个任务是薪酬分布情况,所以我们先来整理这个数据。

在这里插入图片描述

薪资字段格式基本分为15k-25k和15k以上这两种,并且都是字符串。

如果我们只想要薪资下限数据或者薪资上限数据时,怎么办呢?

最好的方式就将salary薪资字段按照最高薪水和最低薪水拆成两列,并且薪水的话如果用几K表示,直接用于计算,所以将k去掉。

这里我们可以使用pandas中的apply方法,针对薪酬这一列数据进行操作,结果如下图。

在这里插入图片描述

# 定义拆分的行数
def split_salary(salary,method):
    # 获取“-”的索引值
    position = salary.upper().find('-')
    if position != -1:# salary值是15k-25k的样式
        low_salary = salary[:position-1]
        high_salary = salary[position+1:len(salary)-1]
        
    else:# salary值是15k以上的样式
        low_salary = salary[:salary.upper().find('K')]
        high_salary = low_salary
    
    # 根据参数用以判断返回的值
    if method == 'low':
        return low_salary
    if method == 'high':
        return high_salary
    if method == 'avg':
        return (int(low_salary)+int(high_salary))/2

# 赋值
data['low_salary'] = data.salary.apply(split_salary,method='low')
data['high_salary'] = data.salary.apply(split_salary,method='high')
data['avg_salary'] = data.salary.apply(split_salary,method='avg')
data.head()
city companyId companySize businessZones firstType secondType education industryField positionId positionAdvantage positionName positionLables salary workYear low_salary high_salary avg_salary
0 上海 8581 2000人以上 ['张江'] 技术 数据开发 硕士 移动互联网 2537336 知名平台 数据分析师 ['分析师', '数据分析', '数据挖掘', '数据'] 7k-9k 应届毕业生 7 9 8.0
1 上海 23177 500-2000人 ['五里桥', '打浦桥', '制造局路'] 技术 数据开发 本科 金融 2427485 挑战机会,团队好,与大牛合作,工作环境好 数据分析师-CR2017-SH2909 ['分析师', '数据分析', '数据挖掘', '数据'] 10k-15k 应届毕业生 10 15 12.5
2 上海 57561 50-150人 ['打浦桥'] 设计 数据分析 本科 移动互联网 2511252 时间自由,领导nic 数据分析师 ['分析师', '数据分析', '数据'] 4k-6k 应届毕业生 4 6 5.0
3 上海 7502 150-500人 ['龙华', '上海体育场', '万体馆'] 市场与销售 数据分析 本科 企业服务,数据服务 2427530 五险一金 绩效奖金 带薪年假 节日福利 大数据业务分析师【数云校招】 ['商业', '分析师', '大数据', '数据'] 6k-8k 应届毕业生 6 8 7.0
4 上海 130876 15-50人 ['上海影城', '新华路', '虹桥'] 技术 软件开发 本科 其他 2245819 在大牛下指导 BI开发/数据分析师 ['分析师', '数据分析', '数据', 'BI'] 2k-3k 应届毕业生 2 3 2.5
  • 第一步,我们自定义了一个函数split_salary()函数,salary参数是使用apply函数必须要传的参数,其实就是data.salary的值。

  • 第二步,使用salary.upper().find(’-’)判断salary值是15k-25k的形式还是15k以上形式,如果结果是-1,表示是15k以上形式,反之是15k-25k形式。为了避免k的大小写,我们用upper函数将k都转换为K,然后以K作为截取。

  • 第三步,在split_salary函数增加了新的参数用以判断返回low_salary还是high_salary或者是avg_salary。

分列除了采取以上的find()函数外,还可以使用split()函数,如下所示:

import pandas as pd

df = pd.DataFrame(data={'序号':[1,2,3,4],
                       '待遇':['12K','12K-15K','20-22k','20k以上']})
df2 = df['待遇'].str.split('-',expand=True)
df2
0 1
0 12K None
1 12K 15K
2 20 22k
3 20k以上 None
df
序号 待遇
0 1 12K
1 2 12K-15K
2 3 20-22k
3 4 20k以上

到此,我们完成了数据整理部分,接着我们看看数据分析师的薪酬情况。

五、绘制图表

%matplotlib inline
import matplotlib.pyplot as plt
from matplotlib import font_manager
import seaborn as sns

# 定义中文字体
my_font = font_manager.FontProperties(fname=r'C:\Users\lin-a\Desktop\Python数据分析\经典黑体简.TTF')
sns.set(style='darkgrid')
plt.figure(figsize=(10,8),dpi=80)
plt.hist(data['avg_salary'],width=5)
plt.xlabel('薪酬区间',fontproperties=my_font)
plt.ylabel('数量',fontproperties=my_font)
plt.title('数据分析师薪酬分布图',fontproperties=my_font)
plt.show()

在这里插入图片描述

接着我们按照城市来观察不同城市对薪酬的影响:

图表中绘制了数据分析师薪资的分布,可以看出薪资的大部分在10k-30k之间,10k-20k这个范围最多。

%matplotlib inline
import matplotlib.pyplot as plt
from matplotlib import font_manager
import seaborn as sns

my_font = font_manager.FontProperties(fname=r'C:\Users\lin-a\Desktop\Python数据分析\经典黑体简.TTF')
plt.figure(figsize=(20,8),dpi=80)
sns.set(style='darkgrid')

groups = data.groupby(by='city')
xticks = []
for group_name,group_df in groups:
    xticks.append(group_name)
    plt.bar(group_name,group_df.avg_salary.mean())
plt.xticks(xticks,fontproperties=my_font)
plt.title('不同城市薪酬分布',fontproperties=my_font)
plt.ylabel('薪酬水平',fontproperties=my_font)
plt.show()

在这里插入图片描述

代码中我们用city进行分组,然后分别绘制了每个城市的平均薪资。
从图表中我们看出,北京的数据分析师薪资高于其他城市,上海和深圳稍次,广州甚至不如杭州和苏州。

接下来,我们再看看不同学历对薪资的影响。
我们同样按学历进行分组,然后对比不同学历的平均薪资。

%matplotlib inline
import matplotlib.pyplot as plt
from matplotlib import font_manager

my_font = font_manager.FontProperties(fname=r'C:\Users\lin-a\Desktop\Python数据分析\经典黑体简.TTF')
plt.figure(figsize=(6,4),dpi=80)
sns.set(style='darkgrid')

groups = data.groupby(by='education')
xticks = []
for group_name,group_df in groups:
    xticks.append(group_name)
    plt.bar(group_name,group_df.avg_salary.mean())
plt.xticks(xticks,fontproperties=my_font)
plt.title('不同学历水平薪酬分布',fontproperties=my_font)
plt.ylabel('薪酬水平',fontproperties=my_font)
plt.show()

在这里插入图片描述

代码中我们用city进行分组,然后分别绘制了不同学历的平均薪资。

从图表中我们看出,博士薪资最高,硕士和本科基本持平,大专学历稍有弱势。

最后,我们再看看不同工作年限对薪资的影响。

我们同样按工作年年限进行分组,然后对比不同年限的平均薪资。

%matplotlib inline
import matplotlib.pyplot as plt
from matplotlib import font_manager

my_font = font_manager.FontProperties(fname=r'C:\Users\lin-a\Desktop\Python数据分析\经典黑体简.TTF')
plt.figure(figsize=(6,4),dpi=80)
sns.set(style='darkgrid')

groups = data.groupby(by='workYear')
xticks = []
for group_name,group_df in groups:
    xticks.append(group_name)
    plt.bar(group_name,group_df.avg_salary.mean())
plt.xticks(xticks,fontproperties=my_font)
plt.title('不同工作年限薪酬分布',fontproperties=my_font)
plt.ylabel('薪酬水平',fontproperties=my_font)
plt.show()

在这里插入图片描述

薪资我们就简单的分析到这里,我们简单的归纳一下我们数据展现的结果:

  1. 数据分析师的薪资的平均数是17k,最大薪资在75k,大部分分析师薪资在10k-20k之间。
  2. 北京的数据分析师薪资高于其他城市,上海和深圳稍次,杭州和苏州已经超过广州。
  3. 薪资最高的是博士,硕士和本科的薪资基本持平,大专学历稍有弱势。
  4. 工作年限越长,薪资就越高。

根据上面数据展现的结果可以得到这样的结论:北上广深依然是我们高薪就业地,同时工作年限和学历都是都与薪资成线性增长趋势。

  1. 2019年全年的天气数据,完成如下需求: 1. 2019年北京哪个月的气温波动最大? 2. 2019年各种空气质量的占比是多少?
%matplotlib inline
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# 导入数据
data = pd.read_
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章