项目目的:通过对2012美国总统竞选赞助数据分析,得出哪个总统更具有优势的结论
项目流程:数据载入、数据清洗、数据聚合分组以及可视化
项目地址:https://tianchi.aliyun.com/notebook-ai/detail?postId=10585

一、导入数据

1.数据载入

导入需要用到的库numpy、pandas、matplotlib.pyplot

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

pd.read_scv来导入存储在csv中的数据。

data_01 = pd.read_csv('D:\mycode\python\study\data\data_01.csv')#用pd.read_csv读取数据
data_02 = pd.read_csv('D:\mycode\python\study\data\data_02.csv')
data_03 = pd.read_csv('D:\mycode\python\study\data\data_03.csv')

2.数据合并

pd.concat对数据进行拼接。

data = pd.concat([data_01, data_02, data_03])#可以将三份数据拼在一起

head()函数对数据前五行进行查看

data.head()#查看前五行数据

前五行数据

数据各字段的含义:

  • cand_nm – 接受捐赠的候选人姓名
  • contbr_nm – 捐赠人姓名
  • contbr_st – 捐赠人所在州
  • contbr_employer – 捐赠人所在公司
  • contbr_occupation – 捐赠人职业
  • contb_receipt_amt – 捐赠数额(美元)
  • contb_receipt_dt – 收到捐款的日期

info()对数据进行数据类型的查看

data.info()#查看数据的信息,每个字段的名称、非空数量、数据的类型
<class 'pandas.core.frame.DataFrame'>
Int64Index: 1001733 entries, 0 to 1730
Data columns (total 7 columns):
 #   Column             Non-Null Count    Dtype  
---  ------             --------------    -----  
 0   cand_nm            1001733 non-null  object 
 1   contbr_nm          1001733 non-null  object 
 2   contbr_st          1001729 non-null  object 
 3   contbr_employer    988004 non-null   object 
 4   contbr_occupation  993303 non-null   object 
 5   contb_receipt_amt  1001733 non-null  float64
 6   contb_receipt_dt   1001733 non-null  object 
dtypes: float64(1), object(6)
memory usage: 61.1+ MB

分析数据信息可知捐赠人职业和公司的两个数据有很大一部分的缺失。

describe()可以得知统计通用的概述值。

data.describe() #用统计学指标反应数据的概况,count非空数据、mean平均值、std标准差,后面为四分位数

统计概述

二、数据清洗

1.缺失值处理

fillna函数可以将数据中的NULL值转化为自己想要的值,其中inplace的值决定了直接覆盖还是创建副本。

data['contbr_employer'].fillna('NOT PROVIDED',inplace = True)#将数据集中的NULL用NOT PROVIDED代替,True代表直接修改原对象
data['contbr_occupation'].fillna('NOT PROVIDED',inplace = True)

2.数据转换

unique()函数是去重函数,其中format函数是将数值传入{}之中。

print('共有{}位候选人,分别是'.format(len(data['cand_nm'].unique())))#unique是将重复的去除
data['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'}

通过候选人的姓名为key值,用map()查询字典获得其党派存入党派列。通过value_counts对候选人所属党派进行统计。

data['party'] = data['cand_nm'].map(parties)#在data中增加一列存储党派,用map查询parties
data['party'].value_counts()#对党派的数据进行统计

党派

将数据根据捐赠人的职业进行划分,统计每个职业的捐赠数额,ascending=False表示为倒序。

#根据职业对数据进行
data.groupby('contbr_occupation')['contb_receipt_amt'].sum().sort_values(ascending=False)[:20]
contbr_occupation
RETIRED                                   48176647.00
ATTORNEY                                  18470473.30
HOMEMAKER                                 17484807.65
INFORMATION REQUESTED PER BEST EFFORTS    15859514.55
INFORMATION REQUESTED                      8742357.59
PHYSICIAN                                  7224044.40
PRESIDENT                                  6347843.59
EXECUTIVE                                  5273717.90
CONSULTANT                                 4932627.98
NOT PROVIDED                               4224760.39
CEO                                        3570942.20
LAWYER                                     3537982.19
OWNER                                      3278488.16
INVESTOR                                   3204481.92
ENGINEER                                   2730527.43
PROFESSOR                                  2458033.81
C.E.O.                                     2433218.11
SELF-EMPLOYED                              2259150.94
MANAGER                                    2167571.47
REAL ESTATE                                2110499.34
Name: contb_receipt_amt, dtype: float64

因为一些职业的名称不一样,但是却是同一个职业,所以对data中的数据进行循环去重。

occupation_map = {
  'INFORMATION REQUESTED PER BEST EFFORTS':'NOT PROVIDED',
  'INFORMATION REQUESTED':'NOT PROVIDED',
  'SELF' : 'SELF-EMPLOYED',
  'SELF EMPLOYED' : 'SELF-EMPLOYED',
  'C.E.O.':'CEO',
  'LAWYER':'ATTORNEY',
}
f = lambda x: occupation_map.get(x,x)
data.contbr_occupation = data.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)
data.contbr_employer = data.contbr_employer.map(f)

3.数据筛选

因为赞助还包括退款(负的),所以为了简化过程,只需要为正的

data = data[data['contb_receipt_amt']>0]

根据捐助人的姓名分组,进行金额的总和,倒叙排序

data.groupby('cand_nm')['contb_receipt_amt'].sum().sort_values(ascending = False)

从下方输出的结果来看,obama和romney的支持率是最高的,因此选择这两个来分析

cand_nm
Obama, Barack                     1.358776e+08
Romney, Mitt                      8.833591e+07
Paul, Ron                         2.100962e+07
Perry, Rick                       2.030675e+07
Gingrich, Newt                    1.283277e+07
Santorum, Rick                    1.104316e+07
Cain, Herman                      7.101082e+06
Pawlenty, Timothy                 6.004819e+06
Huntsman, Jon                     3.330373e+06
Bachmann, Michelle                2.711439e+06
Johnson, Gary Earl                5.669616e+05
Roemer, Charles E. 'Buddy' III    3.730099e+05
McCotter, Thaddeus G              3.903000e+04
Name: contb_receipt_amt, dtype: float64

将两个人的数据组合成一个新的数据集

data_vs = data[data['cand_nm'].isin(['Obama, Barack','Romney, Mitt'])].copy()
#将最主要的两个竞争人的数据集进行复制

4.面元化数据

对两个数据中不同的捐助金额,分别打上标签

bins = np.array([0,1,10,100,1000,10000,100000,1000000,10000000])
labels = pd.cut(data_vs['contb_receipt_amt'],bins)
labels#根据捐助的金额打上标签
411         (10, 100]
412       (100, 1000]
413       (100, 1000]
414         (10, 100]
415         (10, 100]
             ...     
201381      (10, 100]
201382    (100, 1000]
201383        (1, 10]
201384      (10, 100]
201385    (100, 1000]
Name: contb_receipt_amt, Length: 694283, dtype: category
Categories (8, interval[int64]): [(0, 1] < (1, 10] < (10, 100] < (100, 1000] < (1000, 10000] < (10000, 100000] < (100000, 1000000] < (1000000, 10000000]]

三、数据聚合及分组

1.透视表(pivot_table)分析党派和职业

通过pivot_table根据党派和职业对数据进行聚合,然后过滤掉总出资不足200万美元的数据

by_occupation = data.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 = 'bar')

直方图

2.根据职业与雇主信息分组运算

根据职业分组,根据捐赠的金额排序输出最多的七个职业

def get_top_amounts(group,key,n=5):
#传入groupby分组后的对象,返回按照key字段汇总的排序前n的数据
    totals = group.groupby(key)['contb_receipt_amt'].sum()
    return totals.sort_values(ascending=False)[:n]
grouped = data_vs.groupby('cand_nm')
grouped.apply(get_top_amounts,'contbr_occupation',n=7)
cand_nm        contbr_occupation
Obama, Barack  RETIRED              25305316.38
               ATTORNEY             14302461.84
               NOT PROVIDED         13725187.32
               HOMEMAKER             4248875.80
               PHYSICIAN             3735124.94
               CONSULTANT            2459912.71
               PROFESSOR             2165071.08
Romney, Mitt   NOT PROVIDED         11638509.84
               RETIRED              11508473.59
               HOMEMAKER             8147446.22
               ATTORNEY              5372424.02
               PRESIDENT             2491244.89
               CEO                   2324297.03
               EXECUTIVE             2300947.03
Name: contb_receipt_amt, dtype: float64

同理可输出公司的捐赠排名

grouped.apply(get_top_amounts,'contbr_employer',n=10)
cand_nm        contbr_employer   
Obama, Barack  RETIRED               22694558.85
               SELF-EMPLOYED         18626807.16
               NOT PROVIDED          13883494.03
               NOT EMPLOYED           8586308.70
               HOMEMAKER              2605408.54
               STUDENT                 318831.45
               VOLUNTEER               257104.00
               MICROSOFT               215585.36
               SIDLEY AUSTIN LLP       168254.00
               REFUSED                 149516.07
Romney, Mitt   NOT PROVIDED          12321731.24
               RETIRED               11506225.71
               HOMEMAKER              8147196.22
               SELF-EMPLOYED          7414115.22
               STUDENT                 496490.94
               CREDIT SUISSE           281150.00
               MORGAN STANLEY          267266.00
               GOLDMAN SACH & CO.      238250.00
               BARCLAYS CAPITAL        162750.00
               H.I.G. CAPITAL          139500.00
Name: contb_receipt_amt, dtype: float64

综上可以得出支持Obama和Romney的群体。

根据赞助人在不同捐助金额的多少进行分类比较

grouped_bins = data_vs.groupby(['cand_nm',labels])
grouped_bins.size().unstack(0)

捐赠人

每个阶层的捐赠总和

bucket_sums=grouped_bins['contb_receipt_amt'].sum().unstack(0)
bucket_sums

金额

根据金额来画直方图

bucket_sums.plot(kind='bar')

金额直方图

用百分比来显示结果,更加明显

normed_sums = bucket_sums.div(bucket_sums.sum(axis = 1),axis=0)
normed_sums

百分比

normed_sums[:-2].plot(kind='bar',stacked=True)

百分比直方图

按照赞助人姓名分组计数,计算重复赞助次数最多的前20人

data.groupby('contbr_nm')['contbr_nm'].count().sort_values(ascending=False)[:20]
contbr_nm
WILLIAMS, DEBBY          205
BERKE, DAVID MICHAEL     171
SEBAG, DAVID             161
SMITH, ERIK              145
FALLSGRAFF, TOBY         138
SKINNER, DONNA           136
CASPERSON, CAROLINA      132
HARRIS, CLAUDIA W.       132
ROSBERG, MARILYN         115
POTTS, LILLIE            114
DUDLEY, DEBBIE           111
HAUGHEY, NOEL ANTHONY    107
DFHDFH, DFHDFH            96
SHERWIN, GLEN R.          94
MITCHELL, CAITLIN         90
SMITH, CHARLES            88
KARIMIAN, AFSANEH         87
NURU, ISAAC               87
MASTERS, MARGERY          85
BIRMINGHAM, TOM           85
Name: contbr_nm, dtype: int64

四、时间处理

1.str转datetime

使用to_datetime方法解析多种不同的日期表示形式。对标准日期格式(如ISO8601)的解析非常快。我们也可以指定特定的日期解析格式,如pd.to_datetime(series,format='%Y%m%d')

data_vs['time'] = pd.to_datetime(data_vs['contb_receipt_dt'])

2.以时间作为索引

data_vs.set_index('time',inplace = True)
data_vs.head()

时间

3.重采样和频度转换

vs_time = data_vs.groupby('cand_nm').resample('M')['cand_nm'].count()
vs_time.unstack(0)

时间列表

fig, ax1=plt.subplots(figsize=(32,8))
vs_time.unstack(0).plot(kind='area',ax=ax1,alpha=0.6)
plt.show()

时间区域

用面积图把11年4月-12年4月两位总统候选人接受的赞助笔数做个对比可以看出,越临近竞选,大家赞助的热情越高涨,奥巴马在各个时段都占据绝对的优势

Last modification:August 23, 2020
如果觉得我的文章对你有用,请随意赞赏