• 【DW组队学习—动手学数据分析】第二章:第一节数据清洗及特征处理-课程学习


    【回顾&引言】前面一章的内容大家可以感觉到我们主要是对基础知识做一个梳理,让大家了解数据分析的一些操作,主要做了数据的各个角度的观察。那么在这里,我们主要是做数据分析的流程性学习,主要是包括了数据清洗以及数据的特征处理,数据重构以及数据可视化。这些内容是为数据分析最后的建模和模型评价做一个铺垫。

    开始之前,导入numpy、pandas包和数据
    #加载所需的库
    import numpy as np
    import pandas as pd
    
    • 1
    • 2
    • 3
    #加载数据train.csv
    data = pd.read_csv("train.csv")
    
    • 1
    • 2

    2 第二章:数据清洗及特征处理

    我们拿到的数据通常是不干净的,所谓的不干净,就是数据中有缺失值,有一些异常点等,需要经过一定的处理才能继续做后面的分析或建模,所以拿到数据的第一步是进行数据清洗,本章我们将学习缺失值、重复值、字符串和数据转换等操作,将数据清洗成可以分析或建模的亚子。

    2.1 缺失值观察与处理

    我们拿到的数据经常会有很多缺失值,比如我们可以看到Cabin列存在NaN,那其他列还有没有缺失值,这些缺失值要怎么处理呢

    2.1.1 任务一:缺失值观察

    (1) 请查看每个特征缺失值个数

    法一:
    df.info() 可以查看每一列的列名、非空数据个数以及数据类型

    #写入代码
    data.info()
    
    • 1
    • 2
    
    RangeIndex: 891 entries, 0 to 890
    Data columns (total 12 columns):
     #   Column       Non-Null Count  Dtype  
    ---  ------       --------------  -----  
     0   PassengerId  891 non-null    int64  
     1   Survived     891 non-null    int64  
     2   Pclass       891 non-null    int64  
     3   Name         891 non-null    object 
     4   Sex          891 non-null    object 
     5   Age          714 non-null    float64
     6   SibSp        891 non-null    int64  
     7   Parch        891 non-null    int64  
     8   Ticket       891 non-null    object 
     9   Fare         891 non-null    float64
     10  Cabin        204 non-null    object 
     11  Embarked     889 non-null    object 
    dtypes: float64(2), int64(5), object(5)
    memory usage: 83.7+ KB
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    可以看到,行索引为0-890,即有891条数据,故在非空数值计数中,非空值为891的列表示没有却是特征,反之则有
    ∴在导入数据中,Age、Cabin以及Embarked列有空值,即有特征缺失值,其他列没有特征缺失

    此外,还有一些其他方法可以查看缺失值个数

    法二:
    df.isnull() 可以判断指定数据集合中的每一个值是否为空值,返回True表示此处为缺失值
    结合sum() 方法使用,可以统计每一列的空值个数

    data.isnull().head(5)
    
    • 1
    PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
    0FalseFalseFalseFalseFalseFalseFalseFalseFalseFalseTrueFalse
    1FalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalse
    2FalseFalseFalseFalseFalseFalseFalseFalseFalseFalseTrueFalse
    3FalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalse
    4FalseFalseFalseFalseFalseFalseFalseFalseFalseFalseTrueFalse
    data.isnull().sum()
    
    • 1
    PassengerId      0
    Survived         0
    Pclass           0
    Name             0
    Sex              0
    Age            177
    SibSp            0
    Parch            0
    Ticket           0
    Fare             0
    Cabin          687
    Embarked         2
    dtype: int64
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    (2) 请查看Age, Cabin, Embarked列的数据

    #写入代码
    data[["Age", "Cabin", "Embarked"]].head(5)
    
    • 1
    • 2
    AgeCabinEmbarked
    022.0NaNS
    138.0C85C
    226.0NaNS
    335.0C123S
    435.0NaNS
    2.1.2 任务二:对缺失值进行处理

    (1)处理缺失值一般有几种思路

    答:

    • 删除有缺失值的数据
      • df.dropna() 可以删除包含缺失值数据,使用不同的参数可以实现不同的效果
        • axis 可以指定删除包含缺失值的行(axis=0)/列(axis=1)
        • how =“all”可以删除全是缺失值的行/列
        • thresh 可以**指定行非缺失属性值个数的阈值**,低于这个阈值的行数据将被删除(前两种方法删除的会太多/太少)
        • subset 可以**指定列判断缺失值并删除对应行**,即行数据若在指定列属性上为空值,则该行数据被删除
    • 填补缺失值
      • df[筛选条件] = n 运用筛选条件对空值进行指定值替换
      • df.fillna(n) 可以为缺失值填充指定值n,其中n可以是指定常数,也可以是聚合值,如列均值、中位数或众数。使用不同的参数可以实现不同的效果
        • value 可以为不同的列确定单独的常量值,使用字典形式传递给value,eg.{“列名1”:替换值,“列名2”:替换值……}
        • method 可以用该列中的前一个或下一个值替换该列中的缺失值,=‘ffill’或’pad’,表示用前一个非缺失值去填充该缺失值,=‘bflii’或’backfill’,表示用下一个非缺失值填充该缺失值。可以结合limit参数限制替换数量
        • limit 用于指定每列或每行缺失值填充的数量,默认按列操作,可以结合axis参数更改按行(axis=0)/列(axis=1)操作

    【注】参数inplace可以决定是否更新原始表格,True表示更新原始表,False表示不更新原始表

    (2) 请尝试对Age列的数据的缺失值进行处理

    #写入代码
    data["Age"].head(10)
    
    • 1
    • 2
    0    22.0
    1    38.0
    2    26.0
    3    35.0
    4    35.0
    5     NaN
    6    54.0
    7     2.0
    8    27.0
    9    14.0
    Name: Age, dtype: float64
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    #删除空值所在行数据,可以看到少了一行数据
    data.dropna(subset = ["Age"])["Age"].head(10)
    
    • 1
    • 2
    0     22.0
    1     38.0
    2     26.0
    3     35.0
    4     35.0
    6     54.0
    7      2.0
    8     27.0
    9     14.0
    10     4.0
    Name: Age, dtype: float64
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    #填充指定值,可以看到用指定值10填充了空值
    data.fillna(10)["Age"].head(10)
    
    • 1
    • 2
    0    22.0
    1    38.0
    2    26.0
    3    35.0
    4    35.0
    5    10.0
    6    54.0
    7     2.0
    8    27.0
    9    14.0
    Name: Age, dtype: float64
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    #用均值进行填充
    data["Age"].describe()
    
    • 1
    • 2
    count    714.000000
    mean      29.699118
    std       14.526497
    min        0.420000
    25%       20.125000
    50%       28.000000
    75%       38.000000
    max       80.000000
    Name: Age, dtype: float64
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    data.fillna(value = {"Age":round(data["Age"].mean(),1)})["Age"].head(10)
    
    • 1
    0    22.0
    1    38.0
    2    26.0
    3    35.0
    4    35.0
    5    29.7
    6    54.0
    7     2.0
    8    27.0
    9    14.0
    Name: Age, dtype: float64
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    #用前一个值填充
    data.fillna(method = "ffill")["Age"].head(10)
    
    • 1
    • 2
    0    22.0
    1    38.0
    2    26.0
    3    35.0
    4    35.0
    5    35.0
    6    54.0
    7     2.0
    8    27.0
    9    14.0
    Name: Age, dtype: float64
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    (3) 请尝试使用不同的方法直接对整张表的缺失值进行处理

    #写入代码
    data.head(10)
    
    • 1
    • 2
    PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
    0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
    1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
    2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
    3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
    4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
    5603Moran, Mr. JamesmaleNaN003308778.4583NaNQ
    6701McCarthy, Mr. Timothy Jmale54.0001746351.8625E46S
    7803Palsson, Master. Gosta Leonardmale2.03134990921.0750NaNS
    8913Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)female27.00234774211.1333NaNS
    91012Nasser, Mrs. Nicholas (Adele Achem)female14.01023773630.0708NaNC
    #删除具有空值的行
    data.dropna().head(10)
    
    • 1
    • 2
    PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
    1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
    3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
    6701McCarthy, Mr. Timothy Jmale54.0001746351.8625E46S
    101113Sandstrom, Miss. Marguerite Rutfemale4.011PP 954916.7000G6S
    111211Bonnell, Miss. Elizabethfemale58.00011378326.5500C103S
    212212Beesley, Mr. Lawrencemale34.00024869813.0000D56S
    232411Sloper, Mr. William Thompsonmale28.00011378835.5000A6S
    272801Fortune, Mr. Charles Alexandermale19.03219950263.0000C23 C25 C27S
    525311Harper, Mrs. Henry Sleeper (Myna Haxtun)female49.010PC 1757276.7292D33C
    545501Ostby, Mr. Engelhart Corneliusmale65.00111350961.9792B30C
    #删除至少有2个空值的行
    data.dropna(thresh = 11).head(10)
    
    • 1
    • 2
    PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
    0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
    1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
    2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
    3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
    4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
    6701McCarthy, Mr. Timothy Jmale54.0001746351.8625E46S
    7803Palsson, Master. Gosta Leonardmale2.03134990921.0750NaNS
    8913Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)female27.00234774211.1333NaNS
    91012Nasser, Mrs. Nicholas (Adele Achem)female14.01023773630.0708NaNC
    101113Sandstrom, Miss. Marguerite Rutfemale4.011PP 954916.7000G6S
    #仅删除Age列有空值的行
    data.dropna(subset = ["Age"]).head(10)
    
    • 1
    • 2
    PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
    0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
    1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
    2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
    3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
    4503Allen, Mr. William Henrymale35.0003734508.0500NaNS
    6701McCarthy, Mr. Timothy Jmale54.0001746351.8625E46S
    7803Palsson, Master. Gosta Leonardmale2.03134990921.0750NaNS
    8913Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)female27.00234774211.1333NaNS
    91012Nasser, Mrs. Nicholas (Adele Achem)female14.01023773630.0708NaNC
    101113Sandstrom, Miss. Marguerite Rutfemale4.011PP 954916.7000G6S
    #因为有空值的不同列数据类型不一样,故分别指定固定值替换
    data.fillna(value = {"Age":0, "Cabin":"C85", "Embarked": "S"}).head(10)
    
    • 1
    • 2
    PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
    0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500C85S
    1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
    2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250C85S
    3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
    4503Allen, Mr. William Henrymale35.0003734508.0500C85S
    5603Moran, Mr. Jamesmale0.0003308778.4583C85Q
    6701McCarthy, Mr. Timothy Jmale54.0001746351.8625E46S
    7803Palsson, Master. Gosta Leonardmale2.03134990921.0750C85S
    8913Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)female27.00234774211.1333C85S
    91012Nasser, Mrs. Nicholas (Adele Achem)female14.01023773630.0708C85C
    data["Cabin"].describe()
    
    • 1
    count         204
    unique        147
    top       B96 B98
    freq            4
    Name: Cabin, dtype: object
    
    • 1
    • 2
    • 3
    • 4
    • 5

    【VC小注】
    可以看到,对于非数值型的列,使用describe()方法做出的统计结果包括非空值计数、不同取值个数、频次最高取值、最高频次

    【思考1】dropna和fillna有哪些参数,分别如何使用呢?

    【参考】https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.dropna.html

    【参考】https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.fillna.html

    【思考2】检索空缺值用np.nan,None以及.isnull()哪个更好,这是为什么?如果其中某个方式无法找到缺失值,原因又是为什么?

    #思考回答
    data[data["Age"]==np.nan]
    
    • 1
    • 2
    PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
    data[data["Age"]==None]
    
    • 1
    PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
    data[data["Age"].isnull()].head(5)
    
    • 1
    PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
    5603Moran, Mr. JamesmaleNaN003308778.4583NaNQ
    171812Williams, Mr. Charles EugenemaleNaN0024437313.0000NaNS
    192013Masselmani, Mrs. FatimafemaleNaN0026497.2250NaNC
    262703Emir, Mr. Farred ChehabmaleNaN0026317.2250NaNC
    282913O'Dwyer, Miss. Ellen "Nellie"femaleNaN003309597.8792NaNQ

    可以看到只有.isnull()方法筛选出了Age列具有空值的行

    2.2 重复值观察与处理

    由于这样那样的原因,数据中会不会存在重复值呢,如果存在要怎样处理呢

    2.2.1 任务一:请查看数据中的重复值

    df.duplicated() 可以查找并显示数据表中的重复值,配合sum()方法可以得到重复值个数

    【注】

    • 当两条记录中所有的数据都相等时duplicated函数才会判断为重复值
    • duplicated支持从前向后(first),和从后向前(last)两种重复值查找模式
    • 默认是从前向后进行重复值的查找和判断,也就是后面的条目在重复值判断中显示为True
    #写入代码
    data.duplicated().head(5)
    
    • 1
    • 2
    0    False
    1    False
    2    False
    3    False
    4    False
    dtype: bool
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    data["Age"].duplicated().head(5)
    
    • 1
    0    False
    1    False
    2    False
    3    False
    4     True
    Name: Age, dtype: bool
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    #检查有多少重复值
    data["Age"].duplicated().sum()
    
    • 1
    • 2
    802
    
    • 1
    2.2.2 任务二:对重复值进行处理

    (1)重复值有哪些处理方式呢?

    答:删除重复值数据
    df.drop_duplicates() 可以删除重复数据

    • subset 可以指定某几列,当这几列数据都相同时删除对应行数据
    • keep {‘first’, ‘last’, False}, 默认值 ‘first’
      • first: 保留第一次出现的重复行,删除后面的重复行
      • last: 删除重复项,除了最后一次出现
      • False: 删除所有重复项

    (2)处理我们数据的重复值

    #删除重复值,因为没有完全相同的两行数据,所以没有数据被删除
    data.drop_duplicates().shape
    
    • 1
    • 2
    (891, 12)
    
    • 1
    #指定列删除重复值
    data.drop_duplicates(subset = ["Age"], keep = "first").shape
    
    • 1
    • 2
    (89, 12)
    
    • 1
    data.drop_duplicates(subset = ["Age", "Cabin"]).shape
    
    • 1
    (284, 12)
    
    • 1
    2.2.3 任务三:将前面清洗的数据保存为csv格式
    #写入代码
    data.to_csv("train_clear.csv")
    
    • 1
    • 2

    2.3 特征观察与处理

    我们对特征进行一下观察,可以把特征大概分为两大类:
    数值型特征:Survived ,Pclass, Age ,SibSp, Parch, Fare,其中Survived, Pclass为离散型数值特征,Age,SibSp, Parch, Fare为连续型数值特征
    文本型特征:Name, Sex, Cabin,Embarked, Ticket,其中Sex, Cabin, Embarked, Ticket为类别型文本特征。
    数值型特征一般可以直接用于模型的训练,但有时候为了模型的稳定性及鲁棒性会对连续变量进行离散化
    文本型特征往往需要转换成数值型特征才能用于建模分析。

    2.3.1 任务一:对年龄进行分箱(离散化)处理

    (1) 分箱操作是什么?
    答:
    在建立模型前,一般需要对特征变量进行离散化,特征离散化后,有助于处理异常值或者样本量较少的值,模型会更稳定,降低模型过拟合的风险。尤其是采用 logsitic 建立评分卡模型时,必须对连续变量进行离散化。
    特征离散化处理通常采用的就是分箱法,数据分箱(也称为离散分箱或分段)是一种数据预处理技术,用于减少次要观察误差的影响,提高泛化性
    分箱之后,数值型变量的取值空间缩小,也就取值的数量变少了,每个取值的样本量增多。
    缺点: 方差变小,但相应的偏差变大了,也就是数据所能提供的信息没有分箱前那么精确了。
    【VC小注】 可以理解为将数据按照一定规则进行分组,然后赋予离散化标签

    常见的特征分箱的方法
    根据有无目标变量,特征分箱的方法可分为两种:

    • 无监督分箱

      • 等宽(equal width):变量取值的每个区间的宽度是相等的或者有要求的

      pd.cut(x,bins,right=True,labels=None,retbins=False,precision=3,include_lowest=False,duplicates=‘raise’)

      x : 要分箱的数据,一维数组
      bins :整数,标量序列或者间隔索引,是进行分组的依据

      • 如果填入整数n,则表示将x中的数值分成等宽的n份(即每一组内的最大值与最小值之差约相等);
      • 如果是标量序列,序列中的数值表示用来分档的分界值
      • 如果是间隔索引,“ bins”的间隔索引必须不重叠

      include_lowest:布尔值,左区间开闭状态,默认为false,也就左开。
      right :布尔值,右区间开闭状态,默认为True表示右闭

      • 当“ right = True”(默认值)时,则“ bins”=[1、2、3、4]表示(1,2],(2,3],(3,4]
      • 当bins是一个间隔索引时,该参数被忽略。

      labels : 数组或布尔值,可选.指定分箱的标签

      • 如果是数组,长度要与分箱个数一致,比如“ bins”=[1、2、3、4]表示(1,2],(2,3],(3,4]一共3个区间,则labels的长度也就是标签的个数也要是3
      • 如果为False,则仅返回分箱的整数指示符,即x中的数据在第几个箱子里
      • 当bins是间隔索引时,将忽略此参数

      retbins: 是否显示分箱的分界值。默认为False,当bins取整数时可以设置retbins=True以显示分界值,得到划分后的区间
      precision:整数,默认3,存储和显示分箱标签的精度。
      duplicates:如果分箱临界值不唯一,则引发ValueError或丢弃非唯一

      • 等深\等频(equal depth):每个箱内的样本数量(容量)是相同的或者有要求的,假设有 10000 个样本,设置频数为 100,则按照数值排序后,就会分成 100 个箱子

      pd.qcut(x, q, labels=None, retbins=False, precision=3, duplicates=‘raise’)

      x :要分箱的数据,一维数组或者Serise
      q : 表示分位数的整数或者数组,

      • 如果是分位数的整数,例如10用于十分位,4用于四分位
      • 如果是分位数数组,例如[0,0.25,0.5,0.75,1]用于四分位数

      labels : 数组或者布尔值,默认为none,用于指定每个箱体的标签

      • 如果是数组,长度要与分箱个数一致,比如用四分位数分箱,需要指定四个标签
      • 如果为False,则仅返回分箱的整数指示符,即当前数据位于哪个箱子中

      rebines :布尔值,可选。 是否显示分箱的分界值。(由于是按照分位数进行分箱,在不知道分位数具体数值的情况下,可以通过这个参数设置显示分界值即分位数的具体数值)
      precision:整数,默认3,存储和显示分箱标签的精度。
      duplicates:如果分箱临界值不唯一,则引发ValueError或丢弃非唯一

      • 聚类分析:具有相同特征的数据点能够被放置在同一个箱子中,通过聚类的方式找到具有相同属性的类别。聚类分箱就是用 python 中的 k-means 函数进行划分。
      • ……
    • 有监督分箱

      • 决策树
      • 卡方分箱
      • 生存模型分箱
      • best—KS
      • 遗传算法分箱
      • ……

    对于特征的分箱,按步骤可分为两步:

    1. 细分箱:就是先把原始变量分出一些区间
    2. 粗分箱:按照临近属性是否相同将相邻的区间进行合并,放到同一类。

    【参考】
    https://blog.csdn.net/qq_22172133/article/details/118883524
    https://zhuanlan.zhihu.com/p/486766553

    (2) 将连续变量Age平均分箱成5个年龄段,并分别用类别变量12345表示

    #等宽分箱,可以看到,原始数据最后多了一列AgeBin,是根据Age分箱得到的标签结果
    #每项宽度相同,故给bins参数赋予一个常数即可
    data["AgeBin"] = pd.cut(data["Age"], bins = 5, labels = [1,2,3,4,5])
    data.to_csv("train_agebin_1.csv")
    data.head(5)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarkedAgeBin
    0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS2
    1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C3
    2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS2
    3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S3
    4503Allen, Mr. William Henrymale35.0003734508.0500NaNS3

    (3) 将连续变量Age划分为[0,5) [5,15) [15,30) [30,50) [50,80)五个年龄段,并分别用类别变量12345表示

    #仍是根据宽度进行分箱,但每箱宽度不一致,故给bins参数赋予分界值序列
    #左右区间开闭可用include_lewest和right参数确定,默认左开(false)右闭(true)
    data["AgeBin"] = pd.cut(data["Age"], bins = [0,5,15,30,50,80], labels = [1,2,3,4,5], include_lowest = True, right = False)
    data.to_csv("train_agebin_2.csv")
    data.head(5)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarkedAgeBin
    0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS3
    1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C4
    2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS3
    3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S4
    4503Allen, Mr. William Henrymale35.0003734508.0500NaNS4

    (4) 将连续变量Age按10% 30% 50% 70% 90%五个年龄段,并用分类变量12345表示

    #等频分箱,需要赋予分频数组
    data["AgeBin"] = pd.qcut(data["Age"], q = [0,0.1,0.3,0.5,0.7,0.9], labels = [1,2,3,4,5])
    data.to_csv("train_agebin_3.csv")
    data.head(5)
    
    • 1
    • 2
    • 3
    • 4
    PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarkedAgeBin
    0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS2
    1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C5
    2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS3
    3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S4
    4503Allen, Mr. William Henrymale35.0003734508.0500NaNS4

    (5) 将上面的获得的数据分别进行保存,保存为csv格式

    【参考】https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.cut.html

    【参考】https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.qcut.html

    2.3.2 任务二:对文本变量进行转换

    (1) 查看文本变量名及种类

    可以看到,文本类型数据有:Name、Sex、Ticket、Fare、Cabin

    data.info()
    
    • 1
    
    RangeIndex: 891 entries, 0 to 890
    Data columns (total 13 columns):
     #   Column       Non-Null Count  Dtype   
    ---  ------       --------------  -----   
     0   PassengerId  891 non-null    int64   
     1   Survived     891 non-null    int64   
     2   Pclass       891 non-null    int64   
     3   Name         891 non-null    object  
     4   Sex          891 non-null    object  
     5   Age          714 non-null    float64 
     6   SibSp        891 non-null    int64   
     7   Parch        891 non-null    int64   
     8   Ticket       891 non-null    object  
     9   Fare         891 non-null    float64 
     10  Cabin        204 non-null    object  
     11  Embarked     889 non-null    object  
     12  AgeBin       650 non-null    category
    dtypes: category(1), float64(2), int64(5), object(5)
    memory usage: 84.7+ KB
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    【总结】统计方法
    法一:使用df.describe() 方法可以看到文本数据列的非空数据个数、取值个数、频次最高取值、最高频次等信息。但得到的信息有限。

    法二:使用df.value_counts(normalize=False,sort=True,ascending=False,bins=None,dropna=True) 方法来统计dataframe中某列有多少个不同的取值,并且每个取值出现的次数
    参数:

    • normalize 为False时表示按照绝对值进行统计,True时按照百分比进行统计
    • bins 表示分箱,统计每个分箱对应的绝对值或百分比

    法三:使用df.unique() 方法对于一维数组或者列表去重并按元素由大到小返回一个新的无元素重复的元组或者列表。只能看到不同取值,但没有取值频次。
    此外df.nunique() 方法可以得到不同取值的个数。

    #法一
    data["Sex"].describe()
    
    • 1
    • 2
    count      891
    unique       2
    top       male
    freq       577
    Name: Sex, dtype: object
    
    • 1
    • 2
    • 3
    • 4
    • 5
    #法二
    data["Sex"].value_counts()
    
    • 1
    • 2
    male      577
    female    314
    Name: Sex, dtype: int64
    
    • 1
    • 2
    • 3
    #法三
    data["Sex"].unique()
    
    • 1
    • 2
    array(['male', 'female'], dtype=object)
    
    • 1
    data["Sex"].nunique()
    
    • 1
    2
    
    • 1

    (2) 将文本变量Sex, Cabin ,Embarked用数值变量12345表示

    【总结】文本替换方法
    法一:str.replace(old, new[, max]) 方法把字符串中的 old(旧字符串) 替换成 new(新字符串),如果指定第三个参数max,则替换不超过max次。
    法二:map(function, iterable, …) 方法会根据提供的函数对指定序列做映射。第一个参数function以参数序列中的每一个元素调用function函数,返回包含每次function函数返回值的新列表。
    法三:sklearn.preprocessing.LabelEncoder 将n个类别编码为0~n-1之间的整数(包括0和n-1)

    #法一
    data["SexNum"] = data["Sex"].replace(["male","female"], [1,2])
    data.head(5)
    
    • 1
    • 2
    • 3
    PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarkedAgeBinSexNum
    0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS21
    1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C52
    2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS32
    3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S42
    4503Allen, Mr. William Henrymale35.0003734508.0500NaNS41
    #法二
    data['SexNum'] = data['Sex'].map({'male': 1, 'female': 2})
    data.head(5)
    
    • 1
    • 2
    • 3
    PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarkedAgeBinSexNum
    0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS21
    1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C52
    2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS32
    3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S42
    4503Allen, Mr. William Henrymale35.0003734508.0500NaNS41

    (3) 将文本变量Sex, Cabin, Embarked用one-hot编码表示

    pd.got_dummies(data,prefix = None,prefix_sep =“_”,dummy_na = False,columns = None,sparse = False,drop_first = False,dtype = None ) 方法可以进行one-hot编码
    参数:

    • data array、Series或DataFrame
    • prefix string,字符串列表或字符串dict,默认为None,用于追加DataFrame列名的字符串。在DataFrame上调用get_dummies时,传递一个长度等于列数的列表。或者,前缀 可以是将列名称映射到前缀的字典。
    • prefix_sep string,默认为’_'。如果附加前缀,分隔符/分隔符要使用。或者传递与前缀一样的列表或字典。
    • dummy_na bool,默认为False。如果忽略False NaN,则添加一列以指示NaN。
    • columns 类似列表,默认为无。要编码的DataFrame中的列名称。如果列是None,那么所有与列 对象或类别 D型细胞将被转换。
    • sparse bool,默认为False。伪编码列是否应由SparseArray(True)或常规NumPy数组(False)支持。
    • drop_first bool,默认为False。是否删除第一级别。
    for feat in ["Embarked"]:
    #     x = pd.get_dummies(df["Age"] // 6)
    #     x = pd.get_dummies(pd.cut(df['Age'],5))
        x = pd.get_dummies(data[feat], prefix=feat)
        data = pd.concat([data, x], axis=1)
        #df[feat] = pd.get_dummies(df[feat], prefix=feat)
        
    data.head(5)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarkedEmbarked_CEmbarked_QEmbarked_S
    0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS001
    1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C100
    2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS001
    3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S001
    4503Allen, Mr. William Henrymale35.0003734508.0500NaNS001
    2.3.3 任务三:从纯文本Name特征里提取出Titles的特征(所谓的Titles就是Mr,Miss,Mrs等)

    str.extract(pat, flags=0, expand=True) 用于提取正则表达式中的捕获组作为DataFrame中的列。
    参数:

    • pat:具有捕获组的正则表达式模式。
    • flags:int,默认值为0(无标志)
    • expand:如果为True,则返回每个捕获组只有一列的DataFrame。

    【补充】正则表达式(regular expression)
    描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
    具体用法参考:https://www.runoob.com/regexp/regexp-syntax.html

    #写入代码
    data['Title'] = data.Name.str.extract('([A-Za-z]+)\.', expand=False)
    data.head(5)
    
    • 1
    • 2
    • 3
    PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarkedEmbarked_CEmbarked_QEmbarked_STitle
    0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS001Mr
    1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C100Mrs
    2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS001Miss
    3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S001Mrs
    4503Allen, Mr. William Henrymale35.0003734508.0500NaNS001Mr
    #保存最终你完成的已经清理好的数据
    data.to_csv("train_day2.csv")
    
    • 1
    • 2
  • 相关阅读:
    Andoroid 11 开机广播处理超时导致第三方应用启动延迟
    如何优雅地画一张图
    HCIP---企业网的三层架构
    zabbix自动发现linux系统挂载的nas盘,并实现读写故障的监控告警
    【PLC】现场总线和工业以太网汇总
    1、CsvHelper使用小记一
    【运维知识高级篇】超详细的Jenkins教程3(Maven项目上线全流程)
    手把手教你开发微信小程序自定义底部导航栏
    Windows下的定时任务设置
    OpenCV9-窗口交互操作
  • 原文地址:https://blog.csdn.net/sinat_33209811/article/details/126882121