Data Wrangling

掌控資料的能力被總稱為 Data Wrangling(或者 Data Munging),這樣的能力建構在對資料結構的理解與資料框的操作技巧;在面對未來的課題,不論是探索性資料分析(Exploratory Data Analysis,EDA)、統計分析、機器學習或者溝通呈現之前,有極大比例的時間花費在清理並重組資料,在如何掌控資料:認識常見的資料結構之中我們簡介了資料科學團隊常面對的資料結構,其中佔有主流地位的是表格式資料(Tabular Data),在 Python 與 R 語言中,都是以資料框(Data Frame)來處理表格式資料。 拜 Excel 試算表廣受歡迎之賜,資料框對我們並不如陣列或者清單那般陌生,這樣的二維資料結構,每列代表一個觀測值,每欄代表一個變數,就像是增強了列索引值與欄索引值的矩陣,並容許每一個欄位(變數)具有自己的型別。 摘要 本文簡介 Python pandas 與 R 語言中的基本資料框操作技巧,包含建立、檢視、篩選、選擇、排序、新增變數、新增觀測值、摘要與分組。 建立 建立資料框的方式有兩個,一為手動輸入資料,二為載入表格式資料(CSV、TXT 或者試算表)。我們可以分別在 Python 與 R 語言中利用 pandas.DataFrame() 和 data.frame() 函數手動輸入資料框的資料。 手動輸入一個 1995 至 1996 年球季芝加哥公牛隊先發陣容的資料框,這是一個 5 x 2 的資料框,紀錄五個先發球員的背號與姓名。

5 x 2 的資料框,紀錄五個先發球員的背號與姓名 值得注意的是,在 R 語言中資料框預設儲存文字的型別是一種稱為 factor 的型別,這個型別比單純的文字陣列有較多功能但同時也有較多眉角得注意,通常不推薦對於 R 語言不夠熟悉的使用者去處理 factor 型別,因此我們在 data.frame() 函數加入了一個參數 stringsAsFactors = FALSE 。

5 x 2 的資料框,紀錄五個先發球員的背號與姓名 第二個方式是載入一個表格式檔案例如:gapminder.csv 成為資料框,這是一個 1704 x 6的資料框,紀錄 142 個國家 1952 至 2007 年每五年的資訊快照(snapshot)。我們可以分別在 Python 與 R 語言中利用 pandas.read_csv() 和 read.csv() 函數載入資料,而 read.csv() 函數同樣也能加入參數 stringsAsFactors = FALSE 以避免讓使用者去處理 factor 型別。

1704 x 6的資料框,紀錄 142 個國家 1952 至 2007 年每五年的資訊快照

1704 x 6的資料框,紀錄 142 個國家 1952 至 2007 年每五年的資訊快照 檢視 在 Python pandas 中可以透過下列幾個資料框方法或屬性檢視: df.head() :查看前五列觀測值,可以加入參數 n 觀看前 n 列觀測值 df.tail() :查看末五列觀測值,可以加入參數 n 觀看末 n 列觀測值 df.info() :查看資料框的複合資訊,包含型別、外觀與變數型別等 df.describe() :查看數值變數的描述性統計,包含最小值、最大值、平均數與中位數等 df.shape :查看資料框的外觀,以 tuple 的型別回傳,(m, n) 表示 m 列觀測值,n 欄變數 df.columns :查看資料框的變數名稱 df.index :查看資料框的列索引值

df.head() 查看前五列觀測值 df.taile() 查看末五列觀測值 df.info() 查看資料框的複合資訊:

RangeIndex: 1704 entries, 0 to 1703

Data columns (total 6 columns):

country 1704 non-null object

continent 1704 non-null object

year 1704 non-null int64

lifeExp 1704 non-null float64

pop 1704 non-null int64

gdpPercap 1704 non-null float64

dtypes: float64(2), int64(2), object(2)

memory usage: 80.0+ KB

df.describe() 查看數值變數的描述性統計 df.shape 查看資料框的外觀:

(1704, 6)

df.columns 查看資料框的變數名稱:

Index(['country', 'continent', 'year', 'lifeExp', 'pop', 'gdpPercap'], dtype='object')

df.index 查看資料框的列索引值:

RangeIndex(start=0, stop=1704, step=1)

在 R 語言中可以透過下列幾個函數檢視資料框: head() :查看前六列觀測值,可以加入參數 n 觀看前 n 列觀測值 tail() :查看末六列觀測值,可以加入參數 n 觀看末 n 列觀測值 str() :structure 的簡寫,可以查看資料框的複合資訊,包含型別、外觀與變數型別等 summary() :查看描述性統計,包含最小值、最大值、平均數與中位數等 dim() :dimension 的簡寫,可以查看資料框的外觀,以 vector 的型別回傳,[1] m n 表示 m 列觀測值,n 欄變數 nrow() :查看資料框有幾個列 ncol() :查看資料框有幾個欄 colnames() :查看資料框所有的變數名稱 row.names() :查看資料框的列索引值,以文字型別回傳

head() 查看前六列觀測值 tail() 查看末六列觀測值 str() 查看資料框的複合資訊 summary() 查看描述性統計 dim() 查看資料框的外觀:

[1] 1704 6

nrow() 查看資料框有幾個列:

[1] 1704

ncol() 查看資料框有幾個欄:

[1] 6

colnames() 查看資料框所有的變數名稱:

[1] "country" "continent" "year" "lifeExp" "pop" "gdpPercap"

row.names() 查看資料框的列索引值:

[1] "1" "2" "3" "4" "5" "6"

篩選 常見有兩種作法,一是利用觀測值的所在位置(列索引值,欄索引值)進行篩選,二是利用判斷條件產生布林(邏輯)值的陣列再根據該陣列作為篩選依據,透過篩選也能夠實踐刪除觀測值這個操作技巧。 在 Python pandas 中可以使用 df.loc[m, n] 或 df.iloc[m, n] 兩個方法指定觀測值所在位置,兩者用法差在於 df.loc[] 完全憑藉列索引值與欄索引值的標籤;而 df.iloc[] 完全憑藉相對位置(因此方法中的 i 乃是整數 integer 的示意),舉例來說 1995 至 1996 年球季芝加哥公牛隊先發陣容的資料框,記錄五個先發球員的背號與姓名,並且以鋒衛(Guard/Forward)位置作為資料框列索引值。

以鋒衛(Guard/Forward)位置作為資料框列索引值 在索引值不是預設 RangeIndex(start=0, stop=5, step=1) 的時候比較容易區別 loc[] 與 iloc[] 之間的差異。我們希望選出 Michael Jordan、Scottie Pippen 與 Dennis Rodman:

選出 Michael Jordan、Scottie Pippen 與 Dennis Rodman 如果利用判斷條件選擇,那麼不論透過球衣背號或球員姓名都可以選出。

透過球衣背號或球員姓名 在 R 語言中亦能夠透過 df[m, n] 利用位置篩選觀測值以及利用判斷條件選擇這兩種方法。

透過位置 透過球衣背號 透過球員姓名 透過判斷條件也可以考慮使用 dplyr 套件的 filter() 函數。

使用 dplyr 套件的 filter() 函數 選擇 依照變數名稱或者所在位置選擇,透過選擇也能夠實踐刪除變數與調整變數在資料框中的位置這兩個操作技巧。 在 Python pandas 中可以透過 df.col 或 df["col"] 選出資料框的單一個變數,這時會轉換為 pandas.core.series.Series 的型別;透過 df[["col1", "col2"]] 則能夠選出資料框中的多個變數,這時型別依然是資料框。

依照變數名稱選擇 若要依照變數位置選擇,得仰賴 iloc[] ,全選可以使用 : 來表示。

依照變數位置選擇 在 R 語言中能夠透過 df$col 或 df[, "col"] 選擇單一個變數,這時會轉換為 vector,透過 df[, c("col1", "col2")] 則能夠選出資料框中的多個變數,這時型別依然是資料框。

依照變數名稱選擇 透過變數名稱選擇也可以考慮使用 dplyr 套件的 select() 函數。

使用 dplyr 套件的 select() 函數 亦可以依照變數位置選擇。

依照變數位置選擇 排序 依照某個或多個變數大小排序整個資料框的觀測值是常見的應用,可以遞增排序(由小到大)或者遞減排序(由大到小),假使面對文字型別的變數遞增排序,那麼就是按照字母順序 a-zA-Z(R 語言)或者 A-Za-z(Python)。 在 Python pandas 中我們可以使用 df.sort_index() 或 df.sort_values() 來排序資料框,預設的排序方式均為遞增排序(ascending=True),如果希望調整為遞減排序,指定 ascending=False 即可。 首先試試看 df.sort_index() ,利用鋒衛的位置字母順序排序資料框。

依照索引遞增排序 依照索引遞減排序 接著試試看 df.sort_values() ,利用年份排序資料框。

依照 year 遞增排序 依照 year 遞減排序 也能夠輸入多個變數排序,像是先依照 year 遞增排序再依照 continent 遞減排序。

先依照 year 遞增排序再依照 continent 遞減排序 在 R 語言中我們使用 dplyr 套件的 arrange() 函數來排序資料框,預設的排序方式均為遞增排序,如果希望調整為遞減排序,指定 arrange(desc()) 即可。

依照 year 遞增排序 依照 year 遞減排序 也能夠輸入多個變數排序,像是先依照 year 遞增排序再依照 continent 遞減排序。

先依照 year 遞增排序再依照 continent 遞減排序 新增變數 新增一個變數至現有的資料框中有兩種應用情景,一是計算衍生變數,二是非衍生變數,所謂衍生變數(Derived Variables)是指能夠透過現有變數生成的變數,以 1995 至 1996 年球季芝加哥公牛隊先發陣容的資料框為例,衍生變數可能是球員的姓 last_name,該變數可以從 player 衍生而得;非衍生變數可能是球員的身高,無法從既有變數中計算而得,新增非衍生變數時通常可以給一個值;或者給長度與列數相同的陣列。 在 Python pandas 中我們可以使用 .map() 方法搭配 lambda 建立衍生變數:

使用 .map() 方法搭配 lambda 建立衍生變數 last_name 輸入一個值:隊伍名稱 "Chicago Bulls" ,或者輸入五個球員的身高:

輸入一個值:隊伍名稱 "Chicago Bulls" ,或者輸入五個球員的身高 在 R 語言中可以透過 sapply() 函數實踐向量計算,將完成計算的向量直接指派回資料框中即可。

透過 sapply() 函數實踐向量計算,將完成計算的向量直接指派回資料框中 輸入一個值:隊伍名稱 "Chicago Bulls" ,或者輸入五個球員的身高:

輸入一個值:隊伍名稱 "Chicago Bulls" ,或者輸入五個球員的身高 也可以考慮使用 dplyr 套件的 mutate() 函數。

使用 dplyr 套件的 mutate() 函數 新增觀測值 我推薦使用垂直合併資料框的方式來新增觀測值,如此可以避免變數型別轉換的問題,像是在 1995 至 1996 年球季芝加哥公牛隊先發陣容資料框中加入第六人 Toni Kukoc。 在 Python pandas 中可以使用 df.append() 方法垂直合併資料框,合併完以後因為列索引值會重複,所以通常會再利用 reset_index() 方法重新設定列索引。

在 1995 至 1996 年球季芝加哥公牛隊先發陣容資料框中加入第六人 Toni Kukoc 在 R 語言中使用 rbind() 函數垂直合併資料框:

在 1995 至 1996 年球季芝加哥公牛隊先發陣容資料框中加入第六人 Toni Kukoc 摘要 除了使用 .describe() 方法或是像 summary() 函數可以獲取資料框的描述性統計,我們也能夠針對特定變數單獨摘要;例如計算 gapminder 資料框中 2007 年所有國家的人口總和。 在 Python pandas 選擇資料框中特定變數會面對 Series 這樣的資料結構,而 Series 就有完整的摘要方法供我們呼叫,像總和、平均或中位數等。

6251013179

在 R 語言可以使用 dplyr 套件的 summarise() 函數來做變數的摘要。

ttl_pop

1 6251013179

分組 除了單獨使用摘要的相關函數,我們也很常會需要利用相關的文字變數進行分組再摘要,例如計算 gapminder 資料框中 2007 年依照不同 continents 來摘要該洲所有國家的人口總和。 在 Python pandas 中我們會使用 .groupby() 方法指定用來分組資料框的文字變數,然後針對變數呼叫摘要方法,分組摘要的結果會以 Series 的型別回傳。

continent

Africa 929539692

Americas 898871184

Asia 3811953827

Europe 586098529

Oceania 24549947

Name: pop, dtype: int64

在 .groupby() 方法中放多個文字變數就會形成兩層索引值的 Series 輸出,意即照多個文字變數分組,例如依照不同年份與 continents 來摘要各年各洲所有國家的人口總和。

依照不同年份與 continents 來摘要各年各洲所有國家的人口總和 在 R 語言我們利用 dplyr 套件的 group_by() 函數搭配 summarise() 函數來完成分組摘要,結果會以 data.frame 型別(tibble 型別近似 data.frame)回傳,例如計算 gapminder 資料框中 2007 年依照不同 continents 來摘要該洲所有國家的人口總和(看後 10 筆即可)。

gapminder 資料框中 2007 年依照不同 continents 來摘要該洲所有國家的人口總和 在 group_by() 函數中放多個文字變數即照多個文字變數分組,例如依照不同年份與 continents 來摘要各年各洲所有國家的人口總和(看後 10 筆即可)。

依照不同年份與 continents 來摘要各年各洲所有國家的人口總和 延伸閱讀 pandas Foundations | DataCamp

Learn how to use the industry-standard pandas library to import, build, and manipulate DataFrames. www.datacamp.com
Manipulate Data in R | DataCamp

Learn how to manipulate data in R with the easy and intuitive Dplyr syntax--from summarizing to subsetting data.--from… www.datacamp.com
pandas: powerful Python data analysis toolkit - pandas 0.23.1 documentation

Many of these principles are here to address the shortcomings frequently experienced using other languages / scientific… pandas.pydata.org
PythonRData ScienceDataframes Like what you read? Give Yao-Jen Kuo a round of applause. From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.

70

Follow Go to the profile of Yao-Jen Kuo Yao-Jen Kuo Medium member since May 2018 Could that data be any tidier? It is always nice to meet a data enthusiast who is also a marathon runner and a ping-pong lover. Follow DataInPoint DataInPoint DataInPoint 是一個超棒的資料科學專欄,主題涵蓋資料、程式、機器學習與高效能運算。 Also tagged Python Learning Python: From Zero to Hero Go to the profile of TK TK

31K

Also tagged Python 5 Quick and Easy Data Visualizations in Python with Code Go to the profile of George Seif George Seif

6.4K

Responses Write a response…

70

Next story How to Build a Data Science Portfolio


  • create empty dataframe
df <- dataframe()
  • Replace NULL in a dataframe
df.m[is.na(df.m)] <- 0    

gsub("NULL",0,Data_ori)

Reference:

results matching ""

    No results matching ""