2012联邦选举委员会数据分析
程序员文章站
2024-03-26 12:07:47
...
本片分析来自于《利用python进行数据分析》,为巩固学习成果,我对其实践了一遍。
import pandas as pd
fec = pd.read_csv('datasets/fec/P00000001-ALL.csv')
fec.info() #读取文件并查看信息
可以看到这里都是表格的column的名字,cand_nm是选民支持的候选人,但这些列里没有候选人党派的标记,所以我们用Map函数添加一个党派的标记
unique_cands = unique_cands = fec.cand_nm.unique()#得到一个候选人名单列表
parties = {'Bachmann, Michelle': 'Republican',
'Cain, Herman': 'Republican',
'Gingrich, Newt': 'Republican',
'Huntsman, Jon': 'Republican',
'Johnson, Gary Earl': 'Republican',
'McCotter, Thaddeus G': 'Republican',
'Obama, Barack': 'Democrat',
'Paul, Ron': 'Republican',
'Pawlenty, Timothy': 'Republican',
'Perry, Rick': 'Republican',
"Roemer, Charles E. 'Buddy' III": 'Republican',
'Romney, Mitt': 'Republican',
'Santorum, Rick': 'Republican'}#创建一个映射字典
fec['party'] = fec.cand_nm.map(parties) #在表中添加一列叫PARTY并映射党派
fec.groupby('party').size() #现在我们看看两个党派的选民支持数量,对表进行聚合,统计数目
可以看见,*党支持的人数要多一些
由于数据中存在选民退出情况,所以有取出金额情况,这时候金额为负值,这里我们只计算正值。所以进行筛选
fec = fec[fec.contb_receipt_amt > 0]
fec.contbr_occupation.value_counts()[:10]#对选民的职业进行统计,显示前十位
我们可以看见,选民中退休的人是最多的,其次是信息不全的人,其次就是律师了。信息当中INFORMATION REQUESTED PER BEST EFFORTS,INFORMATION REQUESTED,INFORMATION REQUESTED (BEST EFFORTS)等都是没提供信息的意思,我们再用一个映射函数把他们改成相同的名字。
occ_mapping = {
'INFORMATION REQUESTED PER BEST EFFORTS' : 'NOT PROVIDED',
'INFORMATION REQUESTED' : 'NOT PROVIDED',
'INFORMATION REQUESTED (BEST EFFORTS)' : 'NOT PROVIDED',
'C.E.O.': 'CEO'
}
f = lambda x : occ_mapping.get(x,x)
#这里用了一个小技巧,get(x,x)搜寻x,没搜寻到则返回x,
#即在occ_mapping里搜寻,没搜寻到就返回原名字x,搜寻到了就返回字典里对应的统一名字。
#这里的x输入是下面fec.contbr_occupation每一个名字,相当于对其进行一个遍历替换
fec.contbr_occupation = fec.contbr_occupation.map(f)
对雇主信息也进行同样的替换操作
emp_mapping = {
'INFORMATION REQUESTED PER BEST EFFORTS' : 'NOT PROVIDED',
'INFORMATION REQUESTED' : 'NOT PROVIDED',
'SELF' : 'SELF-EMPLOYED',
'SELF EMPLOYED' : 'SELF-EMPLOYED',
}
f = lambda x: emp_mapping.get(x, x)
fec.contbr_employer = fec.contbr_employer.map(f)
然后用数据透视表对各职业对两个党派的捐款,小的没有意义,直接看大的
by_occupation = fec.pivot_table('contb_receipt_amt',index='contbr_occupation' ,
columns='party',aggfunc='sum')
over_2mm = by_occupation[by_occupation.sum(1)>2000000]
over_2mm
over_2mm.plot(kind='barh')
我们想看看最大的捐款群体分别是谁
TOP10 = over_2mm.nlargest(10,columns=['Democrat','Republican'])
TOP10.plot(kind= 'barh')
我们还想看看威望最高的两位候选人分别的捐款情况
fec_mrbo = fec[fec.cand_nm.isin(['Obama, Barack','Romney, Mitt'])]
def get_top_amounts(group,key,n=5):
totals = group.groupby(key)['contb_receipt_amt'].sum()
return totals.nlargest(n)
grouped = fec_mrbo.groupby('cand_nm')
top7 = grouped.apply(get_top_amounts, 'contbr_occupation', n=7)
top7
我们想对这些数据进行一个数据化对比表示,我们先对它进行分段操作,以便于对比
import numpy as np
bins = np.array([0,1,10,100,1000, 10000,
100000, 1000000, 10000000])
labels = pd.cut(fec_mrbo.contb_receipt_amt, bins)
#对两位候选人的候选金额进行分段
labels
为了让数据更加直观,我们对这个分段标签和候选人进行聚合,以表示不同分段对不同候选人的支持人数
grouped = fec_mrbo.groupby(['cand_nm', labels])
grouped.size().unstack(0)
grouped.size().unstack(0).plot(kind='barh')
我们可以看到支持奥巴马的小额选民要多得多。但这样表现,大额选民的人数有但是基本看不见,下面我们用金额比例进行表示。
```python
bucket_sums = grouped.contb_receipt_amt.sum().unstack(0)#算各个分段两个候选人分别的资金
normed_sums = bucket_sums.div(bucket_sums.sum(axis=1), axis=0)#axis=1表示横向相加,这里用除法算比例。
normed_sums
normed_sums[:-2].plot(kind='barh')
总结
本篇分析主要在于对数据进行规整,然后做成数据透视表,对数据进行筛选和切片,以及对表中数据进行归一化处理,然后可视化出来。