zoukankan      html  css  js  c++  java
  • 2-python数据分析-基于pandas的数据清洗、DataFrame的级联与合并操作

    基于pandas的数据清洗

    处理丢失数据

    • 有两种丢失数据:
      • None
      • np.nan(NaN)
    • 两种丢失数据的区别
      • None  是对象类型
      • np.nan 是浮点类型
    type(None)  # NoneType 对象类型
    type(np.nan)  # float 浮点类型 

    为什么在数据分析中需要用到的是浮点类型的空而不是对象类型?

    • 数据分析中会常常使用某些形式的运算来处理原始数据,如果原数数据中的空值为NAN的形式,则不会干扰或者中断运算。
    • NAN可以参与运算的
    • None是不可以参与运算

    在pandas中如果遇到了None形式的空值则pandas会将其强转成NAN的形式。pandas中,None=nan

    pandas处理空值操作

    1. 对空值进行删除
      • 删除我们一般只删除行
    2. 对空值进行填充

    主要用的技术点

    • isnull
    • notnull
    • any
    • all
    • dropna
    • fillna

    首先创建一组带有空值的数据

    df = DataFrame(data=np.random.randint(0,100,size=(7,5)))
    df.iloc[2,3] = None
    df.iloc[4,2] = np.nan
    df.iloc[5,4]= None
    df

    过滤方式1:对空值进行过滤(删除空所在的行数据)

    技术点

    • isnull,any
    • notnull,all
    df.isnull()
    
     

    # 哪些行中有空值
    # any(axis=1)检测哪些行中存有空值
    df.isnull().any(axis=1)  # any会作用isnull返回结果的每一行
    # True对应的行就是存有缺失数据的行
    
    0    False
    1    False
    2     True
    3    False
    4     True
    5     True
    6    False
    dtype: bool


    df.notnull()
    
    
    df.notnull().all(axis=1)
    
    0     True
    1     True
    2    False
    3     True
    4    False
    5    False
    6     True
    dtype: bool

    对空值进行过滤

    # 将布尔值作为源数据的行索引,只保留True对应的行数据
    
    # 用notnull过滤
    df.loc[df.notnull().all(axis=1)]    # 直接保留非Nan的数据
    
      
    # 用istnull过滤
    df.loc[df.isnull().any(axis=1)]   # 保留是Nan的数据,不是想要的结果
    
      
    # 先得到是Nan的索引然后,在所有数据中将他们删除
    nan_index = df.loc[df.isnull().any(axis=1)].index
    df.drop(labels=nan_index, axis=0)
      

    过滤方式2:dropna:可以直接将缺失的行或者列进行删除 

    df.dropna(axis=0)   # 只要是drop打头,axis所代表的意思一样

    对缺失值进行覆盖

    • fillna

    # 使用指定值将源数据中所有的空值进行填充
    # 通常我们不会这么干,会填充一个有意义的值
    df.fillna(value=999)
    # 使用空的近邻值进行填充
    # method=ffill向前填充,bfill向后填充
    df.fillna(axis=0, method='ffill')
     

    什么时候用dropna,什么时候用fillna

    • 尽量使用dropna,如果删除成本比较高,则使用fillna

    使用空值对应列的均值对空值进行填充

    for col in df.columns:
        # 检测哪些列中存有空值
        # df[col].isnull()得到所在列的布尔值,布尔值相加False为0,True为1
        # 若相加后的结果大于0则其中存在True,有空值
        if df[col].isnull().sum() > 0:
            mean_value = df[col].mean()
            df[col] = df[col].fillna(value=mean_value)
     

    面试题

    • 数据说明:

      • 数据是1个冷库的温度数据,1-7对应7个温度采集设备,1分钟采集一次。
    • 数据处理目标:

      • 用1-4对应的4个必须设备,通过建立冷库的温度场关系模型,预估出5-7对应的数据。
      • 最后每个冷库中仅需放置4个设备,取代放置7个设备。
      • f(1-4) --> y(5-7)
    • 数据处理过程:

      • 1、原始数据中有丢帧现象,需要做预处理;
      • 2、matplotlib 绘图;
      • 3、建立逻辑回归模型。
    • 无标准答案,按个人理解操作即可,请把自己的操作过程以文字形式简单描述一下,谢谢配合。

    • 测试数据为testData.xlsx

    df = pd.read_excel('./testData.xlsx')
    
    df.drop(labels=['none', 'none1'])  # 删掉没用的俩列
    
     
    df.shape   # (1060, 8)
    
    # 删除空对应的行数据
    df.dropna(axis=0).shape  # (927, 8)
    
    # 对空值进行填充,这样保证空值被填充
    df.fillna(method='ffill',axio=0).fillna(method='bfill',axis=0)
     

    处理重复数据

    df = DataFrame(data=np.random.randint(0,100,size=(8,6)))
    df.iloc[1] = [1,1,1,1,1,1]
    df.iloc[3] = [1,1,1,1,1,1]
    df.iloc[5] = [1,1,1,1,1,1]
    #检测哪些行存有重复的数据
    df.duplicated(keep='first') # 保留一行
    0    False
    1    False
    2    False
    3     True
    4    False
    5     True
    6    False
    7    False
    dtype: bool
    
    # 用检查到的布尔值取反做索引取值,得到没有重复的数据
    df.loc[~df.duplicated(keep='first')]
     

    一步到位删除重复值

    df.drop_duplicates(keep='first')  # first是保留第一行重复值
    
     
    df.drop_duplicates(keep='last')  # last是保留最后一行重复值
    
     
    df.drop_duplicates(keep=False)  # False是删除全部重复值

    处理异常数据(不符合常规的数据)

    • 自定义一个1000行3列(A,B,C)取值范围为0-1的数据源,然后将C列中的值大于其两倍标准差的异常值进行清洗
    df = DataFrame(data=np.random.random(size=(1000,3)),columns=['A','B','C'])
    df.head()
    # 制定判定异常值的条件
    twice_std = df['C'].std() * 2   # 0.5809877730044463
    
    df.loc[~(df['C'] > twice_std)].head()
     

    级联操作

    • pd.concat, pd.append

    pandas使用pd.concat函数进行级联操作,与numpy中的np.concatenate函数类似,只是多了一些参数

    匹配级联

       行列索引都一致的级联叫做匹配级联

    df1 = pd.DataFrame(data=np.random.randint(0,100,size=(5,3)),columns=['A','B','C'])
    df2 = pd.DataFrame(data=np.random.randint(0,100,size=(5,3)),columns=['A','D','C'])
    
    pd.concat((df1,df1), axis=1)  # axis=0 轴向 列与列级联 , axis=1 横向级联 行和行级联

     不匹配级联

    • 不匹配指的是级联的维度的索引不一致。例如纵向级联时列索引不一致,横向级联时行索引不一致
    • 有2种连接方式:
      • 外连接 outer:补NaN(默认模式),如果想要保留数据的完整性必须使用outer(外连接)
      • 内连接 innter:只连接匹配的项
    pd.concat((df1,df2), axis=1)  # 横向级联,没有毛病
    
     
    # concat()中join参数默认是 outer, 会把不能匹配的补Nan
    pd.concat((df1,df2),axis=0)
    
     
    # inner 可以把能匹配的匹配,不能匹配的直接不要
    pd.concat((df1,df2), axis=0, join='inner')
     

     append函数的使用

      append函数只能轴向级联

    df1.append(df1)
    df1.append(df1)

    合并操作

    • merge与concat的区别在于,merge需要依据某一共同列来进行合并

    • 使用pd.merge()合并时,会自动根据两者相同column名称的那一列,作为key来进行合并。

    • 注意每一列元素的顺序不要求一致

    一对一合并

    df1 = DataFrame({'employee':['Bob','Jake','Lisa'],
                    'group':['Accounting','Engineering','Engineering'],
                    })
    
    
    df2 = DataFrame({'employee':['Lisa','Bob','Jake'],
                    'hire_date':[2004,2008,2012],
                    })
    
    
    pd.merge(df1, df2, on='employee') # 参数1:左表,参数2:右边,参数3:on合并条件

    一对多合并

    df3 = DataFrame({
        'employee':['Lisa','Jake'],
        'group':['Accounting','Engineering'],
        'hire_date':[2004,2016]})
    df4 = DataFrame({'group':['Accounting','Engineering','Engineering'],
                           'supervisor':['Carly','Guido','Steve']
                    })
    pd.merge(df3, df4)  # on如果不写,默认情况下使用两表中共有的列作为合并条件

    多对多合并

    df5 = DataFrame({'employee':['Bob','Jake','Lisa'],
                     'group':['Accounting','Engineering','Engineering']})
    
    
    df6 = DataFrame({'group':['Engineering','Engineering','HR'],
                    'supervisor':['Carly','Guido','Steve']
                    })
    
    
    pd.merge(df5, df6) # 不指定的话how默认是inner 只将能匹配的合并
    
     
    # 内合并与外合并:outer取并集 inner取交集
    pd.merge(df5, df6, how='inner') # inner是只将能匹配的合并
    
     
    pd.merge(df5, df6, how='outer') # outer是能匹配不能匹配的都合并
    
     
    pd.merge(df5, df6, how='right') # right右合并 保留右表数据
    
     
    pd.merge(df5, df6, how='left')  # left左合并 保留左表数据

    key的规范化(两张表没有可进行连接的列)

    • 当两张表没有可进行连接的列时,可使用left_on和right_on手动指定merge中左右两边的哪一列列作为连接的列
    df7 = DataFrame({'employee':['Bobs','Linda','Bill'],
                    'group':['Accounting','Product','Marketing'],
                   'hire_date':[1998,2017,2018]})
    df8 = DataFrame({'name':['Lisa','Bobs','Bill'],
                    'hire_dates':[1998,2016,2007]})
    pd.merge(df7, df8, left_on='employee', right_on='name')
  • 相关阅读:
    GridView使用技巧
    ilspy反编译
    Editplus php
    SQL 日期相减(间隔)datediff函数
    cmd创建文件命令
    iis7 bug解决
    删除qq互联
    discuz 数据库文件密码修改
    linux zip命令
    asp.net调用js方法
  • 原文地址:https://www.cnblogs.com/wgwg/p/13300813.html
Copyright © 2011-2022 走看看