- string 類型的性值
- string 與object區別
- 字符存取方法,string返回相應數據的Nullable類型,object會因缺失值存在而改變返回類型;
- 某些Series方法不能再string上使用,Series.str.decode() 因爲存儲的是字符串而不是字節
- string類型在缺失值存儲或運算時,類型廣播時pd.NAN,而不是np.nan
- string類型的轉化
- 將其他類型的數據直接轉化爲string可能會出錯,辦法如下
s=pd.Series([1,1.]) print(s) s.astype('string') 輸出 0 1.0 1 1.0 dtype: float64 --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-30-2770688874d9> in <module>() #先轉化爲object類型,在轉化爲string s.astype('str').astype('string') 0 1.0 1 1.0 dtype: string
- 將其他類型的數據直接轉化爲string可能會出錯,辦法如下
- string 與object區別
- 拆分和拼接
- str.split方法
-
s.str.split(pat=None, n=-1, expand=False) #str.split方法必須時字符串
- 根據某一元素分隔,默認空格,split後的類型是object,因爲Series中的元素已經不是string,而包含了list,且string類型只能含有字符串。
s=pd.Series(['a b c',np.nan,'f_g_h'],dtype='string') print(s) print(s.str.split()) print(s.str.split('_')) a b c 1 <NA> 2 f_g_h dtype: string 0 [a, b, c] 1 <NA> 2 [f_g_h] dtype: object 0 [a b c] 1 <NA> 2 [f, g, h] print(s.str.split('_').str[0]) 0 a b c 1 <NA> 2 f dtype: object
-
pd.Series(['a_b_c',['a','b','c']],dtype='string') 這樣會報錯,string類型必須是字符串或者包含NaN
-
str方法: 可以進行元素的選擇,如果該單元格元素是列表,那麼str[i]表示取出第i個元素,如果是單個元素,則先把元素轉化爲列表在取出
print(s) print(s.str.split('_').str[1]) print(s.str[0]) 0 a_b_c 1 <NA> 2 c_d_e dtype: string 0 b 1 <NA> 2 d dtype: object 0 a 1 <NA> 2 c dtype: string
-
s=pd.Series(['a_b_c',['a','b','c']],dtype='object') print(s) s.str[1] 0 a_b_c 1 [a, b, c] dtype: object 0 _ 1 b dtype: object
#expand 參數控制了是否將列拆開,n表述最多分隔多少次 s.str.split('_',expand=True) 結果: 0 1 2 0 a b c 1 NaN NaN NaN s.str.split('_',expand=True,n=1) 結果: 0 1 0 a b_c 1 NaN NaN
-
- str.cat方法
- s.str.cat(others=None, sep=None, na_rep=None, join='left')
- 不同對象的拼接模式 cat對於不同對象的作用結果不同,其中對象包括:單列,雙列,多列
- 對於單個Series而言,就是所有的元素進行字符合併爲一個字符串
s=pd.Series(['ab',None,'d'],dtype='string') print(s) 結果 0 ab 1 <NA> 2 d dtype: string print(s.str.cat()) 結果: abd
-
sep分隔參數,缺失值替代字符na_sep
s.str.cat(sep=',') 結果:'ab,d' s.str.cat(sep=',',na_rep='*') 結果 'ab,*,d'
- 對於單個Series而言,就是所有的元素進行字符合併爲一個字符串
-
對於兩個Series合併,是對應索引的元素進行合併
s2=pd.Series(['24',None,None],dtype='string') print('s2\n',s2) print('cat:\n',s.str.cat()) s2 0 24 1 <NA> 2 <NA> dtype: string cat: abd
-
多列拼接剋分爲表的拼接和Series的拼接
-
表的拼接
print(s) s3=pd.DataFrame({0:['1','3','5'],1:['5','b',None]},dtype='string') print(s3) s.str.cat(s3,na_rep='*') 結果: 0 ab 1 <NA> 2 d dtype: string 0 1 0 1 5 1 3 b 2 5 <NA> 0 ab15 1 *3b 2 d5* dtype: string
-
多個Series的拼接
s.str.cat([s+'0',s*2,s*3]) 0 abab0ababababab 1 <NA> 2 dd0ddddd dtype: string
-
- 不同對象的拼接模式 cat對於不同對象的作用結果不同,其中對象包括:單列,雙列,多列
-
cat 的索引對齊
-
當前版本如果兩邊的索引不相同且未指定join參數,默認左連接,設置join=‘left
print(s) s2=pd.Series(list('abc'),index=[1,2,3],dtype='string') print(s2) print(s.str.cat(s2,na_rep='*')) 結果 0 ab 1 <NA> 2 d dtype: string 1 a 2 b 3 c dtype: string 0 ab* 1 *a 2 db dtype: string
-
- s.str.cat(others=None, sep=None, na_rep=None, join='left')
- str.split方法
- 替換
- str.replace常見用法
s=pd.Series(['A','B','C','Aaba','',np.nan,'CANB','dog','cat'],dtype='string') print(s) print(s.str.replace(r'^[AB]','**')) # ^[AB]以A或者B開頭 結果: 0 A 1 B 2 C 3 Aaba 4 5 <NA> 6 CANB 7 dog 8 cat dtype: string 0 ** 1 ** 2 C 3 **aba 4 5 <NA> 6 CANB 7 dog 8 cat dtype: string
- 子組和函數替換
- 通過正整數調用子組(0返回字符本身,從1開始纔是子組)
print(s) s.str.replace(r'([ABC])(\w+)',lambda x:x.group(2)[1:]+'*') 結果: 0 A 1 B 2 C_ 3 Aaba 4 5 <NA> 6 CANB 7 dog 8 cat dtype: string 0 A 1 B 2 * 3 ba* 4 5 <NA> 6 NB* 7 dog 8 cat dtype: string
- 利用?P<> 表達式可以對子組命名調用
s.str.replace(r'(?P<one>[ABC])(?P<two>\w+)',lambda x:x.group('two')[1:]+'*') 結果: 0 A 1 B 2 * 3 ba* 4 5 <NA> 6 NB* 7 dog 8 cat dtype: string
- 通過正整數調用子組(0返回字符本身,從1開始纔是子組)
- 關於str.replace注意事項
- str.replace賦值參數不能未pd.NA,需要先轉換爲object在轉換回來
#str.replace賦值參數不得爲pd.NA # print(pd.Series(['A','B'],dtype='string').str.replace(r'[A]',pd.NA)) pd.Series(['A','B'],dtype='string').astype('O').replace(r'[A]',pd.NA,regex=True).astype('string')
- 對於string類型Series在使用replace函數時不能使用正則表達式替換
print(pd.Series(['A','B'],dtype='string').replace(r'[A]','C',regex=True)) print(pd.Series(['A','B'],dtype='O').replace(r'[A]','C',regex=True)) 0 A 1 B dtype: string 0 C 1 B dtype: object
- 注意事項:
- str.replace 針對的時object和string類型,默認時以正則表達式爲操作,目前暫時不支持DataFrame使用
- repalce針對的時任意類型的序列或數據框,,如果以正則表達式替換,需要設置regex=True,該方法通過字典可支持多列替換
- str.replace賦值參數不能未pd.NA,需要先轉換爲object在轉換回來
- str.replace常見用法
- 子串匹配與提取
- str.extract方法
- 常用方法
pd.Series(['10-87','10-88'],dtype='string').str.extract(r'([\d]{2})-([\d]{2})') 結果 0 1 0 10 87 1 10 88 pd.Series(['10-87','10-88','-89'],dtype='string').str.extract(r'(?P<name_1>[\d]{2})-(?P<name_2>[\d]{2})') 結果 name_1 name_2 0 10 87 1 10 88 2 <NA> <NA> pd.Series(['10-87','10-88','-89'],dtype='string').str.extract(r'(?P<name_1>[\d]{2})?-(?P<name_2>[\d]{2})') name_1 name_2 0 10 87 1 10 88 2 <NA> 89 1
- expand方法(默認爲True)
- 對於一個子組的Series 如果expand設置爲False,則返回Series,若大於一個子組,則expand參數無效,全部返回DataFrame
s = pd.Series(["a1", "b2", "c3"], ["A11", "B22", "C33"], dtype="string") s 輸出: A11 a1 B22 b2 C33 c3 dtype: string s.str.extract(r'([\w])') 結果 0 A11 a B22 b C33 c s.str.extract(r'([\w])',expand=False) 結果 A11 a B22 b C33 c dtype: string s.str.extract(r'([\w])([\d])') 0 1 A11 a 1 B22 b 2 C33 c 3
- 對於一個子組的Index,如果expand設置爲False,則返回提取後的Index,若大於一個子組且expand爲False,報錯
s.index.str.extract(r'([\w])([\d])',expand=False) #報錯 ValueError: only one regex group is supported with Index
- 對於一個子組的Series 如果expand設置爲False,則返回Series,若大於一個子組,則expand參數無效,全部返回DataFrame
- 常用方法
-
str.extractall方法
-
與 extract只匹配一個符合條件的表達式不同,extractall會找出所有符合條件的字符串,並建立多級索引
s = pd.Series(["a1a2", "b1", "c1"], index=["A", "B", "C"],dtype="string") # print(s) two_groups = '(?P<letter>[a-z])(?P<digit>[0-9])' s.str.extract(two_groups, expand=True) letter digit A a 1 B b 1 C c 1 s.str.extractall(two_groups) 輸出 letter digit match A 0 a 1 1 a 2 B 0 b 1 C 0 c 1
-
如果想查看第i層匹配,可使用xs方法
s = pd.Series(["a1a2", "b1b2", "c1c2"], index=["A", "B", "C"],dtype="string") s.str.extractall(two_groups) letter digit match A 0 a 1 1 a 2 B 0 b 1 1 b 2 C 0 c 1 1 c 2 s.str.extractall(two_groups).xs(0,level='match') letter digit A a 1 B b 1 C c 1 s.str.extractall(two_groups).xs(1,level='match') letter digit A a 2 B b 2 C c 2
-
- str.contains str.match
-
str.contains 檢測是否包含某種正則模式
pd.Series(['1', None, '3a', '3b', '03c'], dtype="string").str.contains(r'[0-9][a-z]') 0 False 1 <NA> 2 True 3 True 4 True dtype: boolean #將空設置爲false pd.Series(['1', None, '3a', '3b', '03c'], dtype="string").str.contains('a', na=False) 0 False 1 False 2 True 3 False 4 False dtype: boolean
- str.match 依賴於python的re.match,檢測內容爲是否從頭開始包含該正則模式
pd.Series(['1', None, '3a_', '3b', '03c'], dtype="string").str.match(r'[0-9][a-z]',na=False) 0 False 1 False 2 True 3 True 4 False dtype: boolean
-
- str.extract方法
- 常用字符串方法
- 過濾型方法
- str.strip 過濾空格
s=pd.Series(list('abc'),index=[' space1 ','space2 ',' space3'],dtype="string") print(s.index) s.index.str.strip() Index([' space1 ', 'space2 ', ' space3'], dtype='object') Index(['space1', 'space2', 'space3'], dtype='object')
- str.lower str.upper
pd.Series('A',dtype="string").str.lower() 輸出 0 a dtype: string pd.Series('a',dtype="string").str.upper() 輸出: 0 A dtype: string
- str.swapcase str.capitalize :分別表示交換字母大小寫和大寫首字母
- str.strip 過濾空格
- isnumeric方法 檢查每一位是否都是數字
pd.Series(['1.2','1','-0.3','a',np.nan],dtype="string").str.isnumeric() 0 False 1 True 2 False 3 False 4 <NA> dtype: boolean
- 過濾型方法
- 問題與練習
-
- str對象方法和df/Series對象方法有什麼區別?
- 給出一列string類型,如何判斷單元格是否是數值型數據?
pd.Series(['1.2','1','-0.3','a',np.nan,1]).apply(lambda x:True if type(x)in [float,int] and x==x else False)
- rsplit方法的作用是什麼?它在什麼場合下適用?
- 從右邊開始分隔,處理的字符串比較靠近右邊的時候,容易數;
- 在本章的第二到第四節分別介紹了字符串類型的5類操作,請思考它們各自應用於什麼場景
-
拆分.str.split()比如2019年,我們只關注2019
-
拼接.str.cat() 將幾列拼接成一列
-
替換.str.replace()將Na替換成特定的值,比如衆數
-
匹配.str.contains() .str.match() 查找包含特定值的
-
提取.str.extract() .str.extractall() 查找每個元素中特定的正則表達式的格式的內容並提取出來
練習- 現有一份關於字符串的數據集,請解決以下問題:
(a)現對字符串編碼存儲人員信息(在編號後添加ID列),使用如下格式:“×××(名字):×國人,性別×,生於×年×月×日”pd.DataFrame(d.姓名+','+d.國籍+'國人,'+'性別:'+d.性別+','+'出生於'+d.出生年+'年'+d.出生月+'月'+d.出生日+'日')
(b)將(a)中的人員生日信息部分修改爲用中文表示(如一九七四年十月二十三日),其餘返回格式不變。
(c)將(b)中的ID列結果拆分爲原列表相應的5列,並使用equals檢驗是否一致。 - 現有一份半虛擬的數據集,第一列包含了新型冠狀病毒的一些新聞標題,請解決以下問題:
(a)選出所有關於北京市和上海市新聞標題的所在行。d=pd.read_csv('data/String_data_two.csv').head() d.head() d[d.col1.str.contains('北京|上海')] 輸出: col1 col2 col3 4 上海開學日期延至3月 -95 4.05
(b)求col2的均值。
(c)求col3的均值。
- 現有一份關於字符串的數據集,請解決以下問題:
-
-
-
d.col2.astype('int').mean() d.columns=d.columns.str.strip() d.columns d.col3.astype('float').mean()
應該是存在問題,怎麼可能出這麼簡單的/。。。。。。等着去看下參考答案。