美文网首页机器学习与数据挖掘我爱编程机器学习
Python数据挖掘与机器学习_通信信用风险评估实战(2)——数

Python数据挖掘与机器学习_通信信用风险评估实战(2)——数

作者: padluo | 来源:发表于2018-01-21 10:31 被阅读66次

    系列目录:

    Python数据挖掘与机器学习_通信信用风险评估实战(1)——读数据

    数据说明

    通过对读取数据的实践,下面是数据集文件对应读取后的DataFrame说明。

    数据文件 DataFrame
    DataTech_Credit_Train_Communication1.txt train_comm
    DataTech_Credit_Train_User1 train_user
    DataTech_公共数据_基础信息1 train_basic
    DataTech_公共数据_通话1 train_call

    重塑(reshape)和轴向旋转(pivot)

    其中train_comm有201703-201706共4个月的用户通话数据,以"长格式(long)"或"堆叠格式(stacked)"存储,UserI_Id直接关联其他DataFrame会出现一对多的情况,故需要对它进行重塑(reshape)和旋转(pivot)运算。train_comm有4列数据:'UserI_Id', 'R3A_Stop_Days', 'R3A_Stop_Cnt', 'date',假设只有一个需要参与重塑的数据列,可利用DataFrame的pivot方法实现转换,train_comm_pivoted = train_comm.pivot('UserI_Id', 'date', 'R3A_Stop_Days'),前两个参数值分别用作行和列索引的列名,最后一个参数值是用于填充DataFrame的数据列的列名,假设有两个需要参与重塑的数据列,那么忽略最后一个参数,得到的DataFrame就会带有层次化的列。其实,pivot只是一个快捷方式而已,用set_index创建层次化索引,再用unstack重塑可以达到同样效果。

    train_comm_pivoted = train_comm.pivot('UserI_Id', 'date')
    # train_comm_pivoted = train_comm.set_index(['UserI_Id', 'date']).unstack('date')
    
        R3A_Stop_Days   R3A_Stop_Cnt
    date    201703  201704  201705  201706  201703  201704  201705  201706
    UserI_Id                                
    10032318    1   1   1   1   1   1   1   1
    10041348    1   1   1   1   1   1   1   1
    10076180    1   1   1   1   1   1   1   1
    10099716    4   4   4   4   2   2   2   1
    10101115    1   1   1   1   1   1   1   1
    

    层次化索引

    但是,这样生成的DataFrame有multiindex columns,而我们其他的DataFrame没有,那么怎样合并具有不同列索引层次的DataFrame呢。假设合并的两个DataFrame为train_usertrain_comm_pivoted,这里提供两种解决的方案。

    一是Index to MultiIndex,add a level to the columns of train_user,

    train_user.columns = pd.MultiIndex.from_product([train_user.columns, ['in']])
    
    
        UserI_Id        RISK_Flag
        in              in
    0   60015357        0
    1   60015359        1
    2   60015362        1
    3   60015365        0
    4   10032318        1
    

    二是MultiIndex to Index

    train_comm_pivoted.columns = ['%s%s' % (a, '|%s' % b if b else '') for a, b in train_comm_pivoted.columns]
    
        R3A_Stop_Days|201703    R3A_Stop_Days|201704    R3A_Stop_Days|201705    R3A_Stop_Days|201706    R3A_Stop_Cnt|201703 R3A_Stop_Cnt|201704 R3A_Stop_Cnt|201705 R3A_Stop_Cnt|201706
    UserI_Id                                
    10032318    1   1   1   1   1   1   1   1
    10041348    1   1   1   1   1   1   1   1
    10076180    1   1   1   1   1   1   1   1
    10099716    4   4   4   4   2   2   2   1
    10101115    1   1   1   1   1   1   1   1
    

    为了方便后续与其他数据集的合并,我选择了MultiIndex to Index。

    数据库风格的DataFrame合并

    应用pandas的merge函数,接下来就可以合并train_usertrain_comm_pivoted这两个DataFrame了。

    train_user_comm = pd.merge(train_user, train_comm_pivoted, how='left', left_on='UserI_Id', right_index=True, suffixes=('_user', '_comm'))
    

    pd.merge函数的参数

    参数 说明
    left 参与合并的左侧DataFrame
    right 参与合并的右侧DataFrame
    how "inner"、"outer"、"left"、"right",默认为"inner"
    on 用于连接的列名,如果未指定,且其他连接键也未指定,则以left和right列名的交集作为连接键
    left_on 左侧DataFrame用作连接键的列
    rigth_on 右侧DataFrame用作连接键的列
    left_index 将左侧的行索引用作其连接键
    right_index 将右侧的行索引用作其连接键
    suffixes 字符串值元组,用于追加到重叠列名的末尾,默认为('_x', '_y')。

    当然,合并数据集还可以用一些其他的方式,如pandas.concatDataFrame1.join(DataFrame2),DataFrame的join实例方法,能更为方便的实现按索引的合并,它还可用于合并多个带有相同或相似索引的DataFrame对象,而不管它们有没有重叠的列。这里就引出下一个话题,将DataFrame的一个或多个列当做行索引来用,或者可能希望将行索引变成DataFrame的列。

    列和行索引的转换

    DataFrame的set_index函数会将一个或多个列转化为行索引,并创建一个新的DataFrame。

    # column to index
    train_user = train_user.set_index('UserI_Id')
    

    reset_index的功能跟set_index刚好相反,层次化索引的级别会被转移到列里面。

    # UserI_Id reset_index() to Column
    train_comm_pivoted = train_comm_pivoted.reset_index()
    

    移除重复数据

    DataFrame中经常出现重复行,可以用DataFrame的duplicated方法返回一个布尔型Series,表示各行是否是重复行,还有一个drop_duplicates方法,用于返回一个移除了重复行的DataFrame。这两个方法默认会判断全部列,我们也可以指定部分列进行重复项判断。且,它们默认保留的是第一个出现的值组合,传入参数take_last=True则保留最后一个。

    train_basic = train_basic.drop_duplicates()
    

    索引、选取

    对DataFrame进行索引是获取一个或者多个列。

    train_user_comm_basic[['UserI_Id', 'RISK_Flag']].head()
    
        UserI_Id    RISK_Flag
    0   60015357        0
    1   60015359        1
    2   60015362        1
    3   60015365        0
    4   10032318        1
    

    但是,这种索引方式有几个特殊的情况,首先通过切片或布尔型数组选取行。

    train_basic_201706 = train_basic[train_basic['date'] == 201706]
    

    为了在DataFrame行上进行标签索引,引入索引字段ix。它可以通过NumPy式的标记法和轴标签从DataFrame选取行和列的子集。

    train_user_comm_basic.ix[:3, ['UserI_Id', 'RISK_Flag']].head()
    
        UserI_Id    RISK_Flag
    0   60015357        0
    1   60015359        1
    2   60015362        1
    3   60015365        0
    
    # 切片选取,行包括末端,列不包括???
    train_user_comm_basic.ix[:3, :3].head()
    
        UserI_Id    RISK_Flag   R3A_Stop_Days|201703
    0   60015357        0       1
    1   60015359        1       4
    2   60015362        1       2
    3   60015365        0       1
    

    通过本篇的数据预处理,基本可以形成原始基础数据的一张宽表,因为给出的原始数据是脱敏的,已经做了离散化处理,如果认为宽表的特征还不够丰富的话,可以基于自己对业务和数据的理解衍生一些新的特征。

    附1:bug参考资料

    Join dataframes - one with multiindex columns and the other without
    https://stackoverflow.com/questions/43223615/join-dataframes-one-with-multiindex-columns-and-the-other-without

    Pandas dataframe with multiindex column - merge levels
    https://stackoverflow.com/questions/24290297/pandas-dataframe-with-multiindex-column-merge-levels


    您可能还想看

    Hadoop/CDH

    Hadoop实战(1)_阿里云搭建Hadoop2.x的伪分布式环境

    Hadoop实战(2)_虚拟机搭建Hadoop的全分布模式

    Hadoop实战(3)_虚拟机搭建CDH的全分布模式

    Hadoop实战(4)_Hadoop的集群管理和资源分配

    Hadoop实战(5)_Hadoop的运维经验

    Hadoop实战(6)_搭建Apache Hadoop的Eclipse开发环境

    Hadoop实战(7)_Apache Hadoop安装和配置Hue

    Hadoop实战(8)_CDH添加Hive服务及Hive基础

    Hadoop实战(9)_Hive进阶及UDF开发

    Hadoop实战(10)_Sqoop import与抽取框架封装


    微信公众号「数据分析」,分享数据科学家的自我修养,既然遇见,不如一起成长。

    数据分析

    转载请注明:转载自微信公众号「数据分析」


    读者交流电报群:

    https://t.me/sspadluo

    读者交流群

    相关文章

      网友评论

        本文标题:Python数据挖掘与机器学习_通信信用风险评估实战(2)——数

        本文链接:https://www.haomeiwen.com/subject/tqsfaxtx.html