網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
前言
pandas對(duì)文本數(shù)據(jù)也有很多便捷處理方法,可以不用寫循環(huán),向量化操作運(yùn)算速度快,還可以進(jìn)行高級(jí)的正則表達(dá)式,各種復(fù)雜的邏輯篩選和匹配提取信息。對(duì)于機(jī)器學(xué)習(xí)來(lái)說(shuō),從文本中做特征工程很是很有用的。
還是先導(dǎo)入包,讀取案例數(shù)據(jù):
import numpy as np
import pandas as pd
data = 'https://www.gairuo.com/file/data/dataset/team.xlsx'
df = pd.read_excel(data)
文本數(shù)據(jù)類型
#object 和 StringDtype 是 Pandas 的兩個(gè)文本類型,不過(guò)作為新的數(shù)據(jù)類型,官方推薦 StringDtype 的使用。
#默認(rèn)情況下,文本數(shù)據(jù)會(huì)被推斷為 object 類型。
pd.Series(['a', 'b', 'c'])
string 類型需要專門進(jìn)行指定:
pd.Series(['a', 'b', 'c'], dtype="string")
pd.Series(['a', 'b', 'c'], dtype=pd.StringDtype())
?轉(zhuǎn)換,可以從其他類型轉(zhuǎn)換到這兩個(gè)類型:
s = pd.Series(['a', 'b', 'c'])
s.astype("object") # 轉(zhuǎn)換為 object
s.astype("string") # 轉(zhuǎn)換為 string
# 類型轉(zhuǎn)換,支持 string 類型
df.convert_dtypes().dtypes
推薦使用StringDtype類型取處理文本
字符操作
我們可以使用 .str.<method> 訪問(wèn)器(Accessors)來(lái)對(duì)內(nèi)容進(jìn)行字符操作:
生成案例數(shù)據(jù):
s = pd.Series(['A', 'B', 'C', 'Aaba','Baca', np.nan, 'CABA','dog', 'cat'], dtype="string")
s
s.str.lower()# 轉(zhuǎn)為小寫
對(duì)于非字符類型我們可以先進(jìn)行轉(zhuǎn)換,再使用
# 轉(zhuǎn)為 object
df.Q1.astype(str).str
# 轉(zhuǎn)為 StringDtype
df.team.astype("string").str
df.Q1.astype(str).astype("string").str
?.str后要展示數(shù)據(jù)要進(jìn)行分割
#.str后要展示數(shù)據(jù)要進(jìn)行分割
df.team.astype("string").str.strip()#等價(jià)于df.team.astype("string")
?對(duì)索引進(jìn)行操作:
df.index.str.lower()
# 對(duì)表頭,列名進(jìn)行操作
df.columns.str.lower()
df.columns.str.strip() #相當(dāng)于df.columns
#如果對(duì)數(shù)據(jù)連續(xù)進(jìn)行字符操作,則每個(gè)操作都要使用 .str 方法:
df.columns.str.strip().str.lower().str.replace('q', '_')
文本格式
格式轉(zhuǎn)化:
#格式轉(zhuǎn)換
s = pd.Series(['lower', 'CAPITALS', 'this is a sentence', 'SwApCaSe'])
s.str.lower() # 轉(zhuǎn)為小寫
s.str.upper() # 轉(zhuǎn)為大寫
s.str.title() # 標(biāo)題格式,每個(gè)單詞大寫
s.str.capitalize() # 首字母大寫
s.str.swapcase() # 大小寫互換
s.str.casefold() # 轉(zhuǎn)為小寫,支持其他語(yǔ)言如德語(yǔ)
文本對(duì)齊
類似字符串的格式化,可以填充或者對(duì)齊
# 居中對(duì)齊,寬度為10,用 - 填充
s.str.center(10, fillchar='-')
# 左對(duì)齊
s.str.ljust(10, fillchar='-')
# 右對(duì)齊
s.str.rjust(10, fillchar='-')
?指定寬度,填充內(nèi)容對(duì)齊方式,填充內(nèi)容
# side{‘left', ‘right', ‘both'}, default ‘left'
s.str.pad(width=10, side='left', fillchar='-')
# 填充對(duì)齊
s.str.zfill(10) # 生成字符,不足10位的前邊加0
?文本計(jì)數(shù)和編碼
# 指定字母的數(shù)量
s.str.count('a')
# 支持正則,包含 abc 三個(gè)字母的總數(shù)
s.str.count(r'a|b|c')
# 字符長(zhǎng)度
s.str.len()
# 編碼
s.str.encode('utf-8')
# 解碼
s.str.decode('utf-8')
# 字符串的Unicode普通格式
# form{‘NFC', ‘NFKC', ‘NFD', ‘NFKD'}
s.str.normalize('NFC')
格式判斷
#類別判斷,以下方法可以判斷文本的相關(guān)格式:
# 檢查字母和數(shù)字字符
s.str.isalpha() # 是否純英文數(shù)字單詞組成
s.str.isalnum() # 是否單詞、數(shù)字或者它們組合形式組成
?請(qǐng)注意,對(duì)于字母數(shù)字檢查,針對(duì)混合了任何額外標(biāo)點(diǎn)或空格的字符的檢查將計(jì)算為 False
s.str.isdecimal() # 是否數(shù)字 0-9 組成合規(guī)10進(jìn)制數(shù)字
s.str.isdigit() # 同 但可識(shí)別 unicode中的上標(biāo)和下標(biāo)數(shù)字
s.str.isnumeric() # 是否可識(shí)別為一個(gè)數(shù)字,同 isdigit 可識(shí)別分?jǐn)?shù)
s.str.isdecimal() #是否為小數(shù)
s.str.isspace() # 是否空格
s.str.islower() # 是否小寫
s.str.isupper() # 是否大寫
s.str.istitle() # 是否標(biāo)題格式,只有第一個(gè)字母大寫
?wrap將長(zhǎng)文本拆分開指定寬度的字符,用換行連接?
s.str.wrap(10)
文本高級(jí)處理
文本分割
#對(duì)內(nèi)容中的下劃線進(jìn)行了分隔,分隔后每個(gè)內(nèi)容都成為了一個(gè)列表,其中對(duì)空值是不起作用的。
s2 = pd.Series(['a_b_c', 'c_d_e', np.nan, 'f_g_h'], dtype="string")
s2.str.split('_')
分隔后可以使用 get 或者 [] 來(lái)取出相應(yīng)內(nèi)容,不過(guò) [] 是列表切片操作更加靈活,不僅可以取出單個(gè)內(nèi)容,也可以取出多個(gè)內(nèi)容組成的片斷。
取出每行第二個(gè),列表索引從 0 開始
s2.str.split('_').str[1]
# get 只能傳一個(gè)值
s2.str.split('_').str.get(1)
# [] 可以使用切片操作
s2.str.split('_').str[1:3]
s2.str.split('_').str[:-2]
# 如果不指定分隔符,會(huì)按空格進(jìn)行分隔
s2.str.split()
# 限制分隔的次數(shù),從左開始,剩余的不分隔
s2.str.split(n=2)
?##字符展開,使用 split 可以將分隔后的數(shù)據(jù)展開形成新的行內(nèi)容。
s2.str.split('_', expand=True)
?# 指定展開列數(shù),n 為切片右值
s2.str.split('_', expand=True, n=1)
#rsplit 和 split一樣,只不過(guò)它是從右邊開始分隔,如果沒有n參數(shù),rsplit和split的輸出是相同的。?
s2.str.rsplit('_', expand=True, n=1)
?#使用正則,對(duì)于規(guī)則比較復(fù)雜的,分隔符處可以傳入正則表達(dá)式:
s = pd.Series(["1+1=2"])
s.str.split(r"\+|=", expand=True)
?文本切片選擇 slice
?#可以使用 .str.slice() 將指定的內(nèi)容切除掉,不過(guò)還是推薦使用 s.str[]來(lái)實(shí)現(xiàn),這樣和Python字符串列表操作是一樣的
s = pd.Series(["koala", "fox", "chameleon"])
s.str.slice() # 不做任何事
s.str.slice(1) # 切掉第一個(gè)字符
s.str.slice(start=1) #同上
?其他參數(shù)用法:
# 切除最后一個(gè)以前的,留下最后一個(gè)
s.str.slice(start=-1) # s.str[-1]
# 切除第二位以后的
s.str.slice(stop=2) # s.str[:2]
# 切除步長(zhǎng)為2的內(nèi)容
s.str.slice(step=2) # s.str[::2]
# 切除從開頭開始,第4位以后并且步長(zhǎng)在3的內(nèi)容
# 同 s.str[0:5:3]
s.str.slice(start=0, stop=5, step=3)
劃分 partition
#.str.partition可以將文本按分隔符號(hào)劃分為三個(gè)部分,形成一個(gè)新的 DataFrame或者相關(guān)數(shù)據(jù)類型。
s = pd.Series(['Linda van der Berg', 'George Pitt-Rivers'])
s.str.partition()
?其他:
# 從右開始劃分
s.str.rpartition()
# 指定符號(hào)
s.str.partition('-')
# 劃分為一個(gè)元組列
s.str.partition('-', expand=False)
# 對(duì)索引進(jìn)行劃分
idx = pd.Index(['X 123', 'Y 999'])
idx.str.rpartition()
文本替換
s = pd.Series(['12', '-$10', '$10,000'], dtype="string")
s.str.replace('$', '')
s.str.replace(r'$|,', '')#逗號(hào)也替換
?#如果我們替換 -$ 則發(fā)現(xiàn)不起作用,是因?yàn)樘鎿Q字符默認(rèn)是支持正則的(可以使用 regex=False 不支持),可以進(jìn)行轉(zhuǎn)義來(lái)實(shí)現(xiàn)。
s.str.replace('-$', '') # 不起作用
s.str.replace(r'-\$', '-') # 進(jìn)行轉(zhuǎn)義后正常
指定位置替換
#slice_replace 可以將保留選定內(nèi)容,剩余內(nèi)容進(jìn)行替換:
s = pd.Series(['a', 'ab', 'abc', 'abdc', 'abcde'])
# 保留第一個(gè),其他的替換或者追加 X
s.str.slice_replace(1, repl='X')
?# 指定位置前刪除并用 X 替換
s.str.slice_replace(stop=2, repl='X')
# 指定區(qū)間的內(nèi)容被替換
s.str.slice_replace(start=1, stop=3, repl='X')
重復(fù)替換
# 對(duì)整體重復(fù)兩次
pd.Series(['a', 'b', 'c']).repeat(repeats=2)
# 對(duì)每個(gè)行內(nèi)的內(nèi)容重復(fù)兩次
pd.Series(['a', 'b', 'c']).str.repeat(repeats=2)
# 指定每行重復(fù)幾次
pd.Series(['a', 'b', 'c']).str.repeat(repeats=[1, 2, 3])
文本連接
#方法 s.str.cat 可以做文本連接的功能,下面介紹如何將序列的文本或者兩個(gè)文本序列連接在一起的方法。
#自身的連接
s = pd.Series(['a', 'b', 'c', 'd'], dtype="string")
s.str.cat(sep=',')
# 'a,b,c,d'
s.str.cat()
?對(duì)空值的處理:
t = pd.Series(['a', 'b', np.nan, 'd'], dtype="string")
t.str.cat(sep=',')
#'a,b,d'
t.str.cat(sep=',', na_rep='-')
?#指定列表序列連接
s.str.cat(['A', 'B', 'C', 'D'])
s.str.cat(t, na_rep='-')#空值處理
?當(dāng)然我們也可以使用 pd.concat 來(lái)進(jìn)行鏈接兩個(gè)序列:
d = pd.concat([t, s], axis=1)
'''
0 1
0 a a
1 b b
2 <NA> c
3 d d'''
# 兩次連接
s.str.cat(d, na_rep='-')
文本連接的對(duì)齊方式:
u = pd.Series(['b', 'd', 'a', 'c'],
index=[1, 3, 0, 2],
dtype="string")
# 以左邊索的為主
s.str.cat(u)
s.str.cat(u, join='left')
# 以右邊的索引為主
s.str.cat(u, join='right')
# 其他
s.str.cat(t, join='outer', na_rep='-')
s.str.cat(t, join='inner', na_rep='-')
文本查詢
#查詢 findall
s = pd.Series(['Lion', 'Monkey', 'Rabbit'])
s.str.findall('Monkey')
'''
0 []
1 [Monkey]
2 []
dtype: object
'''
# 大小寫敏感,不會(huì)查出內(nèi)容
s.str.findall('MONKEY')
s.str.findall('on') #包含on
#利用正則查詢和給定文本相同的內(nèi)容:
# 忽略大小寫
import re
s.str.findall('MONKEY', flags=re.IGNORECASE)
# 以 on 結(jié)尾
s.str.findall('on$')
# 包含多個(gè)的會(huì)形成一個(gè)列表
s.str.findall('b')
#可以使用str.find匹配返回匹配結(jié)果的位置(從0開始),-1為不匹配:
s.str.find('Monkey')
s1 = pd.Series(['Mouse', 'dog', 'house and parrot', '23', np.NaN])
s1.str.contains('og', regex=False)
文本包含
#包含 contains
#判斷字符是否有包含關(guān)系,經(jīng)常用在數(shù)據(jù)篩選中。它默認(rèn)是支持正則的,如果不需要可以關(guān)掉。na=nan 可以指定
s1 = pd.Series(['Mouse', 'dog', 'house and parrot', '23', np.NaN])
s1.str.contains('og', regex=False)
?#可以用在數(shù)據(jù)查詢篩選中:
# 名字包含 A 字母
df.loc[df.name.str.contains('A')]
# 包含 A 或者 C
df.loc[df.name.str.contains('A|C')]
# 忽略大小寫
import re
df.loc[df.name.str.contains('A|C', flags=re.IGNORECASE)]
# 包含數(shù)字
df.loc[df.name.str.contains('\d')]
?另外,.str.startswith 和 .str.endswith 還可以指定開頭還是結(jié)尾包含:
s = pd.Series(['bat', 'Bear', 'cat', np.nan])
s.str.startswith('b')
# 對(duì)空值的處理
s.str.startswith('b', na=False)
s.str.endswith('t')
s.str.endswith('t', na=False)
文本匹配
#匹配 match,確定每個(gè)字符串是否與正則表達(dá)式匹配。
pd.Series(['1', '2', '3a', '3b', '03c'], dtype="string").str.match(r'[0-9][a-z]')
文本提取
#提取 extract, .str.extract 可以利用正則將文本中的數(shù)據(jù)提取出來(lái)形成單獨(dú)的列,下列中正則將文本分為兩部分,
#第一部分匹配 ab 三個(gè)字母,第二位匹配數(shù)字,最終得這兩列,c3 由于無(wú)法匹配,最終得到兩列空值。
s=pd.Series(['a1', 'b2', 'c3'],dtype="string")
s.str .extract(r'([ab])(\d)', expand=True)
?#expand 參數(shù)如果為真則返回一個(gè) DataFrame,不管是一列還是多列,為假時(shí)只有一列時(shí)才會(huì)返回一個(gè) Series/Index。
s.str.extract(r'([ab])?(\d)')
#3是數(shù)值,匹配上了
# 取正則組的命名為列名
s.str.extract(r'(?P<letter>[ab])(?P<digit>\d)')
?#匹配全部,會(huì)將一個(gè)文本中所有符合規(guī)則的匹配出來(lái),最終形成一個(gè)多層索引數(shù)據(jù):
s = pd.Series(["a1a2", "b1b7", "c1"],index=["A", "B", "C"], dtype="string")
two_groups = '(?P<letter>[a-z])(?P<digit>[0-9])'
s.str.extract(two_groups, expand=True) # 單次匹配
s.str.extractall(two_groups)
提取虛擬變量
#可以從字符串列中提取虛擬變量。 例如用“ |”分隔:
s = pd.Series(['a', 'a|b', np.nan, 'a|c'], dtype="string")
s.str.get_dummies(sep='|')
?#也可以對(duì)索引進(jìn)行這種操作:
idx = pd.Index(['a', 'a|b', np.nan, 'a|c'])
idx.str.get_dummies(sep='|')
原文鏈接:https://blog.csdn.net/weixin_46277779/article/details/126233515
相關(guān)推薦
- 2022-06-22 深入淺析C/C++?的條件編譯_C 語(yǔ)言
- 2022-07-16 MultipartFile與base64互轉(zhuǎn)
- 2022-08-19 python中的函數(shù)和變量的用法
- 2022-03-23 詳細(xì)聊聊Redis的過(guò)期策略_Redis
- 2022-05-21 C#中Thread(線程)和Task(任務(wù))實(shí)例詳解_C#教程
- 2022-07-28 C++超詳細(xì)講解函數(shù)參數(shù)的默認(rèn)值_C 語(yǔ)言
- 2022-04-14 Python實(shí)現(xiàn)簡(jiǎn)單購(gòu)物車小程序_python
- 2022-01-22 Redis學(xué)習(xí)之旅--與SpringBoot的結(jié)合
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支