joyful-pandas(下)学习笔记——第7章 文本数据
【练习一】 现有一份关于字符串的数据集,请解决以下问题:
(a)现对字符串编码存储人员信息(在编号后添加ID列),使用如下格式:“×××(名字):×国人,性别×,生于×年×月×日”
df['姓名'].str.cat(df['国籍'],sep=':').str.cat(df['性别'],sep='国人,性别').str.cat(df['出生年'],sep=',生于').str.cat(df['出生月'],sep='年').str.cat(df['出生日'],sep='月')+'日'
(b)将(a)中的人员生日信息部分修改为用中文表示(如一九七四年十月二十三日),其余返回格式不变。
L_year = list('零一二三四五六七八九')
L_one = [s.strip() for s in list(' 二三四五六七八九')]
L_two = [s.strip() for s in list(' 一二三四五六七八九')]
年部分:
df['出生年'].str.replace(r'\d',lambda x:L_year[int(x.group(0))])
人员编号
1 一九四二
2 一九八五
3 一九四六
4 一九九九
5 二零一零
...
1996 一九八四
1997 一九四三
1998 二零一八
1999 二零零五
2000 一九六二
Name: 出生年, Length: 2000, dtype: object
月部分:
-
先转换成两位数字(因为有10的存在)
-
将所有两位数字转换为空,所以字符组one前面才要有两个空
-
然后先用bool判断字符串里是不是满足字符组One(0-9),str.replace会将非str类型转换为NAN
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'})
df_new.head()
(c)将(b)中的ID列结果拆分为原列表相应的5列,并使用equals检验是否一致。
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.head()
本文是对joyful-pandas教程的学习思考,感谢GYH大佬的分享!感谢Datawhale的学习组织!
joyful-pandas教程地址http://dwz.date/aZCT