fbpx

Open Data:

Google Play Store Apps

在前一篇文章中我們介紹了如何調整欄位名稱以及改變欄位的型別,接下來我們要進入下一個重點:開始著手進行資料處理與計算。在進行資料處理時,如果是使用Python原生的資料結構與函式進行處理,往往會需要使用多重迴圈,但使用 Pandas 套件時,我們可以使用名為 Vectorize Opration Technoloage的技術直接針對整個欄位的資料進行處理,這將會大大提升我們的作業效率。

  • 使用資料表

Notebook Content:

這次我們會使用google play store(‘googleplaystore.csv’)的公開資料,其中紀錄了google play平台商店中所有app的分類、評分、下載量、名稱、大小⋯⋯等相關資料,假設我們是一間app開發公司的分析人員,我們想研究目前市場中哪些分類的評分以及下載量是比較高的。

首先我們先進行字串類的處理,在上一篇文章的修改欄位名稱部分有提到,Series.str.method 的方法,其實這就是一種 Vectorize Operation Technology,他可以一次針對欄位中的所有值進行同一種方法或函式處理,比如說我們現在想要整理 installs 欄位,我們希望可以計算所有app的平均下載量,所以我們需要去除該欄位的所有單位以及逗號,並轉換欄位型別為數值型別存取為新的欄位 installs_int

Series.str.replace() 替換字串欄位內的特定字元 (官方document):


首先我們使用 Series.str.replace() 將單位與逗號去除,雖然這看起來是一個新的方法,但其實用法很簡單,只需要在.str 後面直接使用Python原生的字串處理函式就可以了:在前一篇文章中我們介紹了如何調整欄位名稱以及改變欄位的型別,接下來我們要進入下一個重點:開始著手進行資料處理與計算。在進行資料處理時,如果是使用Python原生的資料結構與函式進行處理,往往會需要使用多重迴圈,但使用 Pandas 套件時,我們可以使用名為 Vectorize Opration Technoloage的技術直接針對整個欄位的資料進行處理,這將會大大提升我們的作業效率。

google['installs_int'] = google['installs'].str.replace('M','').str.replace(',','')
print(google['installs_int'].head())
0       10000
1      500000
2     5000000
3    50000000
4      100000
Name: installs_int, dtype: int64

從下方結果可以發現,google的新欄位 installs_int 欄位中,所有單位已經被我們成功替換掉了,但欄位型別依然還是 object ,所以我們要再使用上篇文章提過的 Series.astype() 將欄位轉換為數值型別才能計算平均數:

google['installs_int'] = google['installs_int'].astype(float)
print(google['installs_int'].mean())  #16689290.578286853

 

Series.str.lower()/upper()將字串欄位所有字元轉換為大/小寫 (官方document)


像上一篇提到的修改欄位名稱方法一樣,我們也可以使用 Series.str.lower() 將字串中的字元轉換為大寫或小寫,比如說為了方便閱讀,我們想讓google的軟體分類欄位 category 轉換為全小寫字元:

print("修改前:")
print(google['category'].head())
print("修改後:")
print(google['category'].head())
修改前:
0    ART_AND_DESIGN
1    ART_AND_DESIGN
2    ART_AND_DESIGN
3    ART_AND_DESIGN
4    ART_AND_DESIGN
Name: category, dtype: object
修改後:
0    art_and_design
1    art_and_design
2    art_and_design
3    art_and_design
4    art_and_design
Name: category, dtype: object

 

Series.str.split() 字串分割 (官方document)

我們平常在處理字串的時候會使用Python原生的字串方法 split() 處理,並搭配 list() 物件的list[index] 方法選取切割後的特定部分,但 Pandas 套件裡無法直接這樣使用,因為在使用 Series.str.split() 進行切割之後欄位中的內容雖然會變成 list() 但對於pandas來說他依然是一個 DataFrame 物件中的一個欄位,所以這時候如果像原生的方式一樣直接使用 list[index] 進行選取,系統會以為你要選取某個 DataFrame 的欄位,所以這邊可以配合一個參數設定 Series.str.split(expand=True)讓系統回傳一個新的 DataFrame,再從中選取特定的欄位:

假設現在我們想要拿到不同軟體的版本,我們先試著觀察 android_ver 欄位,可以發現如果使用split() 進行字串分割,所有版本號都在第一個元素。

這邊有一個小細節,如果我們沒有設定參數 expand,系統會回傳內容為切割後list()的欄位:

df_android_ver = google['android_ver'].str.split()
df_android_ver_expand = google['android_ver'].str.split(expand=True)
print(f"expand未設定設定:{type(df_android_ver)}")
print(df_android_ver.head())
print(f"expand設定為True:{type(df_android_ver_expand)}")
print(df_android_ver_expand.head())
expand未設定設定:  #<class 'pandas.core.series.Series'>
0    [4.0.3, and, up]
1    [4.0.3, and, up]
2    [4.0.3, and, up]
3      [4.2, and, up]
4      [4.4, and, up]
Name: android_ver, dtype: object
expand設定為True:  #<class 'pandas.core.frame.DataFrame'>
       0    1   2
0  4.0.3  and  up
1  4.0.3  and  up
2  4.0.3  and  up
3    4.2  and  up
4    4.4  and  up

從上面的結果可以看到,在沒有設定參數expand 時,系統會回傳一個 Series 物件,且其中的資料是被切割後的list(),但如果設定參數 expand=False 系統則會回傳一個新的Dataframe ,每一個分割後的值會依序排列為一筆一筆資料,所以這時候我們想要拿到所有軟體的版本號,只需要選取新資料的第一欄即可:

print(df_android_ver_expand[0].head())
0    4.0.3
1    4.0.3
2    4.0.3
3      4.2
4      4.4
Name: 0, dtype: object

 

Series.str.contains()/extract() 檢查字串欄位是否存在特定值 (官方document)


再進行資料處理的時候,我們常常會需要搜尋欄位中有哪幾筆資料含有特定的字串值,這時候主要可以使用 Series.str.contains() 或是 Series.str.extract() ,這兩種方法都可以使用正規表達式來作為搜尋的依據,首先,如果該筆資料存在特定值, contains() 會回傳 True 反之則為False ,此方法通常會利用這個回傳布林值的機制,作為篩選資料的依據,且這個方法可以搜尋多個設定值,只要利用 「」字符將所有特定值串起來即可;另外 extract() 則會回傳擁有特定值的資料但只會回傳符合的部分,反之則回傳空值(NaN),但 extract() 的特定值需要使用小括號「()」作為group,不然會發生 error

我們現在想從所有資料中搜尋名稱為 ‘art’ 以及 ‘design’ 的資料,所以我們用contains()並設定特定值為 ‘art|design’

print(google[google['app'].str.contains('art|design')]['app'].head())
18                         FlipaClip - Cartoon animation
45     Canva: Poster, banner, card maker & graphic de...
58                                     Restart Navigator
80                                 Pick Your Part Garage
123                               Manicure - nail design
Name: app, dtype: object

 

接著我們使用 extract() 搜尋名稱中含有 ‘game’ 的資料,這時我們設定特定值為正規表達式「r'(.+game)’」讓系統回傳 ‘game’ 前面含有數個任何字元的資料:

print(google['app'].str.extract(r'(.+game)').dropna().head())
                                             0
728            Free intellectual training game
884                 Low Poly – Puzzle art game
908                           VRV: Anime, game
955   PlayKids - Educational cartoons and game
1810            Word Crossy - A crossword game

以上是在pandas中較為特殊的字串處理方法,如果仔細觀察可以發現 df.str.method 其實跟python原生的字串物件的處理方法一樣,相信大家都很熟悉了,所以這邊就不另外贅述。在下一篇文章中我們會繼續介紹pandas的數值操作方法~

 

Written by

Glove Yen

一個不務正業的企管人,喜歡有創造性的事物,從管理到設計到程式,目前正在鑽研資料科學以及網頁前端開發,不知從什麼時候開始已經習慣了每天coding的日子。

—轉自好文作者Glove Yen_Data Science_Python資料處理套件part5 – Pandas 資料字串處理
如果你喜歡他的文章、Python資料分析有興趣,歡迎回到他的Blog: glove-coding看更多:)

或接續觀看Pandas 第7講:Python資料處理套件Pandas數值處理與基礎統計量

 

📒 Python Pandas 系列文章:

Pandas 第1講:Python資料處理套件Pandas簡介

Pandas 第2講:Python資料處理套件Pandas資料儲存物件

Pandas 第3講:Python資料處理套件Pandas檢視與定位資料

Pandas 第4講:Python資料處理套件Pandas條件篩選資料

Pandas 第5講:Python資料處理套件Pandas整理資料欄位與型別

Pandas 第6講:Python資料處理套件Pandas 資料字串處理(本文)

Pandas 第7講:Python資料處理套件Pandas數值處理與基礎統計量

快樂學程式在Udemy 也推出了以Pandas 套件進行資料處理的實戰課程,這次是將Python已視覺化的方式

對資料進行解析,只要一個假日拉高你的職場競爭力!快來這裡一起快樂學程式!

如果你的入門還在單打獨鬥,歡迎來到快樂學程式找到志同道合的夥伴,你的自學之路不孤單。

Leave a Reply