Datawhale组队-Pandas(下)文本数据(打卡)
?
一、string類型的性質
1.string和object的區別
string類型和object不同之處有三:
- 字符存取方法(string accessor methods,如str.count)會返回相應數據的Nullable類型,而object會隨缺失值的存在而改變返回類型
- 某些Series方法不能在string上使用,例如:Series.str.decode(),因為存儲的字符串而不是字節
- string類型在缺失值存儲或運算時,類型會廣播為pd.NA,而不是浮點型np.nan
2.string類型的轉換
如果將一個其他類型的容器直接轉換string類型可能會出錯,需要分成兩個轉換,先轉成str型的object,然后再轉成string類型:
#pd.Series([1,'1.']).astype('string') #報錯 #pd.Series([1,2]).astype('string') #報錯 #pd.Series([True,False]).astype('string') #報錯#正確的 pd.Series([1,'1.']).astype('str').astype('string') pd.Series([1,2]).astype('str').astype('string') pd.Series([True,False]).astype('str').astype('string')3. str和string的區別
(a)str字符串有三種寫法:
單引號(Single quotes)、雙引號(Double quotes)、三引號(Triple quoted)。
單雙引號可以互相嵌套,三引號可以嵌套單雙引號,使得字符串擴展為多行。若要嵌套自身,需要用反斜杠轉移。
注:兩個字符串字面量之間只有空格時,它們會被自動轉換為一個字符串
?
二、拆分與拼接
1.str.split方法
(a)分割符與str的位置元素選取
s = pd.Series(['a_b_c', 'c_d_e', np.nan, 'f_g_h'], dtype="string") s.str.split('_')注意split后的類型是object,因為現在Series中的元素已經不是string,而包含了list,且string類型只能含有字符串
對于str方法可以進行元素的選擇,如果該單元格元素是列表,那么str[i]表示取出第i個元素,如果是單個元素,則先把元素轉為列表在取出
s.str.split('_').str[1](b)其他參數
expand參數控制了是否將列拆開,n參數代表最多分割多少次
2.str.cat方法
(a)不同對象的拼接模式
對于單個Series而言,指將所有的元素進行字符合并為字符串,其中可選sep分割符參數,和缺失值替代字符na_rep參數
s = pd.Series(['ab',None,'d'],dtype='string') print(s) s.str.cat(sep=',',na_rep='*')對于兩個Series合并而言,是對應索引的元素進行合并,同樣也有相應參數,但是注意是兩個缺失值被同時替換
? s = pd.Series(['ab',None,'d'],dtype='string') print(s) s2 = pd.Series(['24',None,None],dtype='string') print(s2)#使用分割符? s.str.cat(s2,sep=',',na_rep='*')多列拼接可以分為表的拼接和多Series拼接
#表的拼接 s.str.cat(pd.DataFrame({0:['1','3','5'],1:['5','b',None]},dtype='string'),na_rep='*')#多個Series拼接 s.str.cat([s+'0',s*2])(b)cat中的索引對齊
當前版本中,如果兩邊合并的索引不相同且未指定join參數,默認為左連接,設置join='left'
s2 = pd.Series(list('abc'),index=[1,2,3],dtype='string') print(s2) s.str.cat(s2,na_rep='*')三、替換
1.str.replace的常見用法?
第一個值寫r開頭的正則表達式,后一個寫替換的字符串
s = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca','', np.nan, 'CABA', 'dog', 'cat'],dtype="string") print(s) s.str.replace(r'^[AB]','***')2.子組與函數替換
通過正整數調用子組(0返回字符本身,從1開始才是子組)
s.str.replace(r'([ABC])(\w+)',lambda x:x.group(2)[1:]+'*')利用?<...>表達書可以對子組命名調用
s.str.replace(r'(?P<one>[ABC])(?P<two>\w+)',lambda x:x.group('two')[1:]+'*')3.str.replace注意事項
- str.replace針對的是object類型或string類型,默認是以正則表達式為操作,目前暫時不支持DataFrame上使用
- replace針對的是任意類型的序列或數據框,如果要以正則表達式替換,需要設置regex=True,該方法通過字典可支持多列替換,但現在由于string類型的初步引入,用法上出現了一些問題,這些issue有望在以后的版本中修復
(a)str.replace賦值參數不得為pd.NA
#pd.Series(['A','B'],dtype='string').str.replace(r'[A]',pd.NA) #報錯 #pd.Series(['A','B'],dtype='O').str.replace(r'[A]',pd.NA) #報錯pd.Series(['A','B'],dtype='string').astype('O').replace(r'[A]',pd.NA,regex=True).astype('string')(b)對于string類型Series,在使用replace函數時不能使用正則表達式替換
pd.Series(['A','B'],dtype='string').replace(r'[A]','C',regex=True) pd.Series(['A','B'],dtype='O').replace(r'[A]','C',regex=True)(c)string類型序列如果存在缺失值,不能使用replace替換
pd.Series(['A',np.nan],dtype='string').str.replace('A','B')四、子串匹配與提取
1.str.extract方法
(a)常用方法
pd.Series(['10-87', '10-88', '10-89'],dtype="string").str.extract(r'([\d]{2})-([\d]{2})')使用子組名作為列名
pd.Series(['10-87', '10-88', '-89'],dtype="string").str.extract(r'(?P<name_1>[\d]{2})-(?P<name_2>[\d]{2})')利用?正則表計選擇部分提取
pd.Series(['10-87', '10-88', '-89'],dtype="string").str.extract(r'(?P<name_1>[\d]{2})?-(?P<name_2>[\d]{2})')(b)expand參數(默認為True)
對于一個子組的Series,如果expand設置為False,則返回Series,若大于一個子組,則expand參數無效,全部返回DataFrame
對于一個子組的Index,如果expand設置為False,則返回提取后的Index,若大于一個子組且expand為False,報錯
s = pd.Series(["a1", "b2", "c3"], ["A11", "B22", "C33"], dtype="string") s.index s.str.extract(r'([\w])') s.str.extract(r'([\w])',expand=False) s.index.str.extract(r'([\w])') s.index.str.extract(r'([\w])',expand=False) s.index.str.extract(r'([\w])([\d])')2.str.extractall方法
與extract只匹配第一個符合條件的表達式不同,extractall會找出所有符合條件的字符串,并建立多級索引(即使只找到一個)?
s = pd.Series(["a1a2", "b1", "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['A']='a1' s.str.extractall(two_groups) s = pd.Series(["a1a2", "b1b2", "c1c2"], index=["A", "B", "C"],dtype="string") s.str.extractall(two_groups).xs(1,level='match')3.str.contains 和str.match
str.contains是檢測是否包含某種正則模式,可選參數為na
#查看是否包含字母和數字 pd.Series(['1', None, '3a', '3b', '03c'], dtype="string").str.contains(r'[0-9][a-z]') #查看是否包含a pd.Series(['1', None, '3a', '3b', '03c'], dtype="string").str.contains('a', na=False)str.match與str.contrains的區別在于,match依賴于python的re.match,檢測內容是否從頭開始包含該正則模式
pd.Series(['1', None, '3a_', '3b', '03c'], dtype="string").str.match(r'[0-9][a-z]',na=False) pd.Series(['1', None, '_3a', '3b', '03c'], dtype="string").str.match(r'[0-9][a-z]',na=False)五、常用字符串方法
1.過濾型方法
(a)str.strip 常同于過濾空格
pd.Series(list('abc'),index=[' space1 ','space2 ',' space3'],dtype="string").index.str.strip()(b)str.lower(字母小寫)和str.upper(字母大寫)
pd.Series('A',dtype="string").str.lower() pd.Series('a',dtype="string").str.upper()(c)str.swapcase和str.capitalize(交換字母大小寫和大寫首字母)
pd.Series('abCD',dtype="string").str.swapcase()#大寫變小寫,小寫變大寫 pd.Series('abCD',dtype="string").str.capitalize()#將字符串的第一個字母變成大寫,其他字母變小寫2.isnumeric方法
檢查每一位是否都是數字,請問如何判斷是否是數值
pd.Series(['1.2','1','-0.3','a',np.nan],dtype="string").str.isnumeric()練習:
題二:
求col2的均值,要考慮怎么將字符串類型的負數轉換為我們理解的負數,這里用split按照-分割,可將字符串分成兩部分,整數則直接轉換,負數則可以乘以-1進行轉換,在轉換過程遇到了0-,9‘,/7等不符合常規字符,可先將轉換(前提是數量不多的情況下)。代碼如下:
df.loc[[309,396,485],'col2'] = ['0','9','7'] collist = [] for i in range (df['col2'].shape[0]):strlist = df['col2'][i].split('-')if len(strlist)==2 and strlist[0] =='':col = int(strlist[1])*(-1)else:col = int(strlist[0])collist.append(col) df['new_col2'] = collist df['new_col2'].mean()官方答案,正常思路是可以用正則表達式篩選出非常規字符,然后進行轉換,正則表達式不太會,還在學習中:
df['col2'][~(df['col2'].str.replace(r'-?\d+','True')=='True')] #這三行有問題 df.loc[[309,396,485],'col2'] = [0,9,7] df['col2'].astype('int').mean()?
總結
以上是生活随笔為你收集整理的Datawhale组队-Pandas(下)文本数据(打卡)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 软件测试-测试用例
- 下一篇: gitlab 远程仓库回退到指定版本