本學習筆記為阿里云天池龍珠計劃Python訓練營的學習內容,學習鏈接為:https://tianchi.aliyun.com/specials/promotion/aicamppython?spm=5176.22758685.J_6770933040.1.6f103da1tESyzu
一、學習知識點概要
本次主要通過阿里云天池的賽題【Python入門系列】用Pandas揭秘美國選民的總統喜好 進行學習,主要學習內容有:
- 數據集獲取
- 數據處理
- 數據探索和清洗
- 數據分析
- 數據可視化
二、學習內容
1.數據集獲取
首先,我們需要獲取以下信息:
所有候選人信息
該文件為每個候選人提供一份記錄,并顯示候選人的信息、總收入、從授權委員會收到的轉賬、付款總額、給授權委員會的轉賬、庫存現金總額、貸款和債務以及其他財務匯總信息。
數據字段描述詳細:https://www.fec.gov/campaign-finance-data/all-candidates-file-description/
關鍵字段說明
- CAND_ID 候選人ID
- CAND_NAME 候選人姓名
- CAND_PTY_AFFILIATION 候選人黨派
數據來源:https://www.fec.gov/files/bulk-downloads/2020/weball20.zip
?
候選人委員會鏈接信息
該文件顯示候選人的身份證號碼、候選人的選舉年份、聯邦選舉委員會選舉年份、委員會識別號、委員會類型、委員會名稱和鏈接標識號。
信息描述詳細:https://www.fec.gov/campaign-finance-data/candidate-committee-linkage-file-description/
關鍵字段說明
- CAND_ID 候選人ID
- CAND_ELECTION_YR 候選人選舉年份
- CMTE_ID 委員會ID
數據來源:https://www.fec.gov/files/bulk-downloads/2020/ccl20.zip
?
個人捐款檔案信息?【注意】由于文件較大,本數據集只包含2020.7.22-2020.8.20的相關數據,如果需要更全數據可以通過數據來源中的地址下載。
該文件包含有關收到捐款的委員會、披露捐款的報告、提供捐款的個人、捐款日期、金額和有關捐款的其他信息。
信息描述詳細:https://www.fec.gov/campaign-finance-data/contributions-individuals-file-description/
關鍵字段說明
- CMTE_ID 委員會ID
- NAME 捐款人姓名
- CITY 捐款人所在市
- State 捐款人所在州
- EMPLOYER 捐款人雇主/公司
- OCCUPATION 捐款人職業
數據來源:https://www.fec.gov/files/bulk-downloads/2020/indiv20.zip
接著我們需要安裝詞云處理包
# 安裝詞云處理包wordcloud
!pip install wordcloud --user
2.數據處理
進行數據處理前,我們需要知道我們最終想要的數據是什么樣的,因為我們是想分析候選人與捐贈人之間的關系,所以我們想要一張數據表中有捐贈人與候選人一一對應的關系,所以需要將目前的三張數據表進行一一關聯,匯總到需要的數據。
2.1 將委員會和候選人一一對應,通過CAND_ID
關聯兩個表
由于候選人和委員會的聯系表中無候選人姓名,只有候選人ID(CAND_ID
),所以需要通過CAND_ID
從候選人表中獲取到候選人姓名,最終得到候選人與委員會聯系表ccl
。
# 導入相關處理包
import pandas as pd
# 讀取候選人信息,由于原始數據沒有表頭,需要添加表頭
candidates = pd.read_csv("weball20.txt", sep = '|',names=['CAND_ID','CAND_NAME','CAND_ICI','PTY_CD','CAND_PTY_AFFILIATION','TTL_RECEIPTS','TRANS_FROM_AUTH','TTL_DISB','TRANS_TO_AUTH','COH_BOP','COH_COP','CAND_CONTRIB','CAND_LOANS','OTHER_LOANS','CAND_LOAN_REPAY','OTHER_LOAN_REPAY','DEBTS_OWED_BY','TTL_INDIV_CONTRIB','CAND_OFFICE_ST','CAND_OFFICE_DISTRICT','SPEC_ELECTION','PRIM_ELECTION','RUN_ELECTION','GEN_ELECTION','GEN_ELECTION_PRECENT','OTHER_POL_CMTE_CONTRIB','POL_PTY_CONTRIB','CVG_END_DT','INDIV_REFUNDS','CMTE_REFUNDS'])
# 讀取候選人和委員會的聯系信息
ccl = pd.read_csv("ccl.txt", sep = '|',names=['CAND_ID','CAND_ELECTION_YR','FEC_ELECTION_YR','CMTE_ID','CMTE_TP','CMTE_DSGN','LINKAGE_ID'])
# 關聯兩個表數據
ccl = pd.merge(ccl,candidates)
# 提取出所需要的列
ccl = pd.DataFrame(ccl, columns=[ 'CMTE_ID','CAND_ID', 'CAND_NAME','CAND_PTY_AFFILIATION'])
數據字段說明:
- CMTE_ID:委員會ID
- CAND_ID:候選人ID
- CAND_NAME:候選人姓名
- CAND_PTY_AFFILIATION:候選人黨派
2.2 將候選人和捐贈人一一對應,通過CMTE_ID
關聯兩個表
通過CMTE_ID
將目前處理好的候選人和委員會關系表與人捐款檔案表進行關聯,得到候選人與捐贈人一一對應聯系表cil
。
# 讀取個人捐贈數據,由于原始數據沒有表頭,需要添加表頭
# 提示:讀取本文件大概需要5-10s
itcont = pd.read_csv('itcont_2020_20200722_20200820.txt', sep='|',names=['CMTE_ID','AMNDT_IND','RPT_TP','TRANSACTION_PGI','IMAGE_NUM','TRANSACTION_TP','ENTITY_TP','NAME','CITY','STATE','ZIP_CODE','EMPLOYER','OCCUPATION','TRANSACTION_DT','TRANSACTION_AMT','OTHER_ID','TRAN_ID','FILE_NUM','MEMO_CD','MEMO_TEXT','SUB_ID'])
# 將候選人與委員會關系表ccl和個人捐贈數據表itcont合并,通過 CMTE_ID
c_itcont = pd.merge(ccl,itcont)
# 提取需要的數據列
c_itcont = pd.DataFrame(c_itcont, columns=[ 'CAND_NAME','NAME', 'STATE','EMPLOYER','OCCUPATION','TRANSACTION_AMT', 'TRANSACTION_DT','CAND_PTY_AFFILIATION'])
數據說明
- CAND_NAME – 接受捐贈的候選人姓名
- NAME – 捐贈人姓名
- STATE – 捐贈人所在州
- EMPLOYER – 捐贈人所在公司
- OCCUPATION – 捐贈人職業
- TRANSACTION_AMT – 捐贈數額(美元)
- TRANSACTION_DT – 收到捐款的日期
- CAND_PTY_AFFILIATION – 候選人黨派
3.數據探索和清洗
進過數據處理部分,我們獲得了可用的數據集,現在我們可以利用調用shape
屬性查看數據的規模,調用info
函數查看數據信息,調用describe
函數查看數據分布。
# 查看數據規模 多少行 多少列
c_itcont.shape
#(756205, 8)
# 查看整體數據信息,包括每個字段的名稱、非空數量、字段的數據類型
c_itcont.info()
'''
<class 'pandas.core.frame.DataFrame'>
Int64Index: 756205 entries, 0 to 756204
Data columns (total 8 columns):# Column Non-Null Count Dtype
--- ------ -------------- ----- 0 CAND_NAME 756205 non-null object1 NAME 756205 non-null object2 STATE 756160 non-null object3 EMPLOYER 737413 non-null object4 OCCUPATION 741294 non-null object5 TRANSACTION_AMT 756205 non-null int64 6 TRANSACTION_DT 756205 non-null int64 7 CAND_PTY_AFFILIATION 756205 non-null object
dtypes: int64(2), object(6)
memory usage: 51.9+ MB
'''
通過上面的探索我們知道目前數據集的一些基本情況,目前數據總共有756205行,8列,總占用內存51.9+MB,STATE
、EMPLOYER
、OCCUPATION
有缺失值,另外日期列目前為int64類型,需要進行轉換為str類型。
#空值處理,統一填充 NOT PROVIDEDc_itcont['STATE'].fillna('NOT PROVIDED',inplace=True)c_itcont['EMPLOYER'].fillna('NOT PROVIDED',inplace=True)c_itcont['OCCUPATION'].fillna('NOT PROVIDED',inplace=True)
# 對日期TRANSACTION_DT列進行處理
c_itcont['TRANSACTION_DT'] = c_itcont['TRANSACTION_DT'] .astype(str)
# 將日期格式改為年月日 7242020
c_itcont['TRANSACTION_DT'] = [i[3:7]+i[0]+i[1:3] for i in c_itcont['TRANSACTION_DT'] ]
# 再次查看數據信息
'''
c_itcont.info()<class 'pandas.core.frame.DataFrame'>
Int64Index: 756205 entries, 0 to 756204
Data columns (total 8 columns):# Column Non-Null Count Dtype
--- ------ -------------- ----- 0 CAND_NAME 756205 non-null object1 NAME 756205 non-null object2 STATE 756205 non-null object3 EMPLOYER 756205 non-null object4 OCCUPATION 756205 non-null object5 TRANSACTION_AMT 756205 non-null int64 6 TRANSACTION_DT 756205 non-null object7 CAND_PTY_AFFILIATION 756205 non-null object
dtypes: int64(1), object(7)
memory usage: 51.9+ MB
'''
# 查看數據表中數據類型的列的數據分布情況
c_itcont.describe()
'''TRANSACTION_AMT
count 7.562050e+05
mean 1.504307e+02
std 2.320452e+03
min -5.600000e+03
25% 2.000000e+01
50% 3.500000e+01
75% 1.000000e+02
max 1.500000e+06
'''
# 查看單列的數據發布情況
c_itcont['CAND_NAME'].describe()
'''
count 756205
unique 312
top BIDEN, JOSEPH R JR
freq 507816
Name: CAND_NAME, dtype: object
'''
4.數據分析
# 計算每個黨派的所獲得的捐款總額,然后排序,取前十位
c_itcont.groupby("CAND_PTY_AFFILIATION").sum().sort_values("TRANSACTION_AMT",ascending=False).head(10)
'''TRANSACTION_AMT
CAND_PTY_AFFILIATION DEM 75961730REP 37170653IND 328802LIB 169202DFL 76825GRE 18607NON 11256UNK 10195CON 4117BDY 3250
'''# 計算每個總統候選人所獲得的捐款總額,然后排序,取前十位
c_itcont.groupby("CAND_NAME").sum().sort_values("TRANSACTION_AMT",ascending=False).head(10)
'''TRANSACTION_AMTCAND_NAME BIDEN, JOSEPH R JR 68111142TRUMP, DONALD J. 16594982SULLIVAN, DAN 9912465JACOBS, CHRISTOPHER L. 6939209BLOOMBERG, MICHAEL R. 3451916MARKEY, EDWARD J. SEN. 606832SHAHEEN, JEANNE 505446KENNEDY, JOSEPH P III 467738CORNYN, JOHN SEN 345959
FIGLESTHALER, WILLIAM MATTHEW MD 258221
'''
獲得捐贈最多的黨派有DEM(民主黨)
、REP(共和黨)
,分別對應BIDEN, JOSEPH R JR(拜登)
和TRUMP, DONALD J.(特朗普)
,從我們目前分析的2020.7.22-2020.8.20這一個月的數據來看,在選民的捐贈數據中拜登代表的民主黨完勝特朗普代表的共和黨,由于完整數據量過大,所以沒有對所有數據進行匯總分析,因此也不能確定11月大選公布結果就一定是拜登當選。
# 查看不同職業的人捐款的總額,然后排序,取前十位
c_itcont.groupby('OCCUPATION').sum().sort_values("TRANSACTION_AMT",ascending=False).head(10)
'''TRANSACTION_AMTOCCUPATION
NOT EMPLOYED 24436214RETIRED 18669950
NOT PROVIDED 5089355ATTORNEY 4443569FOUNDER 3519109PHYSICIAN 3295595CONSULTANT 1647033LAWYER 1565976PROFESSOR 1481260EXECUTIVE 1467865
'''
# 查看每個職業捐款人的數量
c_itcont['OCCUPATION'].value_counts().head(10)
'''
NOT EMPLOYED 224109
RETIRED 151834
ATTORNEY 19666
NOT PROVIDED 14912
PHYSICIAN 14033
CONSULTANT 8333
PROFESSOR 8022
TEACHER 8013
ENGINEER 7922
SALES 6435
Name: OCCUPATION, dtype: int64
'''
從捐款人的職業這個角度分析,我們會發現NOT EMPLOYED(自由職業)
的總捐贈額是最多,通過查看每個職業捐贈的人數來看,我們就會發現是因為NOT EMPLOYED(自由職業)
人數多的原因,另外退休人員捐款人數也特別多,所以捐款總數對應的也多,其他比如像:律師、創始人、醫生、顧問、教授、主管這些高薪人才雖然捐款總人數少,但是捐款總金額也占據了很大比例。
# 每個州獲捐款的總額,然后排序,取前五位
c_itcont.groupby('STATE').sum().sort_values("TRANSACTION_AMT",ascending=False).head(5)
'''TRANSACTION_AMT
STATE CA 19999115NY 11468537FL 8128789TX 8101871MA 5187957
'''
# 查看每個州捐款人的數量
c_itcont['STATE'].value_counts().head(5)
'''
CA 127895
TX 54457
FL 54343
NY 49453
MA 29314
Name: STATE, dtype: int64
'''
最后查看每個州的捐款總金額,我們會發現CA(加利福利亞)
、NY(紐約)
、FL(弗羅里達)
這幾個州的捐款是最多的,在捐款人數上也是在Top端,另一方面也凸顯出這些州的經濟水平發達。 大家也可以通過數據查看下上面列舉的高端職業在各州的分布情況,進行進一步的分析探索。
5.數據可視化
首先導入相關Python庫
# 導入matplotlib中的pyplot
import matplotlib.pyplot as plt
# 為了使matplotlib圖形能夠內聯顯示
%matplotlib inline
# 導入詞云庫
from wordcloud import WordCloud,ImageColorGenerator
5.1 按州總捐款數和總捐款人數柱狀圖
# 各州總捐款數可視化
st_amt = c_itcont.groupby('STATE').sum().sort_values("TRANSACTION_AMT",ascending=False)[:10]
st_amt=pd.DataFrame(st_amt, columns=['TRANSACTION_AMT'])
st_amt.plot(kind='bar')
<AxesSubplot:xlabel='STATE'>
5.2 各州捐款總人數可視化
# 各州捐款總人數可視化,取前10個州的數據
st_amt = c_itcont.groupby('STATE').size().sort_values(ascending=False).head(10)
st_amt.plot(kind='bar')
<AxesSubplot:xlabel='STATE'>
5.3 熱門候選人拜登在各州的獲得的捐贈占比
# 從所有數據中取出支持拜登的數據
biden = c_itcont[c_itcont['CAND_NAME']=='BIDEN, JOSEPH R JR']
# 統計各州對拜登的捐款總數
biden_state = biden.groupby('STATE').sum().sort_values("TRANSACTION_AMT", ascending=False).head(10)
# 餅圖可視化各州捐款數據占比
biden_state.plot.pie(figsize=(10, 10),autopct='%0.2f%%',subplots=True)
array([<AxesSubplot:ylabel='TRANSACTION_AMT'>], dtype=object)
5.3 總捐最多的候選人捐贈者詞云圖
通過數據分析中獲得捐贈總額前三的候選人統計中可以看出拜登在2020.7.22-2020.8.20這期間獲得捐贈的總額是最多的,所以我們以拜登為原模型,制作詞云圖。
首先下載圖片模型,這里提供的是已經處理好的圖片,有興趣的選手可以自己寫代碼進行圖片處理
# 處理結果:需要將人圖像和背景顏色分離,并純色填充,詞云才會只顯示在人圖像區域
# 拜登原圖:https://img.alicdn.com/tfs/TB1pUcwmZVl614jSZKPXXaGjpXa-689-390.jpg
# 拜登處理后圖片:https://img.alicdn.com/tfs/TB10Jx4pBBh1e4jSZFhXXcC9VXa-689-390.jpg
!wget https://img.alicdn.com/tfs/TB10Jx4pBBh1e4jSZFhXXcC9VXa-689-390.jpg
# 由于下載圖片文件名過長,我們對文件名進行重命名
import os
os.rename('TB10Jx4pBBh1e4jSZFhXXcC9VXa-689-390.jpg', 'biden.jpg')
# 將所有捐贈者姓名連接成一個字符串
data = ' '.join(biden["NAME"].tolist())
# 讀取圖片文件
bg = plt.imread("biden.jpg")
# 生成
wc = WordCloud(# FFFAE3background_color="white", # 設置背景為白色,默認為黑色width=890, # 設置圖片的寬度height=600, # 設置圖片的高度mask=bg, # 畫布margin=10, # 設置圖片的邊緣max_font_size=100, # 顯示的最大的字體大小random_state=20, # 為每個單詞返回一個PIL顏色
).generate_from_text(data)
# 圖片背景
bg_color = ImageColorGenerator(bg)
# 開始畫圖
plt.imshow(wc.recolor(color_func=bg_color))
# 為云圖去掉坐標軸
plt.axis("off")
# 畫云圖,顯示
# 保存云圖
wc.to_file("biden_wordcloud.png")
<wordcloud.wordcloud.WordCloud at 0x7f64fca05400>
三、學習問題與解答
學習問題出現還是蠻多的,主要是出現的方法的機理,參數的作用不清楚。
四、學習思考與總結
本次學習的內容如果要完全理解對我這種幾天前才開始學Python的人來說還是挺難的,里面有涉及到安裝包、引入庫的操作。引入的那些如Pandas、wordcloud包里面的方法不熟悉,學習起來比較吃力。這些例程做下記錄,以后會好好學習弄懂。