4-1 数据类型的转科单


文档摘要

4-1 数据类型的转科单:astype与tonumeric 本节摘要:object列转数值用tonumeric配errors参数最稳,astype适合干净数据的常规转科,category血型能大幅省内存并固定类别顺序。本节结掉第01章埋的病灶:金额列里的字符串'880'。 承接内科出院的数据:缺失与重复已清,但金额列仍是object血型——聚合、画图、建模全被它拖住。转科是可计算的前提。 首诊:确认血型病灶 astype是"完全信任"的转科:数据里有一个异类就直接抛异常。两种态度可选。 tonumeric的三种态度 coerce的代价要认清:异类被静默换成NaN,等于把类型病转成了缺失病。转完必须跟一句isna统计,把被转换的行捞出来人工过目,而不是让它们再悄悄溜进第03章的流程。

4-1 数据类型的转科单:astype与to_numeric

本节摘要:object列转数值用to_numeric配errors参数最稳,astype适合干净数据的常规转科,category血型能大幅省内存并固定类别顺序。本节结掉第01章埋的病灶:金额列里的字符串'880'。

承接内科出院的数据:缺失与重复已清,但金额列仍是object血型——聚合、画图、建模全被它拖住。转科是可计算的前提。

首诊:确认血型病灶

import pandas as pd df = pd.DataFrame({ '金额': [1280, 960, 1732, '880', 2100], '折扣': ['0.9', '0.85', '0.9', '0.8', '0.95'], '门店': ['A', 'B', 'A', 'C', 'A'], }) print(df.dtypes) # 金额 object ← 病灶:一粒字符串坏一列 # 折扣 object # 门店 object # 直觉写法直接转: # df['金额'].astype(int) # 抛 ValueError:cannot convert...

astype是"完全信任"的转科:数据里有一个异类就直接抛异常。两种态度可选。

to_numeric的三种态度

# 态度一 errors='raise':见异类就停(默认) # 态度二 errors='coerce':异类转NaN,其余照转 fixed = pd.to_numeric(df['金额'], errors='coerce') print(fixed) # 0 1280.0 # 1 960.0 # 2 1732.0 # 3 NaN ← '880'确实能转,此处示意异类下场 # 4 2100.0 # 态度三 errors='ignore':整列放弃转科(已不推荐)

coerce的代价要认清:异类被静默换成NaN,等于把类型病转成了缺失病。转完必须跟一句isna统计,把被转换的行捞出来人工过目,而不是让它们再悄悄溜进第03章的流程。

# 正规转科单:转、查、修三连 df['金额'] = pd.to_numeric(df['金额'], errors='coerce') bad = df[df['金额'].isna()] print('转科失败的行:', bad.index.tolist()) # 若 '880' 本是合法金额只是格式脏,先清洗再转: dirty = pd.Series(['1,280', '960', '880']) cleaned = dirty.str.replace(',', '', regex=False).astype(int) print(cleaned.sum()) # 3120

astype的常规转科

数据干净后,astype承担日常转科:

df['折扣'] = df['折扣'].astype(float) # 类型健康后,跨列计算一行完成——这在object血型下根本跑不动 df['实付'] = (df['金额'].fillna(0) * df['折扣']).round(2) print(df[['金额', '折扣', '实付']]) # 金额 折扣 实付 # 0 1280.0 0.90 1152.00 # 1 960.0 0.85 816.00 # 2 1732.0 0.90 1558.80 # 4 2100.0 0.95 1995.00 # 数值转字符串(如要拼接单号) print(df['门店'] + df.index.astype(str)) # A0 B1 A2 C4

category血型的红利

门店这种列只有三五种取值却重复一千次,object按字符串存一千遍。category把它压成"编码加字典":

df['门店'] = df['门店'].astype('category') print(df['门店'].dtype) # category print(df['门店'].cat.categories.tolist()) # ['A', 'B', 'C'] print(df['门店'].memory_usage(deep=True)) # 显著小于object版 # 固定类别顺序:让第05章的分组报告按业务序而非字母序排 df['门店'] = df['门店'].cat.set_categories(['C', 'B', 'A']) print(df['门店'].value_counts().index.tolist()) # ['C', 'B', 'A']

转科决策路径

常见转科路径与风险

转科方向 器械 风险与对策
object转数值 to_numeric coerce静默产NaN,转后必查isna
带千分位文本 先str.replace再astype 逗号不清洗直接转必失败
数值转字符串 astype(str) 前导零丢失,见1-3的登记参数
字符串日期 to_datetime 混格式用format或errors
低基数字符串 astype('category') 类别顺序用set_categories定

04-4-fig01-4

本节要点回顾

  • astype零容忍,异类直接抛异常;脏数据用to_numeric配coerce
  • coerce的代价是静默NaN,转科后必须isna复核
  • 千分位等格式病先str清洗再转,顺序不能反
  • category三红利:省内存、定类别序、加速分组
  • 类型病与缺失病会互相转化,两条流水线要联动看

追问:select_dtypes批量按血型操作

转科之外还有按血型整批处理的场景:把所有数值列一起标准化、把所有文本列一起消毒。select_dtypes就是按血型点名:

num_cols = df.select_dtypes('number').columns text_cols = df.select_dtypes('object').columns print(num_cols.tolist(), text_cols.tolist()) # ['金额', '折扣'] ['门店'] # 批量消毒:所有文本列一次过strip for c in text_cols: df[c] = df[c].str.strip()

配合第四章的规范化清单,select_dtypes能写成通用的出院检查函数——不管表结构怎么变,"所有object列先审视一遍"这条纪律永远成立。

下一节进影像科:那些大得吓人的金额,是病还是传奇。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U