不間斷 Python 挑戰 Day 29 - 使用Pandas處理CSV文件

閱讀時間約 22 分鐘
上一篇的文章中,我們提到關於開啟CSV文件的方式,從單純的當作純文字文件開啟,到引入Python內建的csv模組對CSV類型的檔案做基本的讀寫操作。在這篇文章中,我們將進一步使用Pandas這套強大的工具,來簡化CSV文件處理的流程。Pandas是Python用於數據處理與分析的軟體庫,它提供處理表格與時間序列的資料結構和運算操作,屬於Python的外部模組,在使用時必須事先安裝導入。
開始之前,我們先到之前提過位於交通部中央氣象局觀測資料查詢系統,下載新北市永和區2022年2月份的氣象資料,在左方欄位選取查詢資料的相關資訊後,按下「查詢」按鈕後,就會開啟選取資料的報表與下載連結,點選「CSV下載」可將檔案下載下來,並移動到PyCharm專案所在的資料夾。
觀測資料查詢系統
氣象資料月報表
關於Pandas函式庫的詳細用法,可以參考官方網站的說明,這篇文章主要針對在PyCharm中使用Pandas處理CSV文件的方法,做進一步的說明。
https://pandas.pydata.org/

安裝Pandas模組

初次使用Pandas模組時,在PyCharm打入「import pandas」會跳出警示的燈泡符號,表示此模組尚未安裝在專案中,我們可以依照在模組這篇文章的說明,到PyCharm的Settings功能頁中新增模組;簡單一點的方式,在這裡點選燈泡即可跳出「Install package pandas」的選項,點擊該選項後就會自動安裝。
未安裝模組警示
安裝Pandas選項
安裝的過程在PyCharm下方的狀態列會顯示「Installing package 'pandas'...」的提示與進度條,安裝完成後也會在Event Log跳出安裝成功的訊息。
安裝進行中
安裝完成
此時我們到PyCharm的Settings功能頁中即可看到pandas以及其相關的模組已經被安裝到專案中。
檢視專案安裝模組

開啟CSV檔案

Pandas使用read_csv()函式讀取CSV檔案,根據Pandas網站的使用說明,擷取部分參數如下:
pandas.read_csv(filepath_or_buffer, sep=NoDefault.no_default, header='infer', usecols=None, nrows=None)
  • filepath_or_buffer:檔案路徑。
  • sep:分隔字元,預設為","。
  • header:設定哪一列為欄位標籤,預設為0。
  • usecols:設定讀取的欄位。
  • nrows:設定讀取前幾列。
先以不帶參數的方式開啟前面下載的檔案,把讀取的內容印出來。
import pandas
weather_data = pandas.read_csv("C0AH10-2022-02.csv")
print(weather_data)
在輸出視窗中,可以得到全部月報表的資料,因為資料過長的關係,大部分被以"..."取代。
   觀測時間(day) 測站氣壓(hPa) 海平面氣壓(hPa)  ... 日最高紫外線指數 日最高紫外線指數時間(LST)     總雲量(0~10)
0    ObsTime   StnPres    SeaPres  ...  UVI Max    UVI Max Time  Cloud Amount
1         01    1016.1        ...  ...      ...             ...           ...
2         02    1016.6        ...  ...      ...             ...           ...
3         03    1014.9        ...  ...      ...             ...           ...
4         04    1018.9        ...  ...      ...             ...           ...
5         05    1021.9        ...  ...      ...             ...           ...
6         06    1020.9        ...  ...      ...             ...           ...
7         07    1014.2        ...  ...      ...             ...           ...
8         08    1017.7        ...  ...      ...             ...           ...
9         09    1016.0        ...  ...      ...             ...           ...
10        10    1015.7        ...  ...      ...             ...           ...
11        11    1013.4        ...  ...      ...             ...           ...
12        12    1013.1        ...  ...      ...             ...           ...
13        13    1011.3        ...  ...      ...             ...           ...
14        14    1015.4        ...  ...      ...             ...           ...
15        15    1014.9        ...  ...      ...             ...           ...
16        16    1014.2        ...  ...      ...             ...           ...
17        17    1013.2        ...  ...      ...             ...           ...
18        18    1013.3        ...  ...      ...             ...           ...
19        19    1015.0        ...  ...      ...             ...           ...
20        20    1021.8        ...  ...      ...             ...           ...
21        21    1020.6        ...  ...      ...             ...           ...
22        22    1019.8        ...  ...      ...             ...           ...
23        23    1021.9        ...  ...      ...             ...           ...
24        24    1023.8        ...  ...      ...             ...           ...
25        25    1020.4        ...  ...      ...             ...           ...
26        26    1017.9        ...  ...      ...             ...           ...
27        27    1017.4        ...  ...      ...             ...           ...
28        28    1014.7        ...  ...      ...             ...           ...
[29 rows x 35 columns]
可以和以Excel開啟的氣象資料月報表互相參照。
以Excel開啟氣象資料月報表
為了更清楚觀察資料,可以將前面提到的參數帶入。假設我們想觀察前十天的溫度,可以指定想要輸出的欄位與列數,header=1表示以第二列做為欄位的標籤。
import pandas
weather_data = pandas.read_csv("C0AH10-2022-02.csv", header=1, usecols=["ObsTime", "Temperature"], nrows=10)
print(weather_data)
執行後,就可以看到簡潔的資料呈現。
   ObsTime  Temperature
0        1         16.8
1        2         17.0
2        3         15.8
3        4         14.3
4        5         13.6
5        6         14.4
6        7         17.6
7        8         15.6
8        9         16.5
9       10         17.2
甚至也可以像字典利用鍵值對的鍵找到對應的值一樣,利用欄位標籤來尋找對應的欄位,例如:
print(weather_data["Temperature"])
結果會印出"Temperature"欄位的資料:
0    16.8
1    17.0
2    15.8
3    14.3
4    13.6
5    14.4
6    17.6
7    15.6
8    16.5
9    17.2
我們可以與上一篇處理CSV的方法比較一下,如果以csv模組開啟CSV檔案,想如同上方一樣輸出每日氣溫的資料,就必須額外花費一些心力來處理讀取的資料。
import csv
with open("C0AH10-2022-02.csv", encoding="utf-8") as weather_file:
  weather_data = csv.reader(weather_file)
  for row in weather_data:
    if row[7] != "氣溫(℃)":
      print(row[0], row[7])

Pandas資料結構

使用type()函式看一下weather_data的資料類型,它告訴我們weather_data整體是一個DataFrame型態的資料,其中的每一個欄位是Series型態的資料。
print(type(weather_data))
print(type(weather_data["Temperature"]))
執行結果:
<class 'pandas.core.frame.DataFrame'>
<class 'pandas.core.series.Series'>
DataFrame和Series共同構成了Pandas的基本資料結構,可以存放整數、浮點數、字串、串列、字典...等資料型態。其中,除了存放的資料以外,DataFrame包含了索引與欄位標籤,Series僅包含了索引。
DataFrame資料結構
Series資料結構
我們也可以看一下欄位標籤與索引的內容,例如在weather_data這個DataFrame中,欄位標籤與索引的內容如下:
print(weather_data.columns)
print(weather_data.index)
可看到欄位標籤即是在開啟CSV檔案時所指定的"ObsTime"與"Temperature",而索引因為沒有特別指定,預設由0開始編碼。
Index(['ObsTime', 'Temperature'], dtype='object')
RangeIndex(start=0, stop=10, step=1)
在weather_data["Temperature"]這個Series中,索引值和weather_data相同。
print(weather_data["Temperature"].index)
執行結果:
RangeIndex(start=0, stop=10, step=1)

建立Series物件

Pandas使用Series()方法來建立物件,其語法如下:
pandas.Series(data=None, index=None, dtype=None, name=None, copy=False, fastpath=False)
以下範例重建weather_data["ObsTime"]與weather_data["Temperature"]兩個Series,首先建立索引串列index,在Series()方法中的data帶入ObsTime與Temperature的資料、在index中帶入索引串列。
index = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
ObsTime_series = pandas.Series([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], index)
Temperature_series = pandas.Series([16.8, 17.0, 15.8, 14.3, 13.6, 14.4, 17.6, 15.6, 16.5, 17.2], index)
print(ObsTime_series)
print(Temperature_series)
執行結果:
0     1
1     2
2     3
3     4
4     5
5     6
6     7
7     8
8     9
9    10
dtype: int64
0    16.8
1    17.0
2    15.8
3    14.3
4    13.6
5    14.4
6    17.6
7    15.6
8    16.5
9    17.2
dtype: float64

建立DataFrame物件

Pandas使用DataFrame()方法來建立物件,其語法如下:
pandas.DataFrame(data=None, index=None, columns=None, dtype=None, copy=None)
接下來的範例,我們想重建weather_data,因此首先先建立一個字典,以"ObsTime"及其資料內容做為一鍵值對、以"Temperature"及其資料內容做為另一鍵值對,並使用相同的索引串列,帶入DataFrame()方法中。
index = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
weather_dict = {"ObsTime": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
         "Temperature": [16.8, 17.0, 15.8, 14.3, 13.6, 14.4, 17.6, 15.6, 16.5, 17.2]}
weather_dataframe = pandas.DataFrame(weather_dict, index)
print(weather_dataframe)
這樣就還原了從CSV檔案擷取下來的weather_data資料。
   ObsTime  Temperature
0        1         16.8
1        2         17.0
2        3         15.8
3        4         14.3
4        5         13.6
5        6         14.4
6        7         17.6
7        8         15.6
8        9         16.5
9       10         17.2
另一種方式,既然前面已經建立了weather_data["ObsTime"]與weather_data["Temperature"]兩個Series物件,我們可以藉由concat()方法將兩個Series組合在一起,語法如下:
pandas.concat(objs, axis=0, join='outer', ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, sort=False, copy=True)
需要注意的是,除了將Series物件帶入以外,這裡的axis參數必須設定為1,代表將兩個Series物件做為不同的欄位串接,而不是將第二個Series放在第一個Series之後,做為同一個欄位。
weather_dataframe_2 = pandas.concat([ObsTime_series, Temperature_series], axis=1)
print(weather_dataframe_2)
執行結果:
    0     1
0   1  16.8
1   2  17.0
2   3  15.8
3   4  14.3
4   5  13.6
5   6  14.4
6   7  17.6
7   8  15.6
8   9  16.5
9  10  17.2
和前面的weather_data比較一下,是否發現有什麼地方不一樣?關鍵在於這裡我們是將兩個Series組合成DataFrame,而Series本身是不包含欄位標籤的。針對這個問題有兩個解決方式,第一種方式從Series物件著手,Series雖然沒有欄位標籤,但它有name屬性,在做DataFrame的串接之前,可以先設定Series的name屬性,串接之後就會自動做為DataFrame的欄位標籤。
ObsTime_series.name = "ObsTime"
Temperature_series.name = "Temperature"
weather_dataframe_2 = pandas.concat([ObsTime_series, Temperature_series], axis=1)
print(weather_dataframe_2)
第二種方式是從DataFrame著手,在串接形成DataFrame之後,直接修改DataFrame的column屬性。
weather_dataframe_2 = pandas.concat([ObsTime_series, Temperature_series], axis=1)
weather_dataframe_2.columns = ["ObsTime", "Temperature"]
print(weather_dataframe_2)
這兩種方法都可以完整建立原本的weather_data資料。
   ObsTime  Temperature
0        1         16.8
1        2         17.0
2        3         15.8
3        4         14.3
4        5         13.6
5        6         14.4
6        7         17.6
7        8         15.6
8        9         16.5
9       10         17.2

總結

這篇文章中,我們說明了Pandas這套強大的外部模組處理CSV資料的方式,並利用網路上可以找到的天氣資料,展示如何使用PyCharm導入Pandas模組、讀取CSV檔案、以及Series和DataFrame的資料結構,並說明如何從頭自己創造出Series和DataFrame物件,最後還原我們從CSV檔案所讀取出來的資料。

程式範例

43會員
36Content count
留言0
查看全部
發表第一個留言支持創作者!
Wei-Jie Weng的沙龍 的其他內容
CSV全名為Comma-Separated Values,中文稱為逗號分隔值,也可稱為字元分隔值,因為分隔字元也可以不是逗號。它以純文字的形式儲存表格資料,同一列的資料以逗號或其它符號分隔成不同欄位,每一列的資料間以換行符號分隔。網路上很多資料的格式都是以CSV檔案呈現,例如交通部中央氣象局的觀測資
到目前為止,我們都還是在附檔名為.py的Python檔案執行程式碼,當程式需要與外部的檔案互動,例如讀取文字、表格、或是影像來做分析,或是把程式執行的結果儲存下來,就需要能夠存取外部的檔案。例如,在上一節中,當貪食蛇遊戲結束之後,隨著程式停止執行,該次的分數也就被丟棄,若能將分數記錄下來,下次遊戲開
接續前一篇文章,說明貪食蛇遊戲架構的後半部份,來完成整個遊戲的程式設計。
接下來我們會運用之前所學過的各種觀念,包括Turtle 模組、繼承等等,來製作這個大家都熟知的小遊戲-貪食蛇。完成品會長得像下圖這樣,包括可以設定難度(速度)、使用鍵盤的上、下、左、右鍵來移動貪食蛇的移動方向來吃到食物並加長蛇身、以及記分板等。
Turtle Graphic的前身是一種設計給小朋友學習的簡易繪圖程式,最初來自於Wally Feurzeig、Seymour Papert和Cynthia Solomon於1967年所創造的Logo編程語言,它是Python內建的繪圖函式庫,我們可以根據函式庫裡面的指令,操控一隻或多隻「小烏龜」在
「繼承」顧名思義就是有一個或多個類別延續了某個類別的特性,就如同在人類社會裡,兒女接收了父母的財產、承襲了上代的技能、延續了前一輩的事業。在Python的語言裡,能夠繼承的特性為類別的屬性與方法,繼承的類別稱為子類別(child class / subclass)或衍伸類別(derived clas
CSV全名為Comma-Separated Values,中文稱為逗號分隔值,也可稱為字元分隔值,因為分隔字元也可以不是逗號。它以純文字的形式儲存表格資料,同一列的資料以逗號或其它符號分隔成不同欄位,每一列的資料間以換行符號分隔。網路上很多資料的格式都是以CSV檔案呈現,例如交通部中央氣象局的觀測資
到目前為止,我們都還是在附檔名為.py的Python檔案執行程式碼,當程式需要與外部的檔案互動,例如讀取文字、表格、或是影像來做分析,或是把程式執行的結果儲存下來,就需要能夠存取外部的檔案。例如,在上一節中,當貪食蛇遊戲結束之後,隨著程式停止執行,該次的分數也就被丟棄,若能將分數記錄下來,下次遊戲開
接續前一篇文章,說明貪食蛇遊戲架構的後半部份,來完成整個遊戲的程式設計。
接下來我們會運用之前所學過的各種觀念,包括Turtle 模組、繼承等等,來製作這個大家都熟知的小遊戲-貪食蛇。完成品會長得像下圖這樣,包括可以設定難度(速度)、使用鍵盤的上、下、左、右鍵來移動貪食蛇的移動方向來吃到食物並加長蛇身、以及記分板等。
Turtle Graphic的前身是一種設計給小朋友學習的簡易繪圖程式,最初來自於Wally Feurzeig、Seymour Papert和Cynthia Solomon於1967年所創造的Logo編程語言,它是Python內建的繪圖函式庫,我們可以根據函式庫裡面的指令,操控一隻或多隻「小烏龜」在
「繼承」顧名思義就是有一個或多個類別延續了某個類別的特性,就如同在人類社會裡,兒女接收了父母的財產、承襲了上代的技能、延續了前一輩的事業。在Python的語言裡,能夠繼承的特性為類別的屬性與方法,繼承的類別稱為子類別(child class / subclass)或衍伸類別(derived clas
你可能也想看
Thumbnail
1.加權指數與櫃買指數 週五的加權指數在非農就業數據開出來後,雖稍微低於預期,但指數仍向上噴出,在美股開盤後於21500形成一個爆量假突破後急轉直下,就一路收至最低。 台股方面走勢需觀察週一在斷頭潮出現後,週二或週三開始有無買單進場支撐,在沒有明確的反轉訊號形成前,小夥伴盡量不要貿然抄底,或是追空
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
Thumbnail
十年前,我跟小悟參加了台南政府所舉辦的 24 小時不間斷進食比賽,當年,我以兩分之差,沒擠進金榜。在挑戰時間內,來不及吃狀元糕跟芋頭八寶冰,以致失掉食物王的頭銜。十年後,小悟說,要不要再來回味當年勇?我知道,年輕的我胃袋能撐船,可逝去的青春,最先反映在食慾上。我笑著說不了......
Thumbnail
持著前作的風格,《蜘蛛人:穿越新宇宙》在色彩或畫面的呈現上依舊大膽、前衛,並且嘗試藉由多重宇宙的「優勢」,在成長動畫的既有敘事上,嘗試更多不同的可能性。精彩的安排讓觀看這部作品讓成為十足的享受,並賦予了觀眾再次進場支持的充分動機。
Thumbnail
節目這邊聽 📎錄製時間: 2023.10 汪汪隊立大功! MRT(Mission Readiness Test)是難度最高的國際搜救犬認證! 但是我們有兩位英雄(一人一汪)順利通過這次的認證,拿到了優良的成績! 讓我們歡迎領犬員羅浩芳!就讓她帶著小編、江小姐還有各位聽眾,一起了解這次搜救犬
Thumbnail
這一陣子不少投資標的都在上漲 連成長性沒有科技股強的食品股也在慢慢上升中 今天記錄一下自己食品股大成的最新績效 身為雞肉雙雄的其中一雄 除了飼料、雞肉、雞蛋以外,還跨足了沙拉油、豬肉、海鮮、餐廳等事業體 幾乎可說是一檔食品ETF(還不用付管理費),進去它的官網就可以看到許多不同的事業體
Thumbnail
你現在也許單一個句子可以說得溜,但持續說話覺得尷尬的原因在於:缺乏連接詞。好的連接詞會讓口語表達更精確有力,讓韓國人聽到你說的話不需要猜測意思或重新思考,表達能力也就跟著上升!
Thumbnail
喜歡音樂的羅小咩,不定期將在周六中午12:00與你聊聊戲劇中的音樂,還有音樂中的戲劇。本次介紹:惡作劇之吻、慶餘年、Good Casting、溫柔時光、鋼之鍊金術師這五個戲劇作品的主題曲。
Thumbnail
喜歡音樂的羅小咩,不定期將在周六中午12:00與你聊聊戲劇中的音樂,還有音樂中的戲劇。本次介紹:必娶女人、kill me heal me、錦衣之下、101次求婚、灌籃高手這五個戲劇作品的主題曲。
近期許多地方受到洪水以及颱風的侵襲 但包你發的線路及網路穩定度完全不受到影響 大家可以放心,我們是24小時全年無休不間斷 就算你半夜三點要玩包你發也完全OK 不會像有些系統只在白天開放 而同樣的穩定度也是一大考驗 在這種供電不穩定的情況 也有可能導致其他遊戲斷線 但包你發機房穩定、有備用電源 完全不
Thumbnail
疫情長時間帶來了減少開放性的社交機會,最直接的影響莫過於情緒勒索造成的封閉性失調,感謝國立台灣戲曲學院傑出校友,為身心障礙的大寶寶們帶來一系列精彩的演出,透過精心策劃的舞蹈及雜耍表演,帶給住民體驗了跟以往不同的志工服務內容,見到了久違住民
Thumbnail
每一次TDCA的關愛陪伴,都讓受贈的服務對象感受到滿滿的幸福感,一起協力完成手作皮革鑰匙圈,每一針每一線都在訓練孩子們手眼協調的肢體,透過不同花色皮革來搭配,不僅訓練孩子對色彩的辨識能力,同時也在培養眼界裡的審美觀噢!
Thumbnail
1.加權指數與櫃買指數 週五的加權指數在非農就業數據開出來後,雖稍微低於預期,但指數仍向上噴出,在美股開盤後於21500形成一個爆量假突破後急轉直下,就一路收至最低。 台股方面走勢需觀察週一在斷頭潮出現後,週二或週三開始有無買單進場支撐,在沒有明確的反轉訊號形成前,小夥伴盡量不要貿然抄底,或是追空
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
Thumbnail
十年前,我跟小悟參加了台南政府所舉辦的 24 小時不間斷進食比賽,當年,我以兩分之差,沒擠進金榜。在挑戰時間內,來不及吃狀元糕跟芋頭八寶冰,以致失掉食物王的頭銜。十年後,小悟說,要不要再來回味當年勇?我知道,年輕的我胃袋能撐船,可逝去的青春,最先反映在食慾上。我笑著說不了......
Thumbnail
持著前作的風格,《蜘蛛人:穿越新宇宙》在色彩或畫面的呈現上依舊大膽、前衛,並且嘗試藉由多重宇宙的「優勢」,在成長動畫的既有敘事上,嘗試更多不同的可能性。精彩的安排讓觀看這部作品讓成為十足的享受,並賦予了觀眾再次進場支持的充分動機。
Thumbnail
節目這邊聽 📎錄製時間: 2023.10 汪汪隊立大功! MRT(Mission Readiness Test)是難度最高的國際搜救犬認證! 但是我們有兩位英雄(一人一汪)順利通過這次的認證,拿到了優良的成績! 讓我們歡迎領犬員羅浩芳!就讓她帶著小編、江小姐還有各位聽眾,一起了解這次搜救犬
Thumbnail
這一陣子不少投資標的都在上漲 連成長性沒有科技股強的食品股也在慢慢上升中 今天記錄一下自己食品股大成的最新績效 身為雞肉雙雄的其中一雄 除了飼料、雞肉、雞蛋以外,還跨足了沙拉油、豬肉、海鮮、餐廳等事業體 幾乎可說是一檔食品ETF(還不用付管理費),進去它的官網就可以看到許多不同的事業體
Thumbnail
你現在也許單一個句子可以說得溜,但持續說話覺得尷尬的原因在於:缺乏連接詞。好的連接詞會讓口語表達更精確有力,讓韓國人聽到你說的話不需要猜測意思或重新思考,表達能力也就跟著上升!
Thumbnail
喜歡音樂的羅小咩,不定期將在周六中午12:00與你聊聊戲劇中的音樂,還有音樂中的戲劇。本次介紹:惡作劇之吻、慶餘年、Good Casting、溫柔時光、鋼之鍊金術師這五個戲劇作品的主題曲。
Thumbnail
喜歡音樂的羅小咩,不定期將在周六中午12:00與你聊聊戲劇中的音樂,還有音樂中的戲劇。本次介紹:必娶女人、kill me heal me、錦衣之下、101次求婚、灌籃高手這五個戲劇作品的主題曲。
近期許多地方受到洪水以及颱風的侵襲 但包你發的線路及網路穩定度完全不受到影響 大家可以放心,我們是24小時全年無休不間斷 就算你半夜三點要玩包你發也完全OK 不會像有些系統只在白天開放 而同樣的穩定度也是一大考驗 在這種供電不穩定的情況 也有可能導致其他遊戲斷線 但包你發機房穩定、有備用電源 完全不
Thumbnail
疫情長時間帶來了減少開放性的社交機會,最直接的影響莫過於情緒勒索造成的封閉性失調,感謝國立台灣戲曲學院傑出校友,為身心障礙的大寶寶們帶來一系列精彩的演出,透過精心策劃的舞蹈及雜耍表演,帶給住民體驗了跟以往不同的志工服務內容,見到了久違住民
Thumbnail
每一次TDCA的關愛陪伴,都讓受贈的服務對象感受到滿滿的幸福感,一起協力完成手作皮革鑰匙圈,每一針每一線都在訓練孩子們手眼協調的肢體,透過不同花色皮革來搭配,不僅訓練孩子對色彩的辨識能力,同時也在培養眼界裡的審美觀噢!