數聚點

數聚點

Share this post

數聚點
數聚點
約維安計畫:中選會選舉資料操作處理
高級約維安

約維安計畫:中選會選舉資料操作處理

第三十八週

Yao-Jen Kuo's avatar
Yao-Jen Kuo
Feb 03, 2024
∙ Paid
1

Share this post

數聚點
數聚點
約維安計畫:中選會選舉資料操作處理
Share
來源:giphy.com

中選會選舉資料

經歷第三十六週的約維安計畫:基礎的資料處理技法以及第三十七週的約維安計畫:進階的資料處理技法之後,在這週我們將綜合使用這些基礎與進階的資料處理技法,來面對真實世界的資料:2024-01-13 的台灣總統、立法委員投票所明細資料,從中選會的官網可以下載第 16 任總統副總統選舉以第 11 屆立法委員選舉的「各投票所得票明細及概況」。

  • 第 16 任總統副總統選舉

  • 第 11 屆立法委員選舉

我們所下載的原始資料是「下載各項統計表」中的「各投票所得票明細及概況(Excel 檔,ZIP 壓縮)」,解壓縮之後可以看到裡面的 Excel 活頁簿檔案大致是這樣的外觀。

來源:總統-A05-4-候選人得票數一覽表-各投開票所(南投縣).xlsx
來源:區域立委-A05-2-得票數一覽表(南投縣).xlsx

待處理的部分

從 Excel 活頁簿檔案中我們可以看到原始資料中存在下列問題:

  • 合併儲存格與空白儲存格,會導致載入後有遺漏值。

  • 總計、小計與明細共存,會導致在應用時有重複計算之虞。

  • 候選人號次、候選人姓名與政黨資料儲存在欄位名稱之中,不方便使用。

在載入活頁簿檔案中的每一張試算表時,我們可以透過相同的處理步驟來使得資料成為整齊的格式:

  1. 將位於倒數八欄的投票所資料獨立出來整理。

  2. 載入時以 skiprows 參數略過特定的列數解決合併儲存格的問題。

  3. 利用 Series 的 fillna() 方法填補遺漏值。

  4. 利用 DataFrame 的 dropna() 方法刪除總計與小計的列數。

  5. 利用 pd.melt() 函數將候選人號次、候選人姓名與政黨資料轉置到資料列中。

由於這些處理步驟會應用到每一個載入的試算表,所以我們應該要寫作方便重複使用的函數組織程式碼。

函數的規劃與執行流程

整齊格式的資料會針對不同的選舉類型而有所差異,因此會有三個函數:

  1. 總統副總統選舉:tidy_president_dataframes() 函數。

  2. 區域立法委員選舉:tidy_legislator_dataframes() 函數。

  3. 不分區立法委員選舉:tidy_party_legislator_dataframes() 函數。

中選會將每個選舉類型的資料都提供至投票所層級,投票所的資料加總後為村鄰里,村鄰里的資料加總後為鄉鎮行政區,鄉鎮行政區的資料加總後為縣市,因此在資料的彙整部分就是將台灣 22 個縣市垂直合併,對應選舉類型同樣有三個函數:

  1. 總統副總統選舉:concat_president_dataframes() 函數。

  2. 立法委員選舉:concat_legislator_dataframes() 函數。

  3. 投票所資訊:concat_office_dataframes() 函數。

在執行流程的規劃上,會由垂直合併的函數(有 concat_ 前綴字)去執行原始資料的載入,並呼叫處理資料的函數(有 tidy_ 前綴字)將資料清理成為整齊格式。

def tidy_president_dataframes():
    ...
    return candidate_df, office_df

def tidy_legislator_dataframes():
    ...
    return candidate_df, office_df

def tidy_party_legislator_dataframes():
    ...
    return candidate_df, office_df

def concat_president_dataframes():
    ...
    return concatenated_president_df, concatenated_office_df

def concat_legislator_dataframes():
    ...
    return concatenated_legislator_df, concatenated_party_legislator_df, concatenated_office_df

def concat_office_dataframes():
    ...
    return concatenated_office_df

president_df, president_office_df = concat_president_dataframes()
legislator_df, party_legislator_df, legislator_office_df = concat_legislator_dataframes()
office_df = concat_office_dataframes(president_office_df, legislator_office_df)

函數執行後的成果

垂直合併的函數(有 concat_ 前綴字)執行完畢後,我們可以檢視四個整齊格式的資料框,分別是總統副總統:

立法委員(含區域、山地與平地):

不分區立法委員(即政黨票):

投票所資訊(含總統副總統、立法委員與不分區立法委員):

類別的規劃

確認函數的規劃、執行流程以及成果無誤之後,我們可以更進一步將程式碼組織成為類別 TidyTaiwanElection2024Data,把前述函數整理為物件方法。

class TidyTaiwanElection2024Data:
    def __init__(self):
        ...
    def tidy_president_dataframes(self):
        ...
    def tidy_legislator_dataframes(self):
        ...
    def tidy_party_legislator_dataframes(self):
        ...
    def concat_president_dataframes(self):
        ...
    def concat_legislator_dataframes(self):
        ...
    def get_tidy_dataframes(self):
        ...
    def get_tidy_csv_files(self):
        ...

作為類別之後,就可以再用一個獨立的模組封裝,未來打算重新運行的時候,就可以將類別由模組載入到工作環境,直接呼叫物件方法即可得到整齊格式的資料框與 CSV 檔案。

from tidy_taiwan_election_2024_data import TidyTaiwanElection2024Data

tidy_twn_election_2024_data = TidyTaiwanElection2024Data()
tidy_dataframes = tidy_twn_election_2024_data.get_tidy_dataframes()
tidy_twn_election_2024_data.get_tidy_csv_files()
tidy_dataframes["president"]
tidy_dataframes["legislator"]
tidy_dataframes["party_legislator"]
tidy_dataframes["polling_place"]

完成中選會選舉資料操作處理之後,我們就能夠在下次的電子報中介紹如何整合正規化到整集格式資料之上。第三十八週約維安計畫:中選會選舉資料操作處理來到尾聲,希望您也和我一樣期待下一篇文章。對於這篇文章有什麼想法呢?喜歡😻、留言🙋‍♂️、訂閱📨或者分享🙌

Leave a comment

Share

約維安計畫學員專區

約維安計畫學員可以點選下列連結取得本篇文章完整的程式碼與整齊格式資料。

This post is for paid subscribers

Already a paid subscriber? Sign in
© 2025 DATAINPOINT, INC.
Privacy ∙ Terms ∙ Collection notice
Start writingGet the app
Substack is the home for great culture

Share