教你學會 Pandas 不是個人目的,教你輕鬆玩轉 Pandas 纔是個人目的。我會經過一系列實例來帶入 Pandas 的知識點,讓你在學習 Pandas 的路上再也不枯燥。html
聲明:我所寫的輕鬆玩轉 Pandas 教程都是免費的,若是對你有幫助,你能夠持續關注我。python
在 Pandas缺失值處理 | 輕鬆玩轉Pandas(3) 介紹了 Pandas 中缺失值的處理,這一節咱們來看一看如何處理 Pandas 中的文本(字符串)。git
# 導入相關庫
import numpy as np
import pandas as pd
複製代碼
文本數據也就是咱們常說的字符串,Pandas 爲 Series 提供了 str
屬性,經過它能夠方便的對每一個元素進行操做。正則表達式
index = pd.Index(data=["Tom", "Bob", "Mary", "James", "Andy", "Alice"], name="name")
data = {
"age": [18, 30, np.nan, 40, np.nan, 30],
"city": ["Bei Jing ", "Shang Hai ", "Guang Zhou", "Shen Zhen", np.nan, " "],
"sex": [None, "male", "female", "male", np.nan, "unknown"],
"birth": ["2000-02-10", "1988-10-17", None, "1978-08-08", np.nan, "1988-10-17"]
}
user_info = pd.DataFrame(data=data, index=index)
# 將出生日期轉爲時間戳
user_info["birth"] = pd.to_datetime(user_info.birth)
user_info
複製代碼
age | birth | city | sex | |
---|---|---|---|---|
name | ||||
Tom | 18.0 | 2000-02-10 | Bei Jing | None |
Bob | 30.0 | 1988-10-17 | Shang Hai | male |
Mary | NaN | NaT | Guang Zhou | female |
James | 40.0 | 1978-08-08 | Shen Zhen | male |
Andy | NaN | NaT | NaN | NaN |
Alice | 30.0 | 1988-10-17 | unknown |
在以前已經瞭解過,在對 Series 中每一個元素處理時,咱們可使用 map
或 apply
方法。api
好比,我想要將每一個城市都轉爲小寫,可使用以下的方式。數組
user_info.city.map(lambda x: x.lower())
複製代碼
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
in ()
----> 1 user_info.city.map(lambda x: x.lower())
C:\soft\py3\lib\site-packages\pandas\core\series.py in map(self, arg, na_action)
2156 else:
2157 # arg is a function
-> 2158 new_values = map_f(values, arg)
2159
2160 return self._constructor(new_values,
pandas/_libs/src\inference.pyx in pandas._libs.lib.map_infer()
in (x)
----> 1 user_info.city.map(lambda x: x.lower())
AttributeError: 'float' object has no attribute 'lower'
複製代碼
What?居然出錯了,錯誤緣由是由於 float 類型的對象沒有 lower 屬性。這是由於缺失值(np.nan)屬於float 類型。app
這時候咱們的 str
屬性操做來了,來看看如何使用吧。機器學習
# 將文本轉爲小寫
user_info.city.str.lower()
複製代碼
name
Tom bei jing
Bob shang hai
Mary guang zhou
James shen zhen
Andy NaN
Alice
Name: city, dtype: object
複製代碼
能夠看到,經過 str
屬性來訪問以後用到的方法名與 Python 內置的字符串的方法名同樣。而且可以自動排除缺失值。學習
咱們再來試試其餘一些方法。例如,統計每一個字符串的長度。測試
user_info.city.str.len()
複製代碼
name
Tom 9.0
Bob 10.0
Mary 10.0
James 9.0
Andy NaN
Alice 1.0
Name: city, dtype: float64
複製代碼
使用 .srt
屬性也支持替換與分割操做。
先來看下替換操做,例如:將空字符串替換成下劃線。
user_info.city.str.replace(" ", "_")
複製代碼
name
Tom Bei_Jing_
Bob Shang_Hai_
Mary Guang_Zhou
James Shen_Zhen
Andy NaN
Alice _
Name: city, dtype: object
複製代碼
replace
方法還支持正則表達式,例如將全部開頭爲 S
的城市替換爲空字符串。
user_info.city.str.replace("^S.*", " ")
複製代碼
name
Tom Bei Jing
Bob
Mary Guang Zhou
James
Andy NaN
Alice
Name: city, dtype: object
複製代碼
再來看下分割操做,例如根據空字符串來分割某一列。
user_info.city.str.split(" ")
複製代碼
name
Tom [Bei, Jing, ]
Bob [Shang, Hai, ]
Mary [Guang, Zhou]
James [Shen, Zhen]
Andy NaN
Alice [, ]
Name: city, dtype: object
複製代碼
分割列表中的元素可使用 get
或 []
符號進行訪問:
user_info.city.str.split(" ").str.get(1)
複製代碼
name
Tom Jing
Bob Hai
Mary Zhou
James Zhen
Andy NaN
Alice
Name: city, dtype: object
複製代碼
user_info.city.str.split(" ").str[1]
複製代碼
name
Tom Jing
Bob Hai
Mary Zhou
James Zhen
Andy NaN
Alice
Name: city, dtype: object
複製代碼
設置參數 expand=True
能夠輕鬆擴展此項以返回 DataFrame。
user_info.city.str.split(" ", expand=True)
複製代碼
0 | 1 | 2 | |
---|---|---|---|
name | |||
Tom | Bei | Jing | |
Bob | Shang | Hai | |
Mary | Guang | Zhou | None |
James | Shen | Zhen | None |
Andy | NaN | None | None |
Alice | None |
既然是在操做字符串,很天然,你可能會想到是否能夠從一個長的字符串中提取出子串。答案是能夠的。
extract
方法接受一個正則表達式並至少包含一個捕獲組,指定參數 expand=True
能夠保證每次都返回 DataFrame。
例如,如今想要匹配空字符串前面的全部的字母,可使用以下操做:
user_info.city.str.extract("(\w+)\s+", expand=True)
複製代碼
0 | |
---|---|
name | |
Tom | Bei |
Bob | Shang |
Mary | Guang |
James | Shen |
Andy | NaN |
Alice | NaN |
若是使用多個組提取正則表達式會返回一個 DataFrame,每一個組只有一列。
例如,想要匹配出空字符串前面和後面的全部字母,操做以下:
user_info.city.str.extract("(\w+)\s+(\w+)", expand=True)
複製代碼
0 | 1 | |
---|---|---|
name | ||
Tom | Bei | Jing |
Bob | Shang | Hai |
Mary | Guang | Zhou |
James | Shen | Zhen |
Andy | NaN | NaN |
Alice | NaN | NaN |
extract
只可以匹配出第一個子串,使用 extractall
能夠匹配出全部的子串。
例如,將全部組的空白字符串前面的字母都匹配出來,能夠以下操做。
user_info.city.str.extractall("(\w+)\s+")
複製代碼
0 | ||
---|---|---|
name | match | |
Tom | 0 | Bei |
1 | Jing | |
Bob | 0 | Shang |
1 | Hai | |
Mary | 0 | Guang |
James | 0 | Shen |
除了能夠匹配出子串外,咱們還可使用 contains
來測試是否包含子串。例如,想要測試城市是否包含子串 「Zh」。
user_info.city.str.contains("Zh")
複製代碼
name
Tom False
Bob False
Mary True
James True
Andy NaN
Alice False
Name: city, dtype: object
複製代碼
固然了,正則表達式也是支持的。例如,想要測試是不是以字母 「S」 開頭。
user_info.city.str.contains("^S")
複製代碼
name
Tom False
Bob True
Mary False
James True
Andy NaN
Alice False
Name: city, dtype: object
複製代碼
這是一個神奇的功能,經過 get_dummies
方法能夠將字符串轉爲啞變量,sep
參數是指定啞變量之間的分隔符。來看看效果吧。
user_info.city.str.get_dummies(sep=" ")
複製代碼
Bei | Guang | Hai | Jing | Shang | Shen | Zhen | Zhou | |
---|---|---|---|---|---|---|---|---|
name | ||||||||
Tom | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
Bob | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 |
Mary | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
James | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 |
Andy | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Alice | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
這樣,它提取出了 Bei, Guang, Hai, Jing, Shang, Shen, Zhen, Zhou
這些啞變量,並對每一個變量下使用 0 或 1 來表達。實際上與 One-Hot(狂熱編碼)是一回事。聽不懂不要緊,以後將機器學習相關知識時會詳細介紹這裏。
這裏列出了一些經常使用的方法摘要。
方法 | 描述 |
---|---|
cat() | 鏈接字符串 |
split() | 在分隔符上分割字符串 |
rsplit() | 從字符串末尾開始分隔字符串 |
get() | 索引到每一個元素(檢索第i個元素) |
join() | 使用分隔符在系列的每一個元素中加入字符串 |
get_dummies() | 在分隔符上分割字符串,返回虛擬變量的DataFrame |
contains() | 若是每一個字符串都包含pattern / regex,則返回布爾數組 |
replace() | 用其餘字符串替換pattern / regex的出現 |
repeat() | 重複值(s.str.repeat(3)等同於x * 3 t2 >) |
pad() | 將空格添加到字符串的左側,右側或兩側 |
center() | 至關於str.center |
ljust() | 至關於str.ljust |
rjust() | 至關於str.rjust |
zfill() | 等同於str.zfill |
wrap() | 將長長的字符串拆分爲長度小於給定寬度的行 |
slice() | 切分Series中的每一個字符串 |
slice_replace() | 用傳遞的值替換每一個字符串中的切片 |
count() | 計數模式的發生 |
startswith() | 至關於每一個元素的str.startswith(pat) |
endswith() | 至關於每一個元素的str.endswith(pat) |
findall() | 計算每一個字符串的全部模式/正則表達式的列表 |
match() | 在每一個元素上調用re.match,返回匹配的組做爲列表 |
extract() | 在每一個元素上調用re.search,爲每一個元素返回一行DataFrame,爲每一個正則表達式捕獲組返回一列 |
extractall() | 在每一個元素上調用re.findall,爲每一個匹配返回一行DataFrame,爲每一個正則表達式捕獲組返回一列 |
len() | 計算字符串長度 |
strip() | 至關於str.strip |
rstrip() | 至關於str.rstrip |
lstrip() | 至關於str.lstrip |
partition() | 等同於str.partition |
rpartition() | 等同於str.rpartition |
lower() | 至關於str.lower |
upper() | 至關於str.upper |
find() | 至關於str.find |
rfind() | 至關於str.rfind |
index() | 至關於str.index |
rindex() | 至關於str.rindex |
capitalize() | 至關於str.capitalize |
swapcase() | 至關於str.swapcase |
normalize() | 返回Unicode標準格式。至關於unicodedata.normalize |
translate() | 等同於str.translate |
isalnum() | 等同於str.isalnum |
isalpha() | 等同於str.isalpha |
isdigit() | 至關於str.isdigit |
isspace() | 等同於str.isspace |
islower() | 至關於str.islower |
isupper() | 至關於str.isupper |
istitle() | 至關於str.istitle |
isnumeric() | 至關於str.isnumeric |
isdecimal() | 至關於str.isdecimal |
想要學習更多關於人工智能的知識,請關注公衆號:AI派
這裏我將整篇文章的內容整理成了pdf,想要pdf文件的能夠在公衆號後臺回覆關鍵字:pandas04。
更多Pandas知識見:輕鬆玩轉Pandas