美文网首页呆鸟的Python数据分析我爱编程Python学习
数据分析-pandas数据处理清洗常用总结

数据分析-pandas数据处理清洗常用总结

作者: 3e93a92f77da | 来源:发表于2018-04-12 18:28 被阅读774次

    利用pandas包进行数据分析时常见的操作有:

    • 1.创建对象
    • 2.查看对象
    • 3.选择
    • 4.缺失值处理
    • 5.相关操作
    • 6.合并
    • 7.分组和分段
    • 8.轴转换和数据透视表
    • 9.时间序列
    • 10.导入和保存数据

    一、创建对象

    • 创建Series
    • 创建DataFrame
    • 查看不同列的数据类型
    • 改变索引列名
      1.通过传递一个 list 对象来创建一个 Series
    s=pd.Series([1,2,3,np.nan,6,8])
    s
    

    2.通过传递一个 numpy array,时间索引以及列标签来创建一个 DataFrame
    numpy.random.randn()是从标准正态分布中返回一个或多个样本值。
    numpy.random.rand()的随机样本位于[0, 1)中。
    np.random.randint(0,7,size=10)生成0到7的随机整数
    dates=pd.date_range('20130101',periods=6)
    df=pd.DataFrame(np.random.randn(6,4),index=dates,columns=list('ABCD'))
    df
    

    index和columns也可以在DataFrame创建后指定:

    df.index=pd.date_range('20130101',periods=df.shape[0])
    df.index=pd.date_range('20130101',periods=len(df))
    

    另外,还可以指定某一列为索引

    df = df.set_index('A', drop = True)
    

    通过字典对象来创建一个 DataFrame

    df2=pd.DataFrame({'A':1.,
                     'B':pd.Timestamp('20130102'),
                     'C':pd.Series(1,index=list(range(4)),dtype='float32'),
                     'D':np.array([3]*4,dtype='float32'),
                     'E':pd.Categorical(['test','train','test','train']),
                     'F':'foo'})
    df2
    

    另外,在原有数据df的基础上,可以创建一个新的数据框df3

    df3=pd.dataframe()
    df3['min']=df.min()
    df3['max']=df.max()
    df3['std']=df.std()
    df3
    

    或者按行进行汇总统计创建一个新的数据框df4

    df4=pd.dataframe()
    df4['min']=df.min(axis=1)
    df4['max']=df.max(axis=1)
    df4['std']=df.std(axis=1)
    df4
    

    轴为0的时候是对列的数据进行统计运算,比如shape[0]是行的个数,相当于一个完整的列有多少数据,df.min(axis=0),求每一列的最小值。轴为1是对行的数据量进行统计。
    3.查看不同列的数据类型

    df2.dtypes
    

    4.改变索引列名

    df.rename(index=lambda x:x+5,columns={'A':'newA','B':'newB'})
    

    二、查看数据

    • 查看头尾的行数据
    • 显示索引、列、底层的数据
    • 统计
    • 转置
    • 按轴排序
    • 按值排序
    • 查看最大值的索引
    • 格式化输出format
      1.查看头尾的行数据
    df.head()
    
    df.tail(3)
    

    2.显示索引、列、底层的数据
    df.index
    df.columns
    df.values



    注意,list(df)显示的是columns
    3.统计
    查看数据框的行数与列数:(shape[0]是行数shape[1]是列数)
    df.shape
    

    查看数据框 (DataFrame) 的索引、数据类型及内存信息:

    df.info()
    

    统计每一列非空个数

    t.count()
    

    统计某列有多少个不同的类用.nunique()或者len(set()),(统计某列不同类对应的个数用value_counts(),后面相关操作中会提到)

    df.A..nunique()
    len(set(df.A))
    

    统计某列有哪些不同的类(使用value_counts()也可以显示,同时会显示各个类的个数)

    df.A.unique()
    

    统计某列是否有重复数据

    df.A.is_unique
    

    对于数据类型为数值型的列,查询其描述性统计的内容:

    df.describe()
    

    统计相关系数

    df.corr()
    

    4.转置

    df.T
    

    5.按轴排序
    df.sort_index(0) 按行名排序
    df.sort_index(1) 按列名排序

    df.sort_index(axis=1,ascending=False)
    

    6.按值排序
    按行的值排序:

    df.sort_values(by='20130101',axis=1)
    

    按列的值排序:

    df.sort_values(by='B')
    

    按顺序进行多列降序排序

    df.sort_values(['A','B'],ascending=False)
    

    7.查看最大值的索引

    df.idxmax(0)    #显示所有列最大值所对应的索引
    df.A.idxmax(0)   #显示A列中最大值对应的索引
    

    8.格式化输出format
    “格式限定符”(语法是'{}'中带:号),可以print相应格式的数据

    print('{:.2%}'.format(0.12354))
    

    金额千位分隔符

    print('{:,}'.format(123456789))
    
    print('{:.2f}'.format(31.31412))
    

    三、选择

    • 直接获取数据
    • 通过标签进行选择 .loc[]
    • 通过位置进行选择 .iloc[:,:]
    • 布尔索引
    • 设置赋值
      1.直接获取数据(用于获取整行或者整列的数据),此处注意列名一定要大小写对应,否则无法取出数据
    df['B']
    df.B
    

    选择两列

    df[['A','B']]
    

    通过切片获取数据

    df[0:3]
    df['20130101':'20130103']
    

    2.通过标签进行选择 .loc[]
    标签的优点是可以多轴交叉选择(注意:iloc内部只能单独使用行标签选择行数据,选择某一列标签时前面需加:,):

    df.loc[dates[0]]
    

    位置加标签(注意只能用:,不能使用类似0:2的切片):

    df.loc[:,['A','B']]
    

    标签加标签:

    df.loc['20130101',['A','B']]
    

    获取一个标量:

    df.loc['20130101','A']
    

    3.通过位置进行选择 .iloc[:,:]
    通过传递数值进行位置选择(选择的是行),特别是选择单行的时候(注意:iloc内部只有一个值得时候是选择的行,选择某一列时列号前面需加:,),另外-1代表最后一列:
    df.iloc[3]
    

    选取除了最后三列之外的数据

    df.lioc[:,:-3]
    

    通过数值进行切片 位置加位置(区别于loc之处)

    df.iloc[1:3,1:3]
    

    通过制定一个位置的列表:

    df.iloc[[1,2],[2,3]]
    

    对行、列进行切片:

    df.iloc[[0,1],:]
    df.iloc[:,[0,1]]
    


    获取特定的值:

    df.iloc[1,1]
    

    4.布尔索引
    使用一个单独列的值来选择数据:

    df[df.A>0]
    
    df[df>0]
    

    选择A列中以a开头的行或列(假设此处的A列是字符串型数据)

    df[df.A.str.startswith('a')]
    

    使用 isin()方法来过滤:

    df['E']=['one','one','two','there','four','there']
    df[df.E.isin(['two','four'])]
    

    5.赋值
    ①通过标签设置新的值

    df.loc['20130101','A']=1
    df
    

    如果赋值的标签不存在,则产生新的列(行),未赋值的位置用空值填充

    t.loc['20130101','H']=3
    t
    

    ②通过位置设置新的值

    df.iloc[0,0]=2
    df
    

    ③设置整列值(len可以求表格数据的行数):

    df.loc[:,'D']=np.array([3]*len(df))
    df
    

    或者

    df['D']=np.array([3]*len(df))
    df
    

    ④通过布尔索引赋值

    df2=df.copy()
    df2[df2>0]=-df2
    df2     #全部转化为负数
    

    四、缺失值处理

    • 删除列的方法
    • 去掉包含缺失值的行,不改变原来的值
    • 对缺失值进行填充
    • 对数据进行布尔填充



      查看每一列有多少缺失值:

    df.isnull().sum()
    

    查看每一列有多少完整的数据

    df.shape[0]-df.isnull().sum()
    

    1.删除列的方法:

    df.drop(df.columns[4],axis=1,inplace=True)  #不知道列名时
    df.drop(‘E’,axis=1,inplace=True)   #根据列名删除
    

    del df['E']
    

    2.去掉包含缺失值的行,不改变原来的值

    df.dropna()   #不返回df还是原值
    df.dropna(how='all')   #删除所有均为空值的行
    df.dropna(inplace=True)   #返回删除后的
    

    移除数据框 DataFrame 中包含空值的列

    df.dropna(axis=1)
    

    3.对缺失值进行填充(如果填充后需要保存,需加inplace=True):

    df.fillna(value=5)
    

    将所有空值替换为平均值

    df.fillna(df.mean())
    

    4.对数据进行布尔填充

    pd.isnull(df)
    

    五、相关操作

    • 统计行列平均值
    • Apply – 对数据应用函数
    • 计数 value_counts()
    • 字符串大小写转换
    • 数据类型转换
    • 替换
      1.统计行列平均值
      按列统计平均
    df.mean()
    

    对平均值取整

    round(df.mean())
    

    按行统计平均

    df.mean(1)
    

    2.Apply – 对数据应用函数
    其中注意临时函数lambda的使用
    df.apply(lambda x:x.max()-x.min())
    
    df.apply(np.mean)   按行统计axis=1
    
    df.apply(np.max,axis=1)
    

    另外可以通过def 定义函数,再使用apply,例如下面数据的第一列,时间为2061年,存在明显错误,可以通过创建函数去修复这个错误

    data = pd.read_table(path6, sep = "\s+", parse_dates = [[0,1,2]]) 
    data.head()
    
    import datetime
    def fix_century(x):
        year = x.year - 100 if x.year > 1989 else x.year
        return datetime.date(year, x.month, x.day)
    data['Yr_Mo_Dy'] = data['Yr_Mo_Dy'].apply(fix_century)
    data.head()
    

    3.计数 value_counts()

    s=pd.Series(np.random.randint(0,7,size=10))
    s.value_counts()
    

    DataFrame查看某一列类别数据各类的个数:

    df2.E.value_counts()
    

    DataFrame查看所有列的各类统计个数

    df2.apply(pd.Series.value_counts)
    

    4.字符串大小写转换

    s=pd.Series(['One','Two'])
    s.str.lower()
    

    5.将DataFrame的格式转化为浮点数

    df.astype(float)
    

    6.替换

    df.replace(4,'one')
    

    六、合并

    • concat (不通过键值之间的连接)
    • merge 类似于 SQL 类型的连接( join)☆
    • Append ---- 类似于 SQL 中 union
      1.concat (默认上下连接,axis=1时左右连接)
    df=pd.DataFrame(np.random.randn(10,4))
    df
    
    pieces=[df[:1],df[6:7]]
    pd.concat(pieces)
    

    2.merge 类似于 SQL 类型的连接( join)
    根据连接
    merge与concat的区别在于,merge需要依据某一共同的行或列来进行合并
    left=pd.DataFrame({'key':['foo','foo1'],
                      'lval':[1,2]})
    left
    
    right=pd.DataFrame({'key':['foo','foo2'],
                      'rval':[4,5]})
    right
    
    pd.merge(left,right,on='key')
    

    左连接left,右连接right,外连接outer 默认是inner

    pd.merge(left,right,on='key',how='left')
    

    3.Append 将一行连接到一个 DataFrame 上
    专门用于上下按照同列名连接---- 类似于 SQL 中 union
    append是concat的简略形式,只不过只能在axis=0上进行合并

    df=pd.DataFrame(np.random.randn(5,4),columns=list('ABCD'))
    df
    
    s=df.iloc[1,:]
    df.append(s,ignore_index=True)
    

    七、分组和分段

    • 分组(对数据进行分组汇总统计,类似数据透视表)
    • 通过多个列进行分组形成一个层次索引
    • 分段(对数据进行分段或者分箱切割,可用于连续变量的特征处理,例如woe)
    df=pd.DataFrame({'A':['foo','bar','foo','bar','foo','bar','foo','bar'],
                    'B':['one','two','three','four','two','two','one','three'],
                    'C':np.random.randn(8),
                    'D':np.random.randn(8)})
    df
    

    1.分组,并对每个分组执行 sum/count/mean/median(中位数)等函数

    df.groupby('A').sum()
    df.groupby('A').agg(np.sum)
    df.groupby('A').agg({'C':sum,'D':sum})
    

    分组求平均值、最大值、最小值

    df.groupby('A').C.agg(['mean','max','min'])
    

    按A中类的个数对C求平均值

    df.groupby('A').agg({'C':sum})['C'].mean()
    

    2.通过多个列进行分组形成一个层次索引

    df.groupby(['A','B']).sum()
    

    3.分段(分箱)
    有两种:pd.qcut与pd.cut
    按变量取值范围进行均匀分割cut

    cut11=pd.cut(df1["可用额度比值"],4)
    cut11.head()
    

    按变量个数进行均匀分割qcut

    cut11=pd.qcut(df1["可用额度比值"],4)
    cut11
    
    cut11=pd.qcut(df1["可用额度比值"],4,labels=False)
    cut11.head()
    

    八、轴转换和数据透视表

    • Stack堆栈
    • 数据透视表
      1.Stack堆栈
    tuples=list(zip(*[['bar','bar','baz','baz','foo','foo','qux','qux'],['one','two','one','two','one','two','one','two']]))
    index=pd.MultiIndex.from_tuples(tuples,names=['first','ssecond'])
    df=pd.DataFrame(np.random.randn(8,2),index=index,columns=['A','B'])
    df
    
    stacked=df.stack()
    stacked
    
    stacked2=stacked.unstack()
    stacked2
    
    stacked3=stacked2=stacked.unstack(0)
    stacked3
    
    stacked4=stacked2=stacked.unstack(1)
    stacked4
    

    2.数据透视表
    pd.pivot_table()
    df=pd.DataFrame({'A':['one','one','two','three']*3,
                    'B':['A','B','C']*4,
                    'C':['foo','foo','foo','bar','bar','bar']*2,
                    'D':np.random.randn(12),
                    'E':np.random.randn(12)})
    df
    
    pd.pivot_table(df,values='D',index=['A','B'],columns='C')
    
    df.pivot_table(df,index=['A','B'],columns=['C'],aggfunc=np.sum)
    

    九、时间序列

    • 针对时间频率重采样
    • 时间类型转换
    • 时间采样分组
    • 时间筛选问题
      1.针对时间频率重采样
      首先创建一个采样后的时间序列:
    rng=pd.date_range('20120101',periods=61,freq='S')
    rng
    

    序列或者索引为时间时,可以使用.resample()重置采样频率
    ts=pd.Series(np.random.randint(0,500,len(rng)),index=rng)
    ts.resample('1Min',how=sum)
    

    另外采样频率还有:
    W weekly frequency
    M 每月最后一天
    BM 每个月最后一个工作日
    2.将int64型数据转化成datetime数据

    crime.info()
    crime.head()
    
    crime.Year = pd.to_datetime(crime.Year, format='%Y')
    crime.info()
    crime.head()
    


    3.按时间采样结果分组
    例如我们获得一组数据索引是每一年



    按如果想按十年进行分组查看数据情况,即进行时间分组求和,可以使用重采样
    crimes = crime.resample('10AS').sum()
    

    另外,人口不能按十年的直接相加,使用10年内的最大值汇总,在上述基础上更新population列

    population = crime['Population'].resample('10AS').max()
    crimes['Population'] = population
    

    4.时间筛选问题
    通过创建时间分列字段,进行取样统计计算,此方法优点是配合query可以实现灵活取样
    例如,如下,计算每一列一月份的平均值



    可以先将时间字段分列,相当于创建了辅助列

    data['date'] = data.index
    data['month'] = data['date'].apply(lambda date: date.month)
    data['year'] = data['date'].apply(lambda date: date.year)
    data['day'] = data['date'].apply(lambda date: date.day)
    data.head()
    

    再筛选计算

    january_winds = data.query('month == 1')
    january_winds.loc[:,'RPT':"MAL"].mean()
    

    按年进行取样

    data.query('month == 1 and day == 1')
    

    按月取样

    data.query('day == 1')
    

    时间差,两个日期之间可以相减,并求对应月数和天数

    (data.max() - data.min()).days
    

    十、导入和保存数据

    • CSV
    • Excel
      1.导出
    df.to_csv('foo.csv')
    df.to_excel('foo.xlsx')
    df.to_sql(table_name,connection_object) # 将数据框 (DataFrame)中的数据导入SQL数据表/数据库中
    df.to_json(filename) # 将数据框 (DataFrame)中的数据导入JSON格式的文件中
    

    2.导入:

    pd.read_csv('foo.csv')
    pd.read_excel('foo.xlsx')
    pd.read_sql(query, connection_object) # 导入SQL数据表/数据库中的数据
    pd.read_json(json_string) # 导入JSON格式的字符,URL地址或者文件中的数据
    

    另外一种常用导入方式

    path3 ='../input/pandas_exercise/exercise_data/drinks.csv'    #'drinks.csv'
    drinks = pd.read_csv(path3)
    

    3.文件导入参数
    在读取文件时考虑到格式问题,会使用一些参数进行调整。
    参考:https://www.cnblogs.com/datablog/p/6127000.html

    sep指定分隔符。如果不指定参数,则会尝试使用逗号分隔。
    其中,会用到正则表达式,可以参考:https://baike.baidu.com/item/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/1700215?fr=aladdin
    \s ->匹配任何空白字符,包括空格、制表符、换页符等
    \f -> 匹配一个换页
    \n -> 匹配一个换行符
    \r -> 匹配一个回车符
    \t -> 匹配一个制表符
    \v -> 匹配一个垂直制表符
    +->匹配前面的子表达式一次或多次(大于等于1次)。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。
    “\s+”则表示匹配任意多个上面的字符。

    data = pd.read_table(path6,sep = '\s+') 
    data.head()
    

    parse_dates 可以将指定的列转化为时间
    data = pd.read_table(path6, sep = "\s+", parse_dates = [[0,1,2]]) 
    data.head()
    

    相关文章

      网友评论

        本文标题:数据分析-pandas数据处理清洗常用总结

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