【Python基础】Pandas向量化字符串操作
一、向量化操作概述
Python內置一系列強大的字符串處理方法,但這些方法只能處理單個字符串,處理一個序列的字符串時,需要用到循環。
那么,有沒有辦法,不用循環就能同時處理多個字符串呢,pandas的向量化操作就提供了這樣的方法。
向量化的操作使我們不必擔心數組的長度和維度,只需要關系操作功能,尤為強大的是,除了支持常用的字符串操作方法,還集成了正則表達式的大部分功能,這使得pandas在處理字符串列時,具有非常大的魔力。
例如,要計算每個單詞中‘a’的個數,下面一行代碼就可以搞定,非常高效
s = pd.Series(['amazon','alibaba','baidu']) s.str.count('a') 0 2 1 3 2 1假如用內置的字符串函數進行操作,需要進行遍歷,且Python原生的遍歷操作無法處理缺失值。
#用循環進行處理 s = ['amazon','alibaba','baidu'] [i.count('a') for i in s] [2,?3,?1] #存在缺失值時,打印報錯 s = ['amazon','alibaba','baidu',None] [i.count('a') for i in s] AttributeError: 'NoneType' object has no attribute 'lower'Pandas的向量化操作,能夠正確的處理缺失值,無報錯信息,如下
s = pd.Series(['amazon','alibaba','baidu',None]) s.str.count('a') Out[36]: 0 2.0 1 3.0 2 1.0 3 NaN dtype: float64通過上面的例子,對向量化進行簡單總結,向量化是一種同時操作整個數組而不是一次操作一個元素的方法,下面從看看具體怎么應用。
?
二、向量化的字符方法
Pandas的字符串屬的方法幾乎包括了大部分Python的內置字符串方法(內置共有45個方法),下面將列舉一些常見的方法的用法,例如上面的count()方法將會返回某個字符的個數,而len方法將會返回整個字符的長度。
方法 | 說明 |
len() | 計算字符串長度 |
strip() | 等價于str.strip,去除字符串開頭和結尾處指定的字符 |
rstrip() | 等價于str.rstrip ,刪除字符串末尾的指定字符(默認為空格) |
lstrip() | 等價于str.lstrip,截掉字符串左邊的空格或指定字符 |
partition() | 等價于str.partition,根據指定的分隔符(sep)將字符串進行分割,從左邊開始 |
rpartition() | 等價于str.rpartition,根據指定的分隔符(sep)將字符串進行分割,從右邊開始 |
lower() | 等價于str.lower,所有大寫字母轉換為小寫字母,僅限英文 |
casefold() | 等價于str.casefold,所有大寫字母轉換為小寫字母,包括非英文 |
upper() | 等價于str.upper,小寫字母轉換為大寫字母 |
find() | 等價于str.find,查找字符串中指定的子字符串sub第一次出現的位置 |
rfind() | 等價于str.rfind,查找字符串中指定的子字符串sub最后一次出現的位置 |
index() | 等價于str.index,查找字符串中第一次出現的子字符串的位置 |
rindex() | 等價于str.rindex,返回子字符串最后一次出現在字符串中的索引位置 |
capitalize() | 等價于str.capitalize,將字符串的第一個字母變成大寫,其余字母變為小寫 |
swapcase() | 等價于str.swapcase,將字符串str中的大小寫字母同時進行互換 |
normalize() | 返回Unicode 標注格式。等價于 unicodedata.normalize |
translate() | 等價于str.translate,根據maketrans()函數給出的字符映射表來轉換字符 |
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,檢查字符串是否只包含十進制字符 |
startswith() | 等價于str.startswith(pat),判斷字符串是否以指定字符或子字符串開頭 |
endswith() | 等價于str.endswith(pat),判斷字符串是否以指定字符或子字符串結尾 |
center() | 等價于str.center,即字符串str居中,兩邊用字符填充 |
ljust() | 等價于str.ljust,左對齊填充,并使用fillchar填充(默認為空格) |
rjust() | 等價于str.rjust,右對齊填充,默認為空格 |
zfill() | 等價于str.zfill,右對齊,前面用0填充到指定字符串長度 |
下面選取部分函數舉例,其他函數參考字符串模塊:Python字符串的45個方法詳解
len()
import pandas as pd import numpy as np s = pd.Series(['amazon','alibaba','Baidu']) s.str.len() Out[5]: 0 6 1 7 2 5 dtype: int64lower()
s = pd.Series(['amazon','alibaba','Baidu']) s.str.lower() 0 amazon 1 alibaba 2 baiduzfill()
右對齊,前面用0填充到指定字符串長度
s = pd.Series(['56783','34','987766721','326']) s.str.zfill(10) Out[53]: 0 0000056783 1 0000000034 2 0987766721 3 0000000326 dtype: object?
三、向量化的正則表達式
Pandas的字符串方法根據Python標準庫的re模塊實現了正則表達式,下面將介紹Pandas的str屬性內置的正則表達式相關方法
方法 | 說明 |
match() | 對每個元素調用re.match(),將會返回一個布爾數組 |
extract() | 對每個元素調用re.match(),將會返回所有結果構成的字符串數組 |
findall() | 對每個元素用re.findall() |
replace() | 用正則模式替換字符串 |
contains() | 對每個元素調用re.search()返回布爾類型 |
count() | 計算符合正則表達式的字符串數量 |
split() | 等價于str.spilt(),支持正則表達式 |
rsplit() | 等價于str.rsplit()支持正則表達式 |
split()
split,按指定字符分割字符串,類似split的方法返回一個列表類型的序列
#按數字分割 pd.Series(['QQ1252號碼','QQ1353加我','我389的']).str.split('\d+') Out[39]: 0 [QQ, 號碼] 1 [QQ, 加我] 2 [我, 的] dtype: object s=pd.Series(['a_b_c', 'c_d_e', np.nan, 'f_g_h']) s.str.split('_') Out[94]: 0 [a, b, c] 1 [c, d, e] 2 NaN 3 [f, g, h] dtype: object切分后的列表中的元素可以通過get方法或者?[]?方法進行讀取
s.str.split('_').str.get(1) Out[96]: 0 b 1 d 2 NaN 3 g dtype: object使用expand方法可以輕易地將這種返回展開為一個數據表
s.str.split('_', expand=True) Out[97]: 0 1 2 0 a b c 1 c d e 2 NaN NaN NaN 3 f g h同樣,我們也可以限制切分的次數:
In [20]: s.str.split('_', expand=True, n=1) Out[20]: 0 1 0 a b_c 1 c d_e 2 NaN NaN 3 f g_hrsplit()
rsplit與split相似,不同的是,這個切分的方向是反的。即,從字串的尾端向首段切分
In [21]: s.str.rsplit('_', expand=True, n=1) Out[21]: 0 1 0 a_b c 1 c_d e 2 NaN NaN 3 f_g h
replace ()
replace方法默認使用正則表達式
s = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca','', np.nan, 'CABA', 'dog', 'cat'])s.str.replace('^.a|dog', 'XX-XX ', case=False) Out[27]: 0 A 1 B 2 C 3 XX-XX ba 4 XX-XX ca 5 6 NaN 7 XX-XX BA 8 XX-XX 9 XX-XX tfindall()
提取聊天記錄中的QQ號 s=pd.Series(['QQ號碼123452124','QQ123356123','我的Q123356189','Q號123356111注意','加我Q號123356124有驚喜']) s.str.findall('\d+') 0 [123452124] 1 [123356123] 2 [123356189] 3 [123356111] 4 [123356124]?
四、其他向量化的方法
除了上面介紹的Pandas字符串的正常操作和正則表達式外,Pandas的str屬性還提供了其他的一些方法,這些方法非常的有用,在進行特征提取或者數據清洗時,非常高效,具體如下:
方法 | 說明 |
get() | 獲取元素索引位置上的值,索引從0開始 |
slice() | 對元素進行切片取值 |
slice_replace() | 對元素進行切片替換 |
cat() | 連接字符串 |
repeat() | 重復元素 |
normalize() | 將字符串轉換為Unicode規范形式 |
pad() | 在字符串的左邊右邊或者兩邊增加空格 |
wrap() | 將字符串按照指定的寬度換行 |
join() | 用分隔符連接Series對象的每個元素 |
get_dummies() | 按照分隔符提取每個元素的dummy變量,轉換為one-hot編碼的DataFrame |
wrap()
s = pd.Series(['0000056783','0000000034','0987766721']) s.str.wrap(5) Out[68]: 0 00000\n56783 1 00000\n00034 2 09877\n66721 dtype: objectpad()
s = pd.Series(['A','E','C','D','E']) s.str.pad(5) Out[65]: 0 A 1 E 2 C 3 D 4 E dtype: objectslice()
Series_1 = pd.Series(['馬 云:2000億','馬化騰:1800億','王健林:1200億','小伍哥:0.000012億']) Series_1.str.slice(0,3) Out[33]: 0 馬 云 1 馬化騰 2 王健林 3 小伍哥 dtype: objectget()
Series_1.str.get(0) Out[34]: 0 馬 1 馬 2 王 3 小 dtype: objectslice_replace()
切片替換 Series_1.str.slice_replace(0,3,'小伍哥') Out[36]: 0 小伍哥:2000億 1 小伍哥:1800億 2 小伍哥:1200億 3 小伍哥:0.000012億 dtype: objectSeries_1.str.join('-') Out[41]: 0 馬- -云-:-2-0-0-0-億 1 馬-化-騰-:-1-8-0-0-億 2 王-健-林-:-1-2-0-0-億 3 小-伍-哥-:-0-.-0-0-0-0-1-2-億 dtype: objectSeries_1 = pd.Series(['A','E','C','D','E']) Series_1.str.get_dummies()A C D E 0 1 0 0 0 1 0 0 0 1 2 0 1 0 0 3 0 0 1 0 4 0 0 0get_dummies()
另一個需要好好解釋的是get_dummies()方法,舉個例子:假如我們用A,B,C,D來表示一個人的某個特征:
monte = pd.Series(['Graham Chapman', 'John Cleese', 'Terry Gilliam','Eric Idle', 'Terry Jones', 'Michael Palin']) full_monte = pd.DataFrame({'name': monte,'info': ['B|C|D', 'B|D', 'A|C','B|D', 'B|C', 'B|C|D']}) full_montename info 0 Graham Chapman B|C|D 1 John Cleese B|D 2 Terry Gilliam A|C 3 Eric Idle B|D 4 Terry Jones B|C 5 Michael Palin B|C|D 可以看到比如Graham Chapman有B,C,D三種特征,而John Cleese有B和D兩種特征。這時我們可以用get_dummies('|')以|作為分隔符,將這些特征進行one-hotfull_monte['info'].str.get_dummies('|') Out[52]: A B C D 0 0 1 1 1 1 0 1 0 1 2 1 0 1 0 3 0 1 0 1 4 0 1 1 0 5 0 1 1 1repeat()
s = pd.Series(['A','E','C','D','E']) s.str.repeat(2) Out[62]: 0 AA 1 EE 2 CC 3 DD 4 EE dtype:?objectcat()
作用:連接字符串?
用法:Series.str.cat(others=None, sep=None, na_rep=None)?
參數:?
others : 列表或復合列表,默認為None,如果為None則連接本身的元素?
sep : 字符串 或者None,默認為None?
na_rep : 字符串或者 None, 默認 None。如果為None缺失值將被忽略。?
返回值:?concat : 序列(Series)/索引(Index)/字符串(str)
#如果連接的是兩個序列,則會一一對應連接 s1 = pd.Series(['A','E','C','D','E']) s2 = pd.Series(['1','2','3','4','5']) s1.str.cat(s2) Out[74]: 0 A1 1 E2 2 C3 3 D4 4 E5 dtype: object#只提供一個序列,則只連接自己,默認為空格 s1.str.cat() 'AECDE' s1.str.cat(sep='-') 'A-E-C-D-E'#也可以同時復核連接,參數可以是二維的 d = pd.concat([s1, s2], axis=1) s3.str.cat(d, na_rep='-') Out[87]: 0 xA1 1 xE2 2 yC3 3 yD4 4 yE5 dtype: objec五、Pandas學習文檔
官方文檔
鏈接:https://pandas.pydata.org/pandas-docs/stable/index.html
官方文檔,每個函數和方法,都有詳細的介紹,對于英語比較好的同學,強烈推薦直接看官方文檔,非常清晰,完整。
? ? ? ? ? ? ?
中文文檔
文檔鏈接:https://www.pypandas.cn/docs/
對于英語不好的同學,可以看國內翻譯過來的文檔,還是比較全面的,基本上也能獲得比較好的學習效果。
? ? ? ?? ? ? ?
接口文檔
https://pandas.pydata.org/pandas-docs/version/0.17.0/#
?
往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習及深度學習筆記等資料打印機器學習在線手冊深度學習筆記專輯《統計學習方法》的代碼復現專輯 AI基礎下載機器學習的數學基礎專輯 獲取本站知識星球優惠券,復制鏈接直接打開: https://t.zsxq.com/y7uvZF6 本站qq群704220115。加入微信群請掃碼: 與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的【Python基础】Pandas向量化字符串操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【效率】NB,真PDF神处理工具!
- 下一篇: 【机器学习基础】用Python构建和可视