美国选总统数据信息说明
数据下载连接
from matplotlib import pyplot as plt
%matplotlib inline
import numpy as np
import pandas as pd
# 导入数据
contb1 = pd.read_csv('./usa_elect/contb_01.csv')
contb2 = pd.read_csv('./usa_elect/contb_02.csv')
contb3 = pd.read_csv('usa_elect/contb_03.csv')
# 查看前几行
contb1.head()
# 查看有多少行 列
contb1.shape
# 合共三张表
contb = pd.concat([contb1,contb2,contb3])
# 查看有多少行 列
contb.shape
# 查看整体信息
contb.info() # 可以得出某些列中有空数据 下边要对某些列中的空数据进行填充
# 查看contbr_employer这一列为空的值
cond = contb['contbr_employer'].isnull()
contb[cond]
# 将所有为Nan的用NOT PROVIDE填充
contb['contbr_employer'].fillna('NOT PROVIDE',inplace = True)
contb['contbr_occupation'].fillna('NOT PROVIDE',inplace = True)
contb['contbr_st'].fillna('NOT PROVIDE',inplace = True)
# 查看整体信息
contb.info()
# 查看候选人的名字(去重)
contb.cand_nm.unique()
#通过搜索百度等途径,获取到每个总统候选人的所属党派,建立字典parties,候选人名字作为键,所属党派作为对应的值
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'}
# 映射 为每个候选人增加党派
contb['party'] = contb['cand_nm'].map(parties)
display(contb)
# 统计每个党派的人数
contb['party'].value_counts()
# 统计每个党派获得赞助资金总数
contb.groupby('party')['contb_receipt_amt'].sum()
# 统计每个职业赞助资金的总数,结果降序排序后只查看前7条
contb.groupby(['contbr_occupation'])['contb_receipt_amt'].sum().sort_values(ascending=False)[:50]
# 可以从结果种看出分组后的数据有些问题
# 1. 有些人在赞助时候,没有填自己的职业
# 2. 同一种职业有多种填法
# 所以要做出相应的修改,将相同的职业合并,没有填自己的职业的补充为NOT PROVIDE
occupation = {
'INFORMATION REQUESTED PER BEST EFFORTS':'NOT PROVIDE',
'INFORMATION REQUESTED':'NOT PROVIDE',
'C.E.O.':'CEO',
'LAWYER':'ATTORNEY',
'SELF':'SELF-EMPLOYED',
'SELF EMPLOYED ':'SELF-EMPLOYED'}
# map.get(x,x):若有x这个key,返回它对应value,若无返回x
f = lambda x : occupation.get(x,x)
contb['contbr_occupation'] = contb['contbr_occupation'].map(f)
contb.groupby(['contbr_occupation'])['contb_receipt_amt'].sum().sort_values(ascending=False)[:50]
# 查看各候选人获得的赞助总金额
contb_ = contb[contb['contb_receipt_amt'] > 0] # 捐赠金额大于0
cand_nm_amt = contb_.groupby(['cand_nm'])['contb_receipt_amt'].sum().sort_values(ascending = False)
# 选取候选人为Obama、Romney的子集数据,然后对contb_receipt_amt面元化
# 人话:将每个人捐赠的钱进行区间划分
# 方式一
contb_Obama_vs_Romney1 = contb_.query('cand_nm == "Obama, Barack" or cand_nm == "Romney, Mitt"')
contb_Obama_vs_Romney1.shape
# 方式二:
cond = contb_['cand_nm'].isin(['Romney, Mitt','Obama, Barack'])
contb_Obama_vs_Romney2 = contb_[cond]
contb_Obama_vs_Romney2.shape
# 查看捐赠最小 大金额
contb_['contb_receipt_amt'].min()
# 查看捐赠最小 大金额
contb_['contb_receipt_amt'].max()
# 区间准备
bins = [0,1,10,100,1000,10000,100000,1000000,10000000]
# 面元化
labels = pd.cut(contb_Obama_vs_Romney1['contb_receipt_amt'],bins)
display(labels.head())
# 统计各区间的赞助金额的总数
amt_Obama_vs_Romney = contb_Obama_vs_Romney1.groupby(['cand_nm',labels]).sum().unstack(level = 0)
amt_Obama_vs_Romney.fillna(0,inplace=True)
amt_Obama_vs_Romney
# 绘图
# 只绘制个人捐款的,组织基金会的捐款舍弃 即区间(100000, 1000000](1000000, 10000000]舍弃
amt_Obama_vs_Romney[:-2].plot(kind = 'bar')
# 百分比堆积图
amt_Obama_vs_Romney.div(amt_Obama_vs_Romney.sum(axis = 1),axis = 0)[:-2].plot(kind = 'bar',stacked = True)
# 透视表(pivot_table)分析党派和职业
# 按照党派、职业对赞助金额进行汇总
# 举例:因为张三支持民主党,所以就只会把money投给民主党,
# 不会投给共和党派,所以共和党派处就为NaN,可以用0进行填充
# 但是也有两党派都支持的
res = contb_.pivot_table('contb_receipt_amt',index='contbr_occupation',columns='party',aggfunc='sum',fill_value=0)
res.head()
# 统计哪个职业捐款最多
# 统计哪个职业捐款最多
res['total'] = res['Democrat'] + res['Republican']
res.sort_values(by='total',ascending=False).head()
# 过滤掉赞助金额小于200W的职业(为画图做准备)
# 过滤掉赞助金额小于200W的职业(为画图做准备)
cond = res['total'] >= 2000000
res_big = res[cond]
# 绘图
# 绘图
plt.figure(figsize=(20,8),dpi=80) # 设置宽高 像素
ax = plt.subplot(1,1,1)
res_big.plot(kind='bar',ax =ax)
# 根据职业分组后统计赞助资金的总和,结果降序排序并且取前n个
# 以下的方法做不到降序排序
t = contb_Obama_vs_Romney1.groupby(['cand_nm','contbr_occupation'])['contb_receipt_amt'].sum().unstack(level = 0)[:7]
display(t)
# 根据职业分组后统计赞助资金的总和,结果降序排序并且取前n个
# 可以做到降序排序
def get_top_amounts(grouped,key,n):
# 先根据key[contbr_occupation]进行分组,然后统计赞助资金的总和,结果降序排序并且取前n个
t = grouped.groupby(key)['contb_receipt_amt'].sum()
#display(type(t)) # t的类型为Series
return t.sort_values(ascending = False)[:n]
grouped = contb_Obama_vs_Romney1.groupby('cand_nm')
grouped.apply(get_top_amounts,'contbr_occupation',7)
# 反转之后就不在降序排序了
grouped.apply(get_top_amounts,'contbr_occupation',7).unstack(level=0)
# 时间处理
contb_Obama_vs_Romney1['contb_receipt_dt'] = pd.to_datetime(contb_Obama_vs_Romney1['contb_receipt_dt'])
contb_Obama_vs_Romney_time = contb_Obama_vs_Romney1.set_index('contb_receipt_dt')
# 重采样和频度转换
# 重采样(Resampling)指的是把时间序列的频度变为另一个频度的过程。
# 降采样(downsampling)把高频度的数据变为低频度。
# 这里我们把频率从每日转换为每月,属于高频转低频的降采样。
# resample会对数据进行分组,然后再调用聚合函数groupby。
vs_m = contb_Obama_vs_Romney_time.groupby(['cand_nm']).resample('M')['contb_receipt_amt'].sum().unstack(level = 0)
# 画图
vs_m.plot(kind = 'line')
# 依据州和候选人进行分组
state_vs = contb_Obama_vs_Romney1.groupby(['cand_nm','contbr_st'])['contb_receipt_amt'].sum().unstack(level = 0)
state_vs.fillna(0,inplace=True)
# 画图
# 删除错误的州名
state_vs_rate.drop(labels=['AA','AB','AE','NOT PROVIDE'],inplace = True)
plt.figure(figsize=(23,9))
ax = plt.subplot(1,1,1)
state_vs_rate.plot(kind = 'bar',stacked = True,ax=ax)