前言
最近在学习《从零开始学Python数据分析》这本书,第六章的综合实例——巴尔的摩公务员工资数据集,原网站上数据集被清除,于是在Kaggle上寻找了相似的数据“Employee_monthly_salary.csv”进行可视化数据分析。
工作环境
系统: windows10
工具: pycharm2019.2.6
第三方包:
pandas1.1.4
numpy1.19.4
matplotlib==3.3.2
文件(Employee_monthly_salary.csv)
完整代码
# import numpy as np
import pandas as pd
# from pandas import DataFrame
import matplotlib.pyplot as plt
# import matplotlib as mlbpd.set_option('mode.chained_assignment', None) # 消除链接操作时警示(治标不治本)"""
EmpID 职工ID
Name 姓名
Gender 性别
Date_of_Birth 出生日期
Age 年龄
Join_Date 入职日期
Tenure_in_org_in_months 工作总月份
GROSS 总工资
Net_Pay 实际工资
Deduction 扣除部分
Deduction_percentage 扣除百分比
Designation 职位
Department 部门
""""""
我们即将实现的功能:1.男女平均工资对比;2.男性和女性最高工资和最低工资对比;3.月薪的分布状况 4.人数最多的职位Top5的平均工资;5.不同月份入职人员数量;6.任职时间和工资的关系"""# 主菜单
def menu():print('*' * 10, '请选择功能', '*' * 10, '\n')print('请输入对应功能的序号:')print("1.男女工资平均对比")print('2.最高工资和最低工资对比')print('3.月薪分布状况')print('4.人数最多的职位Top5的平均工资')print('5. 不同月份入职人员数量')print('6. 入职时间和工资的关系')print("输入0字符退出")print('*' * 10, '退出程序', '*' * 10, '\n')# 男女平均工资对比
def sex_salary(salary):avg_salary = salary.groupby('Gender')['Net_Pay'].mean() # 求平均数avg_salary.plot.bar(color='orange') # 设置柱的颜色plt.show() # 画布# 男性和女性最高工资和最低工资对比
def salary_contrast(salary):max_salary = salary.groupby('Gender', as_index=False)['Net_Pay'].max() # 求最大值print(max_salary)min_salary = salary.groupby('Gender', as_index=False)['Net_Pay'].min() # 求最小值print(min_salary)salary_s = pd.merge(max_salary, min_salary, on='Gender', suffixes=['_max_salary', '_min_salary']) # 数据合并,suffixes设置区分两个数据同名列# 由于最低工资过低,我们这里将它扩大100倍来进行比较salary_s['Net_Pay_min_salary'] = salary_s.loc[:, 'Net_Pay_min_salary'] * 100salary_s.plot(kind='bar') # bar代表柱形图plt.show()# 工资的分布状况
def salary_distribution(salary):salary['Net_Pay'].hist(bins=20) # bins将值分段,不设置默认为10, hist绘制直方图plt.show()# 人数最多的职位Top5的平均工资
def designation_top(salary):avg_salary = salary.groupby('Designation')['Net_Pay'].agg(['mean', 'count']) # 数据分组,mean求不同职位工资平均值,count计算不同职位人数sort_salary = avg_salary.sort_values(by='count', ascending=False)[:5] # by指定排序列名,ascending=False设置降序,默认升序sort_salary['mean'].plot(kind='bar') # 这里的mean是自动创建的平均值列名,绘制柱形图plt.show()# conversion函数用于将数据里类似“01”,“02”等转化为1,2,类型为str
def conversion(x):data = {'01': 1,'02': 2,'03': 3,'04': 4,'05': 5,'06': 6,'07': 7,'08': 8,'09': 9,}list_data = ['01', '02', '03', '04', '05', '06', '07', '08', '09']if x in list_data:x = data[x]return str(x)else:return x# 不同月份入职人员数量
def month_count(salary):salary['month'] = salary['month'].map(conversion) # 使用map函数将month列传入conversion实现数据修改month_counts = salary['month'].value_counts() # value_counts统计每个月份入职人员数month_counts.plot(kind='bar')plt.show()# 工作时间和工资的关系
def work_months(salary):salary.plot(kind='scatter', x='Tenure_in_org_in_months', y='Net_Pay') # 绘制散点图,展示工作时间和工资的关系plt.show()# 主函数
def main():df = pd.read_csv('Employee_salary.csv') # 读取数据集# print(df.info()) # 打印信息# print(df.shape) # DataFrame维度# print(df.isnull().sum()) # 统计缺失值总数df = df.dropna() # 删除有缺失值的行salary = df[['EmpID', 'Name', 'Gender', 'Age', 'Join_Date', 'Tenure_in_org_in_months', 'Net_Pay','Designation']] # 选择部分字段使用# df.to_csv('employee.csv') # 将新DataFrame对象数据写入csv文件中salary['month'] = salary['Join_Date'].str.split('/').str[1] # 将Join_Date入职日期分离,获取入职月份,添加新列到salary中menu()n = eval(input("请输入编号:(1/2/3/4/5/6/0):")) # 输入对应整数选择功能print("\n")if n == 1:sex_salary(salary)elif n == 2:salary_contrast(salary)elif n == 3:salary_distribution(salary)elif n == 4:designation_top(salary)elif n == 5:month_count(salary)elif n == 6:work_months(salary)else:exit(0)if __name__ == "__main__": # 当程序因为自身调动是才启动程序main()
功能效果展示
男女平均工资对比
分析:M(male)代表男性,F(female)代表女性,女性平均工资低于男性,大致接近(可能存在样本量不足因素)
男性和女性最高工资和最低工资对比
分析:0为女性,1为男性(忘了改了,问题不大),无论男性还是女性最低和最高工资差距极大(注意这里最低工资已经乘了100倍);最高工资男性较高,最低工资男女接近。
工资的分布状况
分析:满足正太分布,工资在100000左右的居大多数。
人数最多的职位Top5的平均工资
不同月份入职人员数量
分析:没有按照顺序排列月份(自己搞去),默认从高到低排列,7月入职的人最多,2月最少。
工作时间和工资的关系
分析:数据可见,工作时间长工资不一定就高啊。
数据集
最最重要的来了,拿走不用谢
码云(gitee)
注意:
我在项目文件里修改了文件名称,切莫忘记修改