In [1]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
In [2]:
#读取excel数据并转化为csv格式
data_xls=pd.read_excel('地市级党委书记数据库(2000-10).xls','中国人民共和国地市级党委书记数据库(2000-10)',index_col = 0)
data_xls.to_csv('test_csv.csv', encoding='utf-8')
 
In [3]:
#读取csv格式的文件
data=pd.read_csv('test_csv.csv')
data.head(5)
 
 
Out[3]:
0130000河北省130100石家庄市2000陈来立NaNNaNNaNNaN...NaN硕士1.0NaNNaNNaNNaNNaNNaNNaN
1130000河北省130100石家庄市2001吴振华NaNNaNNaNNaN...NaN本科0.00.00.01.00.00.0NaNNaN
2130000河北省130100石家庄市2002吴振华NaNNaNNaNNaN...NaN本科0.00.00.01.00.00.0NaNNaN
3130000河北省130100石家庄市2003吴振华NaNNaNNaNNaN...NaN本科0.00.00.01.00.00.0NaNNaN
4130000河北省130100石家庄市2004吴振华NaNNaNNaNNaN...NaN本科0.00.00.01.00.00.0NaNNaN

5 rows × 23 columns

In [4]:
#把列名转化长一个列表
filed=data.columns.tolist()
print(filed)
print(data.columns)
['省级政区代码', '省级政区名称', '地市级政区代码', '地市级政区名称', '年份', '党委书记姓名', '出生年份', '出生月份', '籍贯省份代码', '籍贯省份名称', '籍贯地市代码', '籍贯地市名称', '性别', '民族', '教育', '是否是党校教育(是=1,否=0)', '专业:人文', '专业:社科', '专业:理工', '专业:农科', '专业:医科', '入党年份', '工作年份']
Index(['省级政区代码', '省级政区名称', '地市级政区代码', '地市级政区名称', '年份', '党委书记姓名', '出生年份',
'出生月份', '籍贯省份代码', '籍贯省份名称', '籍贯地市代码', '籍贯地市名称', '性别', '民族', '教育',
'是否是党校教育(是=1,否=0)', '专业:人文', '专业:社科', '专业:理工', '专业:农科', '专业:医科', '入党年份',
'工作年份'],
dtype='object')
In [5]:
print(data.describe(include=[np.number]))
print('----------')
# .describe()返回基本数据信息
# .describe(include=[np.number])只统计数值类型
# ()中没有任何参数时,会默认只统计数值类型的字段内容,包括:计数,平均数,方差,最小值,最大值,四分位数,若其中有字符串数据会报错
print(data.describe(include=[np.object]))
# 这里代表只统计字符串类型的字段内容:计数,唯一值数量,出现频率最高的内容,最高出现频率
 
 
 
              省级政区代码        地市级政区代码           年份         出生年份         出生月份  \
count 3663.000000 3663.000000 3663.000000 2676.000000 2645.000000
mean 403393.393393 404456.756757 2005.000000 1953.622571 6.790548
std 148176.721620 148485.810327 3.162709 4.416316 3.614664
min 130000.000000 130100.000000 2000.000000 1941.000000 1.000000
25% 330000.000000 330100.000000 2002.000000 1951.000000 3.000000
50% 420000.000000 420200.000000 2005.000000 1954.000000 7.000000
75% 510000.000000 513400.000000 2008.000000 1956.000000 10.000000
max 650000.000000 654300.000000 2010.000000 1966.000000 14.000000 籍贯省份代码 籍贯地市代码 是否是党校教育(是=1,否=0) 专业:人文 \
count 2624.000000 2615.000000 2493.000000 2370.000000
mean 364428.353659 365742.332696 0.430405 0.275527
std 126267.485520 125961.993399 0.576136 0.446874
min 110000.000000 120000.000000 0.000000 0.000000
25% 320000.000000 320700.000000 0.000000 0.000000
50% 370000.000000 370700.000000 0.000000 0.000000
75% 430000.000000 431300.000000 1.000000 1.000000
max 640000.000000 640500.000000 9.000000 1.000000 专业:社科 专业:理工 专业:农科 专业:医科 入党年份 \
count 2376.000000 2371.000000 2369.000000 2370.000000 2384.000000
mean 0.627525 0.256854 0.067539 0.009705 1976.906879
std 0.483566 0.436990 0.251006 0.098054 5.310080
min 0.000000 0.000000 0.000000 0.000000 1961.000000
25% 0.000000 0.000000 0.000000 0.000000 1973.000000
50% 1.000000 0.000000 0.000000 0.000000 1976.000000
75% 1.000000 1.000000 0.000000 0.000000 1981.000000
max 1.000000 1.000000 1.000000 1.000000 1994.000000 工作年份
count 2568.000000
mean 1973.129673
std 4.856564
min 1958.000000
25% 1970.000000
50% 1972.500000
75% 1976.000000
max 1990.000000
----------
省级政区名称 地市级政区名称 党委书记姓名 籍贯省份名称 籍贯地市名称 性别 民族 教育
count 3663 3663 3021 2624 2615 2708 2517 2550
unique 27 333 901 29 240 2 2 7
top 广东省 白山市 焉荣竹 山东省 威海市 男 汉族 硕士
freq 231 11 11 313 58 2633 2351 1381
In [6]:
#取出性别这一列
data_gender=data['性别']
data_gender.head()
Out[6]:
0    NaN
1 NaN
2 NaN
3 NaN
4 NaN
Name: 性别, dtype: object
In [7]:
 
#过来吃掉空值
data_gender_re=data_gender[data_gender.notnull()]
data_gender_re.head()
Out[7]:
121    男
122 男
123 男
124 男
125 男
Name: 性别, dtype: object
In [8]:
#查看性别这一列都有那些数值
data_gender_re.unique()
Out[8]:
array(['男', '女'], dtype=object)
In [9]:
#统计总数
count_total=data_gender_re.count()
count_total
Out[9]:
2708
In [10]:
#分别统计男女占比
count_m=data_gender_re[data_gender_re=='男'].count()
count_m
Out[10]:
2633
In [11]:
#统计女的数量
count_f=data_gender_re[data_gender_re=='女'].count()
count_f
Out[11]:
75
In [12]:
#分别查看男女数量
data_gender_re.value_counts()
Out[12]:
男    2633
女 75
Name: 性别, dtype: int64
In [13]:
#查看男占比
count_m/count_total
Out[13]:
0.9723042836041359
In [14]:
#查看女占比
count_f/count_total
Out[14]:
0.027695716395864108

按省份分析市委书记的女性比例

In [15]:
#取出省份和性别这两列,过滤掉性别为空的
data_gender2 = data[['省级政区名称','性别']]
data_gender2_re = data_gender2[data_gender2['性别'].notnull()]
data_gender2_re.head()
 
Out[15]:
121山西省
122山西省
123山西省
124山西省
125山西省
In [16]:
#按省份分组,统计性别的频数
pt=pd.crosstab(data_gender2_re['省级政区名称'],data_gender2_re['性别'])
pt.head()
Out[16]:
云南省273
内蒙古自治区086
吉林省472
四川省8155
宁夏回族自治区049
In [17]:
#给pt1新增一列女性占比,按男性占比后赋值给pt2
pt['女性占比']=pt['女']/(pt['男']+pt['女'])
pt2=pt.sort_values(by=['女性占比'],ascending=False)
pt2.head()
 
Out[17]:
辽宁省131210.097015
陕西省9930.088235
吉林省4720.052632
山西省61120.050847
四川省81550.049080
In [18]:
#根据上面结构绘图
#创建一张8*4的图标
fig_q1_1=plt.figure(figsize=(8,4))
#把省份作为横轴,取钱10个
index=pt2.index[:10]
plt.bar(range(10),  # 横坐标
        pt2['女性占比'][:10], # 纵坐标
        tick_label=index, # 横轴标签
        color = 'red' )  # 颜色
plt.title('不同省份女性市委书记占比')
plt.xlabel('省份')
plt.ylabel('女性占比')
plt.show()
 
 
 
In [19]:
##图标2:女性视为书籍的占比结构
fig_q1_2=plt.figure(figsize=(4,4))
plt.boxplot(pt2['女性占比'],#值
           vert=True,#纵向
           showmeans=True)#显示均值
plt.title('女性市委书记占比')
plt.xticks([])
plt.ylabel('女性占比')
plt.show()
 
 
 
 

年龄情况 ,专业情况

In [20]:
#年龄情况,整体年龄情况/入职年龄情况/退休年龄情况
data_age=data[['出生年份','党委书记姓名','年份']]
data_age.head()
 
 
Out[20]:
0NaN陈来立2000
1NaN吴振华2001
2NaN吴振华2002
3NaN吴振华2003
4NaN吴振华2004
In [21]:
#过滤掉出生年份为空的
data_age_re=data_age[data_age['出生年份'].notnull()]
data_age_re.head()
Out[21]:
1211945.0侯伍杰2000
1221945.0侯伍杰2001
1231950.0云公民2002
1241950.0云公民2003
1251950.0云公民2004
In [23]:
 
#查看出生年份的组成值
data_age_re['出生年份'].unique()
 
Out[23]:
array([1945., 1950., 1956., 1949., 1952., 1957., 1953., 1960., 1955.,
1951., 1954., 1948., 1947., 1946., 1944., 1962., 1964., 1942.,
1963., 1958., 1965., 1943., 1961., 1959., 1941., 1966.])
In [24]:
#查看出生年份的描述
data_age_re.describe()
Out[24]:
count2676.0000002676.000000
mean1953.6225712005.214499
std4.4163163.046486
min1941.0000002000.000000
25%1951.0000002003.000000
50%1954.0000002005.000000
75%1956.0000002008.000000
max1966.0000002010.000000
In [31]:
 
#计算出整体年龄数据
df1=2017-data_age_re['出生年份']
df1.head()
Out[31]:
121    72.0
122 72.0
123 67.0
124 67.0
125 67.0
Name: 出生年份, dtype: float64
In [37]:
df1.describe()
Out[37]:
count    2676.000000
mean 63.377429
std 4.416316
min 51.000000
25% 61.000000
50% 63.000000
75% 66.000000
max 76.000000
Name: 出生年份, dtype: float64
In [53]:
#计算入职年龄(先计算每个人入职年龄的最小值),再看每个年份的入职人数
df_yearmin = data_age_re[['党委书记姓名','年份']].groupby(data_age_re['党委书记姓名']).min()
df2=df_yearmin['年份'].groupby(df_yearmin['年份']).count()
df2
Out[53]:
年份
2000 190
2001 69
2002 65
2003 88
2004 51
2005 55
2006 50
2007 59
2008 99
2009 23
Name: 年份, dtype: int64
In [55]:
#查看卸任年龄
df_yearmax = data_age_re[['党委书记姓名','年份']].groupby(data_age_re['党委书记姓名']).max()
df3=df_yearmax.groupby(df_yearmax['年份']).count()
df3
 
 
Out[55]:
200047
200144
200271
200338
200448
200549
200658
2007105
200825
200941
2010223
In [64]:
##专业情况  专业结构 / 专业整体情况 / 专业大类分布 
data_major=data[['党委书记姓名','专业:人文','专业:社科','专业:理工','专业:农科','专业:医科']]
data_major_re=data[data_major['专业:人文'].notnull()]
data_major_re.head()
 
 
Out[64]:
1130000河北省130100石家庄市2001吴振华NaNNaNNaNNaN...NaN本科0.00.00.01.00.00.0NaNNaN
2130000河北省130100石家庄市2002吴振华NaNNaNNaNNaN...NaN本科0.00.00.01.00.00.0NaNNaN
3130000河北省130100石家庄市2003吴振华NaNNaNNaNNaN...NaN本科0.00.00.01.00.00.0NaNNaN
4130000河北省130100石家庄市2004吴振华NaNNaNNaNNaN...NaN本科0.00.00.01.00.00.0NaNNaN
5130000河北省130100石家庄市2005吴振华NaNNaNNaNNaN...NaN本科0.00.00.01.00.00.0NaNNaN

5 rows × 23 columns

In [66]:
 
data_major_re.mean()
 
 
Out[66]:
省级政区代码              388046.413502
地市级政区代码 388781.772152
年份 2005.479747
出生年份 1954.297048
出生月份 6.704082
籍贯省份代码 369873.772791
籍贯地市代码 371312.159624
是否是党校教育(是=1,否=0) 0.406809
专业:人文 0.275527
专业:社科 0.626582
专业:理工 0.256540
专业:农科 0.067539
专业:医科 0.009705
入党年份 1977.430507
工作年份 1973.622338
dtype: float64
In [67]:
data_major_re.describe()
 
Out[67]:
count2370.0000002370.0000002370.0000002168.0000002156.0000002139.0000002130.0000002350.0000002370.0000002370.0000002370.0000002369.0000002370.0000001993.0000002113.000000
mean388046.413502388781.7721522005.4797471954.2970486.704082369873.772791371312.1596240.4068090.2755270.6265820.2565400.0675390.0097051977.4305071973.622338
std137507.595852137533.4258653.0402904.2505033.618283126451.656681126006.1848350.4913430.4468740.4838140.4368150.2510060.0980545.2655694.857468
min130000.000000130100.0000002000.0000001941.0000001.000000110000.000000120000.0000000.0000000.0000000.0000000.0000000.0000000.0000001964.0000001960.000000
25%320000.000000321300.0000002003.0000001952.0000003.000000320000.000000320900.0000000.0000000.0000000.0000000.0000000.0000000.0000001974.0000001970.000000
50%410000.000000410600.0000002006.0000001954.0000007.000000370000.000000370900.0000000.0000000.0000001.0000000.0000000.0000000.0000001976.0000001973.000000
75%450000.000000451175.0000002008.0000001957.00000010.000000440000.000000440500.0000001.0000001.0000001.0000001.0000000.0000000.0000001982.0000001976.000000
max650000.000000650200.0000002010.0000001966.00000014.000000640000.000000640500.0000001.0000001.0000001.0000001.0000001.0000001.0000001994.0000001990.000000
In [86]:
 
#统计每个人的专业
data_major_re['专业']=data_major_re[['专业:人文', '专业:社科', '专业:理工', '专业:农科', '专业:医科']].idxmax(axis=1)
data_major_re.head()
C:\Anaconda3\lib\site-packages\ipykernel_launcher.py:2: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
Out[86]:
1130000河北省130100石家庄市2001吴振华NaNNaNNaNNaN...本科0.00.00.01.00.00.0NaNNaN专业:理工
2130000河北省130100石家庄市2002吴振华NaNNaNNaNNaN...本科0.00.00.01.00.00.0NaNNaN专业:理工
3130000河北省130100石家庄市2003吴振华NaNNaNNaNNaN...本科0.00.00.01.00.00.0NaNNaN专业:理工
4130000河北省130100石家庄市2004吴振华NaNNaNNaNNaN...本科0.00.00.01.00.00.0NaNNaN专业:理工
5130000河北省130100石家庄市2005吴振华NaNNaNNaNNaN...本科0.00.00.01.00.00.0NaNNaN专业:理工

5 rows × 24 columns

In [90]:
#去重
data_major_st=data_major_re[['党委书记姓名','专业']].drop_duplicates()
data_major_st.head()
Out[90]:
1吴振华专业:理工
7吴显国专业:社科
9车俊专业:社科
10孙瑞彬专业:社科
11白润璋专业:理工
In [93]:
#统计专业结构
df4=data_major_st['专业'].groupby(data_major_st['专业']).count()
df4
Out[93]:
专业
专业:人文 187
专业:农科 21
专业:医科 5
专业:理工 127
专业:社科 346
Name: 专业, dtype: int64
In [96]:
#计算每年专业的整体数据情况(这是未去重的)
df5=pd.crosstab(data_major_re['年份'],data_major_re['专业'])
df5
Out[96]:
200033724353
200142633678
200256543590
2003677225106
2004687228118
2005637231123
2006679234123
2007698234128
2008688044130
2009678042131
2010717038131
In [97]:
# 计算每年专业大类分布数据
df5['社科比例'] = df5['专业:社科'] / (df5['专业:理工'] + df5['专业:医科'] + df5['专业:社科'] + df5['专业:农科'] + df5['专业:人文'])
df5['人文比例'] = df5['专业:人文'] / (df5['专业:理工'] + df5['专业:医科'] + df5['专业:社科'] + df5['专业:农科'] + df5['专业:人文'])
df5['理工农医比例'] = (df5['专业:理工'] + df5['专业:医科'] + df5['专业:农科'])/ (df5['专业:理工'] + df5['专业:医科'] + df5['专业:社科'] + df5['专业:农科'] + df5['专业:人文'])
print(df5[['社科比例','人文比例','理工农医比例']])
 
专业        社科比例      人文比例    理工农医比例
年份
2000 0.384058 0.239130 0.376812
2001 0.472727 0.254545 0.272727
2002 0.473684 0.294737 0.231579
2003 0.512077 0.323671 0.164251
2004 0.529148 0.304933 0.165919
2005 0.544248 0.278761 0.176991
2006 0.523404 0.285106 0.191489
2007 0.531120 0.286307 0.182573
2008 0.520000 0.272000 0.208000
2009 0.528226 0.270161 0.201613
2010 0.530364 0.287449 0.182186
 

年龄情况的图标绘制

In [120]:
 
fig_q2=plt.figure(figsize=(12,8))
ax1=fig_q2.add_subplot(2,3,1)
ax2=fig_q2.add_subplot(2,3,2)
ax3=fig_q2.add_subplot(2,3,3)
ax4=fig_q2.add_subplot(2,3,4)
ax5=fig_q2.add_subplot(2,3,5)
ax6=fig_q2.add_subplot(2,3,6)
#亿创建的图标划分成2*3#的表格矩阵
ax1.hist(df1,bins=11,color='gray',alpha=0.9)
ax1.set_title('整体年龄分布')
ax1.grid(True)
ax2.plot(df2,color='r',marker='o',alpha=0.9)
ax2.set_title('入职年龄分布')
ax2.set_xticks(range(2000,2011,2))
ax2.grid(True)
ax3.plot(df3,color='g',marker='o',alpha=0.9)
ax3.set_title('卸任年龄分布')
ax3.set_xticks(range(2000,2011,2))
ax3.grid(True)
ax4.bar(range(len(df4)),df4,color='y')
ax4.set_xticklabels(['人文','农科','医科','理工','社科'])
ax4.grid(True)
ax4.set_title('专业结构')
ax5.plot(df5.index,df5[['专业:人文','专业:农科','专业:医科','专业:理工','专业:社科']])
ax5.grid(True)
ax5.set_title('专业整体情况')
ax6.bar(df5.index,df5['社科比例'],color = 'darkred',alpha=0.7)
ax6.bar(df5.index,df5['人文比例'],color = 'darkred',bottom = df5['社科比例'],alpha=0.5)
ax6.bar(df5.index,df5['理工农医比例'],color = 'darkred',bottom = df5['人文比例'] + df5['社科比例'],alpha=0.3)
ax6.grid(True)
ax6.set_title('专业大类分布:社科、人文、理工农医')
plt.show()
 
 
 
 

任期

In [128]:
#出生年份与任期的关系
# 新建变量data_term,赋值包括年份、姓名、出生年份字段内容
# 清除缺失值
data_term=data[['年份','党委书记姓名','出生年份']]
data_term_re=data_term[data_term['出生年份'].notnull()]
data_term_re.head()
 
Out[128]:
1212000侯伍杰1945.0
1222001侯伍杰1945.0
1232002云公民1950.0
1242003云公民1950.0
1252004云公民1950.0
In [129]:
year_max = data_term_re[['出生年份','年份']].groupby(data_term_re['党委书记姓名']).max()
year_max.rename(columns={'年份':'年份max'}, inplace = True)
year_max['姓名'] = year_max.index
# 统计每个党委书记任期年份最大值,且更改列明
# 将index提取出字段内容
 
 
In [130]:
year_min = data_term_re[['出生年份','年份']].groupby(data_term_re['党委书记姓名']).min()
year_min.rename(columns={'年份':'年份min'}, inplace = True)
year_min['姓名'] = year_min.index
# 统计每个党委书记任期年份最小值,且更改列明
# 将index提取出字段内容
 
In [131]:
data_term_fin = pd.merge(year_max,year_min)
print(data_term_fin.head())
print(data_term_fin.dtypes)
# 合并表格,默认重叠重复列明
# .dtypes查看字段类型 → 年份均为int
 
     出生年份  年份max   姓名  年份min
0 1951.0 2009 丁海中 2003
1 1948.0 2003 丁耀民 2000
2 1951.0 2007 丁解民 2001
3 1964.0 2007 万庆良 2005
4 1957.0 2010 丰立祥 2008
出生年份 float64
年份max int64
姓名 object
年份min int64
dtype: object
In [132]:
 
data_term_fin['任期'] = data_term_fin['年份max'] - data_term_fin['年份min']
print(data_term_fin.head())
# 计算任期
 
     出生年份  年份max   姓名  年份min  任期
0 1951.0 2009 丁海中 2003 6
1 1948.0 2003 丁耀民 2000 3
2 1951.0 2007 丁解民 2001 6
3 1964.0 2007 万庆良 2005 2
4 1957.0 2010 丰立祥 2008 2
In [133]:
# 绘制图表1:任期与出生年份关系
fig_q3_1 = plt.figure(figsize = (8,4))
# 创建一个图表,大小为8*4
plt.scatter(data_term_fin['出生年份'],data_term_fin['任期'],color = 'black', alpha=0.2, s = 10)
plt.title('任期与出生年份关系')
plt.xlabel('出身年份')
plt.ylabel('任期(年)')
plt.grid(True)
plt.show()
# 创建散点图,aplha代表透明度 → 点颜色叠加,s代表点大小,
# 参数添加,grid添加网格
# plt.show():显示图表
 
 
 
In [135]:
 
# 绘制图表2:任期与出生年份关系 - 热图
fig_q3_2 = plt.figure(figsize = (8,4))
# 创建一个图表,大小为8*4
df = pd.crosstab(data_term_fin['任期'], data_term_fin['出生年份'])
print(df.head())
print('----------')
# 整合数据
ax = fig_q3_2.add_subplot(111)
cax = ax.pcolor(df, cmap='Blues')
#cax = ax.matshow(df, cmap='Blues_r')
fig_q3_2.colorbar(cax)
plt.title('任期与出生年份关系 - 热图\n')
ax.set_xticklabels(data_term_fin['出生年份'].tolist())
plt.show()
# 创建热图,横坐标为出生年份,纵坐标为任期,
 
 
 
出生年份  1941.0  1942.0  1943.0  1944.0  1945.0  1946.0  1947.0  1948.0  1949.0  \
任期
0 4 2 6 5 6 7 3 5 7
1 2 3 1 6 3 6 3 6 8
2 0 2 1 4 6 9 5 11 11
3 0 0 0 1 1 4 2 4 7
4 0 0 0 0 2 1 0 0 3 出生年份 1950.0 ... 1957.0 1958.0 1959.0 1960.0 1961.0 1962.0 1963.0 \
任期 ...
0 3 ... 2 2 0 1 1 0 0
1 8 ... 13 6 4 3 1 7 1
2 5 ... 19 9 5 3 9 7 3
3 8 ... 6 5 3 4 1 4 0
4 5 ... 8 2 2 1 1 2 0 出生年份 1964.0 1965.0 1966.0
任期
0 0 1 0
1 2 0 2
2 4 0 0
3 2 2 0
4 0 1 0 [5 rows x 26 columns]
----------
 
In [ ]:
 
 
 
 
 
 
 
05-28 12:32