数据分析基础pandas八大常用知识点汇总

讨论 伪硬核玩家
Lv2 初级炼丹师
发布在 Pandas   1277   0
讨论 伪硬核玩家   1277   0

    目录

    1. 数据结构简介

    1.1 Series的创建

    1.2 DataFrame的创建

    2. 数据索引index

    2.1 通过索引值或索引标签获取数据

    2.2 自动化对齐

    3. 利用pandas查询数据

    4. 利用pandas的DataFrames进行统计分析

    5. 利用pandas实现SQL操作

    6. 利用pandas进行缺失值的处理

    7. 利用pandas实现Excel的数据透视表功能

    8. 多层索引的使用

    【此文旨在个人学习过程中知识点回顾,希望对大家也有帮助】

    B站同步视频bilibili.com/video/av63245020

    一、数据结构介绍

    在pandas中有两类非常重要的数据结构,即序列Series和数据框DataFrame。Series类似于numpy中的一维数组,除了通用一维数组的函数和方法,而且可通过索引标签的方式获取数据,还具有索引的自动对齐功能;DataFrame类似于numpy中的二维数组,同样可以通用numpy数组的函数和方法,且具有其他应用后续详聊。

    1.1Series的创建

    序列的创建有其他三种方式:

    1)通过一维数组创建序列

    import numpy as np
    import pandas as pd
    
    a = np.arange(10)
    print(a, type(a))
    a1 = pd.Series(a) #利用a得到的一维数组直接创建序列
    print(a1, type(a1))
    #自行运行观察结果

    2)通过字典方式创建序列

    a = {'a':10,'b':20,'c':30,'d':40,'e':50}
    print(a, type(a))
    a_Series = pd.Series(a)
    print(a_Series, type(a_Series))
    #自行运行观察结果

    3)通过DataFrame中的某一行或某一列创建

    此方法不展开,详细可百度

    1.2DataFrame数据框的创建——三种方法

    1)通过二维数组是创建

    a = np.arange(np.arange(12)).reshape(3, 4)
    print(a, type(a))
    df1 = pd.DataFrame(a)
    print(df1, type(df1))
    #自行运行观察结果

    2)通过字典方式创建

    #字典列表方式
    dic2 = {'a':[1,2,3,4],'b':[5,6,7,8],'c':[9,10,11,12],'d':[13,14,15,16]}
    print(dic2)
    print(type(dic2))
    df2 = pd.DataFrame(dic2) ## 创建方式
    print(df2)
    print(type(df2))
    #嵌套字典方式
    dic3 = {'one':{'a':1,'b':2,'c':3,'d':4},'two':{'a':5,'b':6,'c':7,'d':8},'three':{'a':9,'b':10,'c':11,'d':12}}
    print(dic3)
    print(type(dic3))
    df3 = pd.DataFrame(dic3)
    print(df3)
    print(type(df3))
    #自行运行观察结果

    3)通过数据框的方式创建数据框

    df4 = df3[['one','three']]
    print(df4, type(df4))
    s3 = df3['one']
    print(s3, type(s3))

    二、数据索引丨index

    细致的朋友可能会发现一个现象,无论序列、数据框,对象的左边总有一个非原始数据对象,这就是索引。序列或数据框的索引有两大用处,一个事通过索引值或索引标签获取数据,另一个是通过索引,可以使序列或数据框的数据自动化对齐。

    2.1通过索引或索引标签获取数据

    s4 = pd.Series(np.array([1,1,2,3,5,8]))
    print(s4)

    如果不给序列一个指定的索引值,则序列自动生成一个从0开始的自增索引。可以通过index查看索引。

    print(s4.index)

    创建自定义索引值:

    s4.index = ['a','b','c','d','e','f']
    print(s4)

    数据有了索引值或索引标签就可以利用后去数据:

    print('s4[3]:',s4[3])
    print('s4[e]:',s4['e'])
    print('s4[1,3,5]:',s4[[1,3,5]])
    print("s4[['a','b','d','f']]:",s4[['a','b','d','f']])
    print('s4[:4]:',s4[:4])
    print("s4['c':]:",s4['c':])
    print("s4['b':'e']:",s4['b':'e'])
    #自行操作观察结果

    千万注意:如果通过索引标签获取数据的话,末端标签所对应的值是可以返回的!在一维数组中就无法通过标签获取数据,这也是序列不同于一维数组的一个方面。

    2.2自动化对齐

    若有两个序列,对其进行算数运算,这是索引就体现了价值——自动化对其。

    s5 = pd.Series(np.array([10,15,20,30,55,80]),index = ['a','b','c','d','e','f'])
    print(s5)
    
    s6 = pd.Series(np.array([12,11,13,15,14,16]),index = ['a','c','g','b','d','f'])
    print(s6)
    print(s5+s6)
    print(s5/s6)

    由于s5、s6中存在非对应索引,故结果存在NaN。注意,这里的算数结果就实现了序列索引的自动对齐。对于数据框不仅自动对齐行,也会自动对齐列(变量名)。

    数据框中同样存在索引,且数据框是二维数据组的推广,故其不仅有行索引又有列索引,关于数据框中的索引要比序列强大很多。

    三、利用pandas 查询数据

    这里的查询数据相当于R语言的subset功能,可以通过布尔索引有针对的选取元数据的子集、指定行&列等。

    import pandas as ps
    
    stu_dic = {'Age':[14,13,13,14,14,12,12,15,13,12,11,14,12,15,16,12,15,11,15],
    'Height':[69,56.5,65.3,62.8,63.5,57.3,59.8,62.5,62.5,59,51.3,64.3,56.3,66.5,72,64.8,67,57.5,66.5],
    'Name':['Alfred','Alice','Barbara','Carol','Henry','James','Jane','Janet','Jeffrey','John','Joyce','Judy','Louise','Marry','Philip','Robert','Ronald','Thomas','Willam'],
    'Sex':['M','F','F','F','M','M','F','F','M','M','F','F','F','F','M','M','M','M','M'],
    'Weight':[112.5,84,98,102.5,102.5,83,84.5,112.5,84,99.5,50.5,90,77,112,150,128,133,85,112]}
    student = pd.DataFrame(stu_dic) #导入数据创建数据框
    
    print(student.head()) #查询数据前5列
    print(student.tail()) #查询数据后5列(默认)

    查询指定行

    print(student.loc[[0,2,4,5,7]]) #这里的loc索引标签函数必须是中括号[]

    查询指定列

    print(student[['Name','Height','Weight']].head()) #如果多个列的话,必须使用双重中括号[]
    #方法2
    print(student.loc[:,['Name','Height','Weight']].head())

    查询12岁以上的女生信息

    student[(条件1) & (条件2)]

    print(student[(student['Sex']=='F') & (student['Age']>12)])

    自己写出下面这条需求

    查询出所有12岁以上女生姓名、身高和体重?

    student[(student['Sex']=='F') & (student['Age']>12)][['Name','Height','Weight']]

    注意:如果是多个条件的查询,必须使用&(and)或者丨(or)的两端条件用括号括起来。

    四、利用pandas 的DataFrame进行统计分析

    np.random.seed(1234)
    d1 = pd.Series(2*np.random.normal(size = 100)+3)
    d2 = np.random.f(2,4,size = 100)
    d3 = np.random.randint(1,100,size = 100)
    
    print('非空元素计算: ', d1.count()) #非空元素计算
    print('最小值: ', d1.min()) #最小值
    print('最大值: ', d1.max()) #最大值
    print('最小值的位置: ', d1.idxmin()) #最小值的位置,类似于R中的which.min函数
    print('最大值的位置: ', d1.idxmax()) #最大值的位置,类似于R中的which.max函数
    print('10%分位数: ', d1.quantile(0.1)) #10%分位数
    print('求和: ', d1.sum()) #求和
    print('均值: ', d1.mean()) #均值
    print('中位数: ', d1.median()) #中位数
    print('众数: ', d1.mode()) #众数
    print('方差: ', d1.var()) #方差
    print('标准差: ', d1.std()) #标准差
    print('平均绝对偏差: ', d1.mad()) #平均绝对偏差
    print('偏度: ', d1.skew()) #偏度
    print('峰度: ', d1.kurt()) #峰度
    print('描述性统计指标: ', d1.describe()) #一次性输出多个描述性统计指标
    ########## 自行操作观察结果,加深记忆  ###############

    必须注意的是,descirbe方法只能针对序列或数据框,一维数组是没有这个方法的

    定义一个函数将描述性统计指标汇总到一起:

    def stats(x):
        return pd.Series([x.count(),x.min(),x.idxmin(),x.quantile(.25),x.median(),x.quantile(.75),
                          x.mean(),x.max(),x.idxmax(),x.mad(),x.var(),x.std(),x.skew(),x.kurt()],
                         index = ['Count','Min','Whicn_Min','Q1','Median','Q3','Mean','Max',
                                  'Which_Max','Mad','Var','Std','Skew','Kurt'])
    print(stats(d1))

    在实际工作中,可能处理一些数据型数据框,将函数应用到数据框中的每一列,可以使用apply函数,将之前创建的d1\d2\d3数据构建为数据框:

    df = pd.DataFrame(np.array([d1,d2,d3]).T,columns  = ['x1','x2','x3']) #.T进行转置
    print(df.head())
    print(df.apply(stats))
    #输出效果很神奇

    对于离散型数据,需要统计离散变量的观测数、唯一值个数、众数水平及个数。使用descirbe方法便可实现:

    print(student['Sex'].describe())

    count 19 unique 2 top M freq 10 Name: Sex, dtype: object

    连续变量的相关系数(corr)和协方差矩阵(cov)的求解

    print(df.corr())
    
    print(df.corr('spearman'))
    #关于相关系数的计算可以调用pearson方法或kendell方法或spearman方法,默认使用pearson方法。

    如果只想关注某一个变量与其余变量的相关系数的话,可以使用corrwith,如下方只关心x1与其余变量的相关系数:

    print(df.corrwith(df['x1']))

    数值型变量间的协方差矩阵

    print(df.cov())

    五、利用pandas实现SQL操作

    增删改查!!!

    #创建新数据框student2
    dic = {'Name':['LiuShunxiang','Zhangshan'],'Sex':['M','F'],'Age':[27,23],'Height':[165.7,167.2],'Weight':[61,63]}
    student2 = pd.DataFrame(dic)
    print(student2)

    增:添加新行或新列

    将student2中的数据新增到student中,通过concat函数实现:

    student3 = pd.concat([student, student2])
    print(student3)

    在数据库中union必须要求两张表的顺序一致,而这里concat函数可以自动对齐两个数据框数据。

    新增列:

    print(pd.DataFrame(student2, columns = ['Age','Height','Name','Sex','Weight','Score']))

    新增的列没有赋值,则会NaN。

    删:删除表、观测行和变量列

    del student2 #直接删除
    print(student.drop([0,1,3,6])) # 删除指定行
    print(student[student['Age']>14])  #删除满足Age中大于14的数据行
    print(student.drop(['Height','Weight'],axis=1).head()) #删除指定列

    发现不论是删除列还是行,都可以通过drop方法实现,只需要设定好删除的轴即可,即调整drop方法中的阿西斯参数。默认该参数为0,表示删除行观测,参数1表示删除列变量。

    改:修改原始记录的值

    例如发现student3中姓名为LiuShunxiang的学生身高错了,应该是173,如何改?

    student3.loc[syudent3['Name'] == 'LiuShuanxiang','Height'] = 173
    print(student3)
    
    print(syudent3[syudent3['Name'] == 'LiuShunxiang'][['Name','Height']]) # 仅获取指定索引的某一数据

    查:有关数据查询部分,上面已经介绍过了

    重点来了

    聚合:pandas模块中可以通过groupby()函数实现数据的聚合操作

    根据性别分组,计算各组别中学生身高he体重的均值:

    print(student.groupby('Sex').mean())

    如果不对源数据做限制的话,聚合数据会自动选择数值型数据进行聚合计算。如果不想对年龄计算平均值的话就需要剔除改变量:

    print(student.drop('Age',axis=1).groupby('Sex').mean())

    groupby还可以使用多个分组变量,例如根据年龄和性别分组,计算身高和体重的平均值:

    print(student.groupby(['Age','Sex']).std()) #注意这里的中括号

    当然也可以对每个分组进行多个统计量计算:

    print(student.drop('Age',axis=1).groupby('Sex').agg([np.mean,np.median]))

    排序:

    排序在日常工作中使用较多,可以通过sort_index 和 sort_values实现对序列和数据框的排序工作:

    Data = pd.Series(np.array(np.random.randint(1,20,10)))
    print(Data)
    print(Data.sort_index())
    print(Data.sort_values(ascending=False))  #False为降序,True 为升序

    在数据框中一般都是按值排序:

    print(student.sort_values(by = ['Age','Height']))

    多表链接:

    多表连接是非常常见的数据库操作,连接分内链接和外连接,在数据库中通过join关键字实现,pandas我比较建议使用merge函数实现数据的各种连接操作。如下构造一张学生的成绩表:

    dic2 = {'Name':['Alfred','Alice','Barbara','Carol','Henry','Jeffrey','Judy','Philip','Robert','Willam'],
            'Score':[88,76,89,67,79,90,92,86,73,77]}
    score = pd.DataFrame(dic2)
    print(score)

    将student与score进行关联:

    stu_score1 = pd.merge(student, score,on = 'Name')
    print(stu_score1)

    注意:merge函数默认情况下实现两个表的内连接,即返回两张表中共有部分。通过how参数设置连接方式,left为左连接,right为右连接,outer为外连接。

    stu_score3 = pd.merge(student, score, on = 'Name', how = 'left')
    print(stu_score3)

    左连接实现的是保留student中的数据,将score与之匹配,能匹配多少算多少,匹配不上的显示NaN。


    六、利用pandas进行缺失值处理

    常用三种方法,删除法,填补法,插值法。

    删除法:当数据中某个变量大部分都是缺失值,可以考虑将其删除;当缺失值是随机分布的,且缺失值并不是很多,可以选择删除这些缺失值的观测。

    替补法:对于连续型变量,若变量的分布近似或就是正态分布的话,可以用均值替代那些缺失值‘如果变量是有偏的,可以使用中位数来替代,对于离散型数据一般使用众数来替换缺失的观测。

    插补法:插补法基于蒙特卡洛模拟法,结合线性模型、广义线性模型和决策树等方法计算出来的预测值替换缺失值。

    简单的删除法和替补法:

    s = stu_score3['Score']
    print(s)

    上面显示的是一组含有缺失值的序列,结合sum和isnull函数来检测数据中含有多少缺失值:

    print(sum(pd.isnull(s)))  #显示9个

    直接删除缺失值:

    print(s.dropna())

    默认dropna会删除含有缺失值的行,试一下:

    df = pd.DataFrame([[1,1,2],[3,5,np.nan],[13,21,34],[55,np.nan,10],[np.nan,np.nan,np.nan],[np.nan,1,2]],columns=('x1','x2','x3'))
    print(df)
    print(df.dropna())

    返回结果表明,数据中只要含有NaN,该行就会被删掉。若使用参数how='all',则表明只删除所有行为缺失值的观测;使用一个常量填补缺失值,可以使用fillna实现简单的填补:

    1)用0填补所有缺失值

    print(df.fillna(0))

    2)采用前项、后项填补

    print(df.fillna(method='ffill'))
    print(df.fillna(method='bfill'))
    #如果前项或后项无值,则继续NaN

    3)使用常量填补不同的列

    print(df.fillna({'x1':1,'x2':2,'x3':3})) # 注意使用{ }

    很显然使用各项的median、mode、mean填充更加合理一点。

    七、利用pandas实现Excel的数据透视表功能

    pivo_table(data, values=None,
               index = None,
               columns = None,
               aggfunc = 'mean',
               fill_values = None,
               margins = False,
               dropna = True,
               margind_name = 'All')

    data:需要进行数据透视操作的数据框

    values:指定需要聚合的字段

    index:制定某些原始变量作为行索引

    columns:指定那些离散的分组变量

    aggfunc:指定相应的聚合函数

    margins:是否进行行列的汇总,默认不汇总

    dropna:某人所有观测为确实的列

    margins_name:默认行汇总和列汇总的名称为All

    利用pivot_table函数的用法:对一组变量(Sex),一个数据变量(Height)进行统计汇总

    Table1 = pd.pivot_table(student, values=['Height'], columns=['Sex'])
    print(Table1)

    对一个分组变量(Sex),两个数值变量(Height,Weight)进行统计汇总

    Table2 = pd.pivot_table(student, values=['Height','Weight'], columns=['Sex'])
    print(Table2)

    对两个分组变量(Sex,Age),两个数值变量(Height,Weight)进行汇总

    Table3 = pd.pivot_table(student, values=['Height','Weight'],columns=['Sex','Age'])
    print(Table3) #打印出来可能不太好看,可以进行非堆叠操作
    Table3 = pd.pivot_table(student, values=['Height','Weight'],columns=['Sex','Age']).unstack()
    print(Table3)

    使用多个聚合函数

    Table5 = pd.pivot_table(student, values=['Height','Weight'],columns=['Sex'],aggfunc=[np.mean,np.median,np.std])
    print(Table5)

    有关更多数据透视表的操作,可参考《Pandas透视表(pivot_table)详解》一文,链接地址:http://python.jobbole.com/81212/ (链接时灵时不灵)

    八、多层索引的使用

    最后我们再来讲讲pandas中的一个重要功能,那就是多层索引。在序列中它可以实现在一个轴上拥有多个索引,就类似于Excel中常见的这种形式:

    pandas可以帮我们实现用低维度形式处理高维数数据,这里举个例子:

    #Series的层次化索引,索引是一个二维数组,相当于两个索引决定一个值
    #有点类似于DataFrame的行索引和列索引
    s = pd.Series(np.arange(1,10),index=[["a","a","a","b","b","c","c","d","d"],[1,2,3,1,2,3,1,2,3]])
    print(s)
    print(s.index)

    索引操作

    #选取外层索引为a的数据
    print(s['a'])
    #选取外层索引为a和内层索引为1的数据
    print(s['a'],1)
    #选取外层索引为a和内层索引为1,3的数据
    print(s['a'][[1,3]])
    #层次化索引的切片,包括右端的额索引
    print(s[['a','c']])
    print(s['b':'d'])
    #通过unstack方法可以讲Series变成一个DataFrame
    #数据类型和数据的输出结构都变成了DataFrame,对于不存在的部分使用NaN填充
    print(s.unstack())
    
    ###  自行原型观察结果 ###  只看学不会,关键还是练

    DataFrame的层次化索引

    #创建新的DataFrame
    data = pd.DataFrame(np.random.randint(0,150,size=(8,12)),
                   columns = pd.MultiIndex.from_product([['模拟考','正式考'],
                                                       ['数学','语文','英语','物理','化学','生物']]),
                   index = pd.MultiIndex.from_product([['期中','期末'],
                                                       ['雷军','李斌'],
                                                      ['测试一','测试二']]))
    data  # 观察data

    索引操作

    data['模拟考'][['语文','数学']]
    
    ####
    
    print(data.loc['期中','雷军','测试一']['模拟考','数学'])
    print(data.loc['期中','雷军','测试一'])
    print(data.iloc[0])  #结果与上边的一样
    #
    data['正式考']
    
    

    掌握了pandas这8个主要的应用方法就可以灵活的解决很多工作中的数据处理、统计分析等任务。

    最近准备将我之前写的数据分析报告,数据源,以及python分析源代码整理发布到Pandas中文社区。此外还将在bilibili将操作的数据分析项目用视频的方式讲解出来,一方面加深自己的记忆提高熟练度,另一方面个希望对大家也有帮助。

    有关更多的pandas介绍,可参考Pandas中文文档

    版权声明:作者保留权利,不代表意本站立场。如需转载请联系本站以及作者。

    参与讨论

    回复《 数据分析基础pandas八大常用知识点汇总

    EditorJs 编辑器

    沙发,很寂寞~
    反馈
    to-top--btn