4-3 字符串与规范化处置:整形科收官 本节摘要:str访问器提供矢量化的文本处理——strip族去空白、lower统一大小写、replace与正则做提取替换。本节给查体阶段收官:一张出院前的规范化清单,任何没过的项目都可能在第06章合并时对不上键。 异常值判完(4-2),最后进整形科。文本列的病肉眼看着最轻(不就多个空格吗),后果却最隐蔽:merge与groupby按键精确匹配,"A店"与"A店 "是两个键。这类病不报错、不警告,只在结果里少数据。 str访问器:给整列做整形 str链式调用与python字符串方法同名,上手零成本。注意Series是object dtype才有str访问器;含None的列照常工作,None处理后仍是NaN(2-2的str条件同款行为)。
本节摘要:str访问器提供矢量化的文本处理——strip族去空白、lower统一大小写、replace与正则做提取替换。本节给查体阶段收官:一张出院前的规范化清单,任何没过的项目都可能在第06章合并时对不上键。
异常值判完(4-2),最后进整形科。文本列的病肉眼看着最轻(不就多个空格吗),后果却最隐蔽:merge与groupby按键精确匹配,"A店"与"A店 "是两个键。这类病不报错、不警告,只在结果里少数据。
import pandas as pd df = pd.DataFrame({ '门店': ['A店 ', ' a店', 'A店', 'B店', ' B店 '], '电话': ['010-88886666', '(010)77778888', '13900001111', '010-66665555', None], }) # 三板斧:去空白、统一大小写、全半角 df['门店干净'] = df['门店'].str.strip().str.upper() print(df['门店干净'].tolist()) # ['A店', 'A店', 'A店', 'B店', 'B店'] ← 五个值收敛成两个 # 没整形前的分组现场: print(df['门店'].value_counts().to_dict()) # {'A店': 1, ' a店': 1, 'A店 ': 1, ' B店 ': 1, 'B店': 1} ← 一店一格 print(df['门店干净'].value_counts().to_dict()) # {'A店': 3, 'B店': 2}
str链式调用与python字符串方法同名,上手零成本。注意Series是object dtype才有str访问器;含None的列照常工作,None处理后仍是NaN(2-2的str条件同款行为)。
# 提取:从电话里抽出区号与号码 extracted = df['电话'].str.extract(r'\(?(\d{3})\)?[-]?(\d{8})') print(extracted) # 0 1 # 0 010 88886666 # 1 010 77778888 # 2 NaN NaN ← 手机号不匹配,返回NaN # 3 010 66665555 # 4 NaN NaN # 替换:把英文标签批量换中文 labels = pd.Series(['online', 'offline', 'online']) print(labels.str.replace('online', '线上', regex=False).unique()) # ['线上', '线下'] # 切分:一列拆多列 addr = pd.Series(['北京市-朝阳区-望京', '上海市-浦东新区-张江']) parts = addr.str.split('-', expand=True) print(parts.iloc[0].tolist()) # ['北京市', '朝阳区', '望京']
⚠️ 常见坑:replace默认按正则解释字符串,传'('这类正则元字符会抛错误。纯文本替换永远加regex=False,这是个一行参数省一小时排错的习惯。
s = pd.Series(['订单T01', '订单T02', '运费', '订单T03']) print(s.str.startswith('订单').sum()) # 3 print(s.str.contains('T0[12]', regex=True).tolist()) # [True, True, False, False] print(s.str.len()) # 0 5 # 1 5 # 2 2 # 3 5 # 找出长度异常的脏值(拼接错位的字段往往长度先露馅) weird = df['门店'][df['门店'].str.len() > 3] print(weird.tolist()) # []
三个科室走完,数据出院前过一遍这张清单:
def discharge_checklist(df): """出院体检:逐项过筛,返回问题报告""" report = {} report['object列'] = df.select_dtypes('object').columns.tolist() report['门店唯一值'] = sorted(df['门店'].str.strip().unique().tolist()) report['缺失合计'] = int(df.isna().sum().sum()) dup_n = int(df.duplicated().sum()) report['整行重复'] = dup_n return report df['门店'] = df['门店'].str.strip() print(discharge_checklist(df)) # {'object列': ['门店', '电话'], '门店唯一值': ['A店', 'B店'], # '缺失合计': 4, '整行重复': 0}

整形科最后回答一个度的问题:strip、lower、格式统一是必做项,但再往深做(拼音归一、简称映射、地址标准化)就要看下游需求了。判断标准只有一条:规范化的深度跟着合并与分组的键走。键只用到门店名,就把门店名消毒到位;不参与任何键的备注列,保留原样反而是 feature——它是追溯原始记录的凭证,过度清洗会把证据洗掉。查体阶段的目标是"健康"不是"无菌",这个分寸感是清洗老手和新手最大的差别。
下一章起进入报告阶段:分组与聚合把千行明细压成一张会诊报告。