pandas学习-文本数据

学习链接: https://github.com/datawhalechina/joyful-pandas/blob/master/%E7%AC%AC7%E7%AB%A0%20%E6%96%87%E6%9C%AC%E6%95%B0%E6%8D%AE.ipynb.

7.1 string类型的性质

  • string与object的区别
    ① 字符存取方法(如str.count)会返回相应数据的Nullable类型,而object会随缺失值的存在而改变返回类型
    ② 因为存储的是字符串而不是字节,某些Series方法不能在string上使用,例如: Series.str.decode()
    ③ string类型在缺失值存储或运算时,类型会广播为pd.NA,而不是浮点型np.nan

  • string类型的转换
    如果将一个其他类型的容器直接转换string类型可能会出错,当下正确的方法是分两部转换,先转为str型object,在转为string类型。

    pd.Series([1,'Hello']).astype('str').astype('string')
    
  • 元素的选择
    如果该单元格元素是列表,那么str[i]表示取出第i个元素;如果是单个元素,则先把元素转为列表在取出

    s.str.split('_').str[1]		#object类型,直接取
    pd.Series(['a_b_c', ['a', 'b', 'c']],dtype=object).str[1]		#先把第一个元素转换成列表再取		
    

7.2 拆分与拼接

  • str.split() 拆分 从左往右拆分

    s.str.split('_', expand=True, n=2)
    

    第一个参数:根据某一个元素分割,默认为空格
    expand参数:控制了是否将列拆开
    n参数:代表最多分割多少次
    [注]:注意split后的类型是object,因为现在Series中的元素已经不是string,而包含了list,string类型只能含有字符串。

  • str.rsplit() 从右往左拆分

  • str.cat() 拼接

    s.str.cat(s2, sep=',', na_rep='*',join=‘left’)
    

    第一个参数:需要合并的列
    sep参数:连接中间的分隔符
    na_rep参数:缺失值替代字符
    join参数:索引对齐,默认为左连接

    ① 单列拼接,就是指所有的元素进行字符合并为一个字符串

    输入:s = pd.Series(['ab',None,'d'],dtype='string')
           s.str.cat()
    输出:'abc'
    

    ② 多列拼接,可以分为表的拼接和多Series拼接
    表的拼接

    s.str.cat(pd.DataFrame({0:['1','3','5'],1:['5','b',None]},dtype='string'),na_rep='*')
    

    多列拼接

    s.str.cat([s+'0',s*2])
    

7.3 替换

  • 基础知识:正则表达式.

  • str.replace() 针对的是object类型或string类型,默认是以正则表达式为操作,目前暂时不支持DataFrame上使用
    ① 对于string类型Series,如果要替换的类型为非缺失值,直接替换

    pd.Series(['a', 'b']).str.replace('a', 'c')		#把a替换为c
    

    ② 如果要替换的类型为缺失值,先转为object再转回来

    pd.Series(['A', 'B'],dtype='string').astype('object').replace('A', pd.NA).astype('string')
    

    [注]:对于string类型Series在使用replace函数时不能使用正则表达式替换

  • replace() 针对的是任意类型的序列或数据框

    df.replace({5:6, 6:7}, inplace=True, regex=False)
    

    第一个参数:替换
    inplace参数:是否修改原数据表
    regex参数:以正则表达式的方式替换

    ① 多对一替换

    df = pd.DataFrame({'col1': list('abcde'), 'col2': range(5,10), 'col3': [1.3,2.5,3.6,4.6,5.8]}, index=list('一二三四五'))
    df.replace(['a', 'b'], 'c')
    

    ② 多对多替换

    输入:df.replace({5:6, 6:7})	
    

7.4 子串匹配与提取

  • str.extract() 只提取第一个符合条件的字符串

    输入: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)
    输出:letter digit
    A      a     1
    B      b     1
    C      c     1
    

    expand参数:默认为Ture。对于一个子组的Series,如果expand设置为False,则返回Series,若大于一个子组,则expand参数无效,全部返回DataFrame;对于一个子组的Index,如果expand设置为False,则返回提取后的Index,若大于一个子组且expand为False,报错

  • str.extractall() 会找出所有符合条件的字符串,并建立多级索引(即使只找到一个)

    输入:s.str.extractall(two_groups,expand=True)
    输出:  letter digit
      match             
    A 0          a     1
      1          a     2
    B 0          b     1
    C 0          c     1
    

    如果想查看第i层匹配,可使用xs方法

    输入:s.str.extractall(two_groups).xs(0, level='match')
    输出:  letter digit
    A      a     1
    B      b     1
    C      c     1
    
  • str.contains() 检测是否包含某种正则模式

    输入:pd.Series(['1', None, '3a', '3b', '03c'], dtype="string").str.contains('a', na=False)
    输出:
    0    False
    1    False		#na=True返回<NA>
    2     True
    3    False
    4    False
    dtype: boolean
    

    第一个参数:要匹配的字符串
    na参数:设置缺失值匹配结果为False

  • str,match() 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    False		#若是‘3a_’返回True
    3     True
    4    False
    dtype: boolean
    

7.5 常用字符串方法

  • str.strip() 常用于过滤空格

    pd.Series(list('abc'),index=[' space1  ','space2  ','  space3'],dtype="string").index.str.strip()
    
  • 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() 交换大小写

    输入:d.Series('abCD',dtype="string").str.swapcase()
    输出:
    0    ABcd
    dtype: string
    
  • str.capitalize() 大写首字母

    输入:pd.Series('abCD',dtype="string").str.capitalize()
    输出:
    0    Abcd
    dtype: string
    
  • str.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
    

问题与练习

1(a)
df = pd.read_csv(r'D:\python\python3.6\pysl\Pre_\data\String_data_one.csv', index_col='人员编号').astype('str')
temp = df['姓名'] + ":" + df['国籍'] + "国人,性别"\
       + df['性别'] + "生于" + df['出生年'] + "年" \
       + df['出生月'] + "月" + df['出生日'] + "日"
temp.to_frame().rename(columns={0:'ID'})
#1(b)
L_year = list('零一二三四五六七八九')
L_one = [s.strip() for s in list('  二三四五六七八九')]
L_two = [s.strip() for s in list(' 一二三四五六七八九')]
df_new = (df['姓名']+':'+df['国籍']+'国人,性别'+df['性别']+',生于'
          +df['出生年'].str.replace(r'\d',lambda x:L_year[int(x.group(0))])+'年'
          +df['出生月'].apply(lambda x:x if len(x)==2 else '0'+x)\
                      .str.replace(r'(?P<one>[\d])(?P<two>\d?)',lambda x:L_one[int(x.group('one'))]
                      +bool(int(x.group('one')))*'十'+L_two[int(x.group('two'))])+'月'
          +df['出生日'].apply(lambda x:x if len(x)==2 else '0'+x)\
                      .str.replace(r'(?P<one>[\d])(?P<two>\d?)',lambda x:L_one[int(x.group('one'))]
                      +bool(int(x.group('one')))*'十'+L_two[int(x.group('two'))])+'日')\
          .to_frame().rename(columns={0:'ID'})
1(c)
dic_year = {i[0]:i[1] for i in zip(list('零一二三四五六七八九'),list('0123456789'))}
dic_two = {i[0]:i[1] for i in zip(list('十一二三四五六七八九'),list('0123456789'))}
dic_one = {'十':'1','二十':'2','三十':'3',None:''}
df_res = df_new['ID'].str.extract(r'(?P<姓名>[a-zA-Z]+):(?P<国籍>[\d])国人,性别(?P<性别>[\w]),生于(?P<出生年>[\w]{4})年(?P<出生月>[\w]+)月(?P<出生日>[\w]+)日')
df_res['出生年'] = df_res['出生年'].str.replace(r'(\w)+',lambda x:''.join([dic_year[x.group(0)[i]] for i in range(4)]))
df_res['出生月'] = df_res['出生月'].str.replace(r'(?P<one>\w?十)?(?P<two>[\w])',lambda x:dic_one[x.group('one')]+dic_two[x.group('two')]).str.replace(r'0','10')
df_res['出生日'] = df_res['出生日'].str.replace(r'(?P<one>\w?十)?(?P<two>[\w])',lambda x:dic_one[x.group('one')]+dic_two[x.group('two')]).str.replace(r'^0','10')
df_res.equals(df)
2(a)
df1 = pd.read_csv(r'D:\python\python3.6\pysl\Pre_\data\String_data_two.csv')
df1[df1['col1'].str.contains(r'[北京]{2}|[上海]{2}')]
2(b)
df['col2'][~(df['col2'].str.replace(r'-?\d+','True')=='True')] #这三行有问题
df.loc[[309,396,485],'col2'] = [0,9,7]
df['col2'].astype('int').mean()
2(c)
df.columns = df.columns.str.strip()
df['col3'].head()
df['col3'][~(df['col3'].str.replace(r'-?\d+\.?\d+','True')=='True')]
df.loc[[28,122,332],'col3'] = [355.3567,9056.2253, 3534.6554]
df['col3'].astype('float').mean()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值