Pandas 第7章 文本数据

目录

string 类型的性值

拆分和拼接

替换

子串匹配与提取

常用字符串方法

问题与练习


  1. string 类型的性值
    1. string 与object区别
      1. 字符存取方法,string返回相应数据的Nullable类型,object会因缺失值存在而改变返回类型;
      2. 某些Series方法不能再string上使用,Series.str.decode()  因为存储的是字符串而不是字节
      3. string类型在缺失值存储或运算时,类型广播时pd.NAN,而不是np.nan
    2. string类型的转化
      1. 将其他类型的数据直接转化为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
        
        ​
        
        ​

 

  1. 拆分和拼接
    1. str.split方法
      1. s.str.split(pat=None, n=-1, expand=False) #str.split方法必须时字符串
      2. 根据某一元素分隔,默认空格,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

         

      3. pd.Series(['a_b_c',['a','b','c']],dtype='string')
        
        
        这样会报错,string类型必须是字符串或者包含NaN
      4. 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

         

      5. 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

         

    2. str.cat方法
      1. s.str.cat(others=None, sep=None, na_rep=None, join='left')
        1. 不同对象的拼接模式 cat对于不同对象的作用结果不同,其中对象包括:单列,双列,多列
          1. 对于单个Series而言,就是所有的元素进行字符合并为一个字符串
            s=pd.Series(['ab',None,'d'],dtype='string')
            print(s)
            
            结果
                0      ab
                1    <NA>
                2       d
                dtype: string
               
            print(s.str.cat()) 
              
            结果:
            
             abd
          2. sep分隔参数,缺失值替代字符na_sep

            s.str.cat(sep=',')
            
            结果:'ab,d'
            
            s.str.cat(sep=',',na_rep='*')
            
            结果 'ab,*,d'

             

        2. 对于两个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
        3. 多列拼接剋分为表的拼接和Series的拼接

          1. 表的拼接

            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

             

          2. 多个Series的拼接

            s.str.cat([s+'0',s*2,s*3])
            
            0    abab0ababababab
            1               <NA>
            2           dd0ddddd
            dtype: string
      2. cat 的索引对齐

        1. 当前版本如果两边的索引不相同且未指定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

           

  2. 替换
    1. 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

       

    2. 子组和函数替换
      1. 通过正整数调用子组(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

         

      2. 利用?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

         

    3. 关于str.replace注意事项
      1. 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')

         

      2. 对于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

         

      3. 注意事项:
        1. str.replace 针对的时object和string类型,默认时以正则表达式为操作,目前暂时不支持DataFrame使用
        2. repalce针对的时任意类型的序列或数据框,,如果以正则表达式替换,需要设置regex=True,该方法通过字典可支持多列替换
  3. 子串匹配与提取
    1. str.extract方法
      1. 常用方法
        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
        ​
      2. expand方法(默认为True)
        1. 对于一个子组的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

           

        2. 对于一个子组的Index,如果expand设置为False,则返回提取后的Index,若大于一个子组且expand为False,报错
          s.index.str.extract(r'([\w])([\d])',expand=False) #报错
          
          
          ValueError: only one regex group is supported with Index
          

           

    2. str.extractall方法

      1. 与 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

         

      2. 如果想查看第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

         

    3. str.contains str.match
      1. 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

         

      2. 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

         

  4. 常用字符串方法
    1. 过滤型方法
      1. 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')

         

      2. 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

         

      3. str.swapcase str.capitalize    :分别表示交换字母大小写和大写首字母
    2. 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

       

  5. 问题与练习
    1.  
      1. str对象方法和df/Series对象方法有什么区别?
      2. 给出一列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)
        

         

      3.  rsplit方法的作用是什么?它在什么场合下适用?
        1. 从右边开始分隔,处理的字符串比较靠近右边的时候,容易数;
      4.  在本章的第二到第四节分别介绍了字符串类型的5类操作,请思考它们各自应用于什么场景
        1. 拆分.str.split()比如2019年,我们只关注2019 

        2. 拼接.str.cat()  将几列拼接成一列

        3. 替换.str.replace()将Na替换成特定的值,比如众数

        4. 匹配.str.contains() .str.match()   查找包含特定值的

        5. 提取.str.extract() .str.extractall()  查找每个元素中特定的正则表达式的格式的内容并提取出来


          练习

          1.  现有一份关于字符串的数据集,请解决以下问题:
            (a)现对字符串编码存储人员信息(在编号后添加ID列),使用如下格式:“×××(名字):×国人,性别×,生于×年×月×日”
            pd.DataFrame(d.姓名+','+d.国籍+'国人,'+'性别:'+d.性别+','+'出生于'+d.出生年+'年'+d.出生月+'月'+d.出生日+'日')

            (b)将(a)中的人员生日信息部分修改为用中文表示(如一九七四年十月二十三日),其余返回格式不变。
            (c)将(b)中的ID列结果拆分为原列表相应的5列,并使用equals检验是否一致。
          2.  现有一份半虚拟的数据集,第一列包含了新型冠状病毒的一些新闻标题,请解决以下问题:
            (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()

    应该是存在问题,怎么可能出这么简单的/。。。。。。等着去看下参考答案。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值