• 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')
  • 相关阅读:
    sfs2x 连接 mongodb
    java websocket
    webstorm 4.0 注册码
    解决 sfs2 admin tool 找不到扩展
    window 注册表五大类
    opengl 学习第二日
    java google Protobuf
    扩展 java sencha touch PhonegapPlugin
    sencha touch2 kryonet socket phonegap 通信 作者:围城
    sencha touch2 layout 笔记
  • 原文地址:https://www.cnblogs.com/wgwg/p/13300813.html
Copyright © 2020-2023  润新知