• 强大的数据分析工具——Pandas操作、易错点、知识点三万字详解


    一、 Pandas数据结构

    1.Series
    2.DataFrame
    3.从DataFrame中查询出Series

    DataFrame: 二维数据、整个表格、多行多列

    9262c6a37f2c4dfc9ff211e99d6767c0.png

    Series:一维数据,一行或者一列 

    a8e26ded8b4d484f9a12cfd8891c7288.png

    1. import pandas as pd
    2. import numpy as np

     

    1、Series

    Series是一种类似于一维数组的对象,它由一组数据〈不同数据类型)以及一组与之相关的数据标签(即索引)组成。

    1.1仅有数据列表即可产生最简单的Series

    左侧为索引,右侧为数据

    1. s1=pd.Series([1,'x',5.7,7])
    2. #左侧为索引,右侧为数据
    3. s1

    获取索引
    s1.index

    1. 获取索引
    2. s1.index

    获取数据
    s1.values

    1. #获取数据
    2. s1.values

    bb96f75758ae47069df2684fca9e4379.png

    1.2创建一个具有标签索引的Series 

    1. s2=pd.Series([1,'x',5.7,7],index=['d','b','a','c'])
    2. s2
    3. s2.index

    105cd540c4ef42f0ad1090dca21b268a.png

    1.3使用python字典创建Series

    python字典和seires有着密不可分的关系

    1. sdata={'apple':35,'tex':40,'bananan':20,'pearl':30}
    2. s3=pd.Series(sdata)
    3. s3

     fe15888a39b7492faff9dec582f76266.png

    1.4根据标签索引查询数据

    ----类似pthon的字典dict

    1. s2
    2. s2['a']

     查一个数据得到是python原生的数据类型

    1. #查一个数据得到是python原生的数据类型
    2. type(s2['a'])
    3. s2[['b','a']]

    查询Series的类型  type(s2[['b','a']])

    1. #查询Series的类型
    2. type(s2[['b','a']])

    dbf8eb4a1fad4698a352c09a8ea223e8.png

    2.DataFrame

    DataFrame是一个表格型的数据结构

    ①每列可以是不同的值类型(数值、字符串、布尔值等)
    ②既有行索引index,也有列索引columns
    ③可以被看做由Series组成的字典
    ④创建dataframe最常用的方法,见读取纯文本文件、excel、mysql数据库

     

    2.1根据多个字典序列创建dataframe

    列表中每个值的个数都必须相同

    1. #列表中每个值都必须相同
    2. data={
    3. 'state':['apple','tex','txt','banana','cxv'],
    4. 'year':[2000,1999,1998,1997,1996],
    5. 'pop':[1.1,1.2,1.3,1.4,1.5]
    6. }
    7. df=pd.DataFrame(data)
    8. df
    1. df.dtypes
    2. df.columns
    3. df.index

    6450cab34ec3408d8d0e7cdd60d3757e.png

     3.从DataFrame中查询出Series

        如果只查询一列,一行,返回的是pd.Series
        如果查询多行、多列,返回的是pd.DataFrame

    df

    4144a47a58df4c0cbf130557e36b7ade.png

    3.1查询一列,结果是一个pd.Series 

    1. df['state']
    2. type(df['year'])

    d483b9e6e28b44719c268a5024ce4d0c.png

    3.2查询多列,结果是一个pd.DataFrame 

    1. df[['pop','year']]
    2. type(df[['pop','year']])

    3368e20e76b249ba8448d594d28ba14c.png

    3.3查询一行,结果是一个pd.Series 

    loc(1)代表查询一行

    1. df.loc[1]
    2. type(df.loc[1])

    3.4查询多行,结果是一个pd.DataFrame

    列表中切片的操作方法去取,但是在Pandas中包括末尾元素

    1. #列表中切片的操作方法去取,但是在Pandas中包括末尾元素
    2. df.loc[1:3]
    3. type(df.loc[1:3])

    7afd28dc54bb40e4ad8cf8bc1bb69ecb.png

     总结:
    60843b869a5748c7aebe7b09b1a1463a.png

    81ae818f42484eaba3f9fd2a2ed20253.png

     

    二、Pandas数据读取

            f269be97029c403abea506fad63c1e87.png

            1. pandas读取纯文本文件
            ·读取csv文件
            ·读取csv文件
            2. pandas读取xlsx格式excel文件
            3. pandas读取mysql数据表 

    1、读取纯文本文件

    1.1读取CSV,使用默认的标题行、逗号分隔符

    1. import pandas as pd
    2. fpath="./datas/ml-latest-small/ratings.csv"
    3. #注意是反斜杠/,不然会报错

    注意:地址中是反斜杠/,不然会报错

    使用pd.read_csv读取数据

    ratings=pd.read_csv(fpath)

    查看前几行的数据
    ratings.head()

    1. #查看前几行的数据
    2. ratings.head()

    e6f8ae0996b5458ba80c095e1e5bb617.png

     

    查看数据的形状,返回(行数,列数)ratings.shape

    1. #查看数据的形状,返回(行数,列数)
    2. ratings.shape

    查看列名列表
    ratings.columns

    1. #查看列名列表
    2. ratings.columns

    查看索引列
    ratings.index

    1. #查看索引列
    2. ratings.index

    查看每列的数据类型
    ratings.dtypes

    1. #查看每列的数据类型
    2. ratings.dtypes

    8d3ecafa96a145a8b0df37fad68661ef.png

    1.2 读取txt文件,自己指定分隔符、列名 

    fpath2='./datas/crazyant/access_pvuv.txt'
    1. pvuv2=pd.read_csv(
    2. fpath2,
    3. sep='\t',
    4. header=None,
    5. names=['pdate','pv','pu']
    6. #注意设置列名的时候是names,而不是nameread_csv() got an unexpected keyword argument 'name'
    7. )
    8. pvuv2

    注意:设置列名的时候是names,而不是name 报错:read_csv() got an unexpected keyword argument 'name'

    c14edc564ab94277b3ca93f615ade78d.png

    2、读取excel文件

    1. fpath3='./datas/crazyant/access_pvuv.xlsx'
    2. p3=pd.read_excel(fpath3)
    3. p3

    9dcbc875d2de42808432f996cf780c04.png

    3、读取MySQL数据库 

    1. !pip install pymysql
    2. #使用的方法是read_sql
    3. import pymysql

    使用的方法是read_sql:

    1. coon=pymysql.connect(
    2. host='127.0.0.1',
    3. user='root',
    4. database='test'
    5. charset='utf-8'
    6. )
    7. mysql_page=pd.read_sql('select * form crazyant_pvuv',con=coon)

    注意:host是数据库的本地连接,user都是你本地电脑中设置的参数

     

    三、Pandas查询数据

    Pandas查询数据的几种方法

    1.df.loc方法,根据行、列的标签值查询

    2. df.iloc方法,根据行、列的数字位置查询

    3. df.where方法

    4. df.query方法

    .loc既能查询,又能覆盖写入,强烈推荐!

    Pandas使用df.loc查询数据的方法

    1.使用单个label值查询数据

    2.使用值列表批量查询

    3.使用数值区间进行范围查询

    4.使用条件表达式查询

    5.调用函数查询

    ·以上查询方法,既适用于行,也适用于列·注意观察降维dataFrame>Series>值

    import pandas as pd

    1、读取数据

    北京2018年全年天气预报

    1. df=pd.read_csv('./datas/beijing_tianqi/beijing_tianqi_2018.csv',index_col='ymd')
    2. df.head()
    3. df.index

    d67f39280ca74207bb82d4b6092933c0.png

    设置索引为日期,方便按日期筛选
    inplace=True 表示直接在原存储空间上进行更改,不是重新开辟一块空间进行更改
     

    1. #设置索引为日期,方便按日期筛选
    2. #inplace=True 表示直接在原存储空间上进行更改,不是重新开辟一块空间进行更改
    3. df.set_index('ymd',inplace=True)
    4. df.head()

    503518185e824759a088e6c57ed68743.png

    替换掉温度后的℃
    其实还是使用切片操作,首先筛选出所有的行,在筛选出yWendu中一列,带着类型replace修改完之后,在对修改后的类型进行转换 

    1. df.loc[:,'bWendu']=df['bWendu'].str.replace('℃','').astype('int32')
    2. df.loc[:,'yWendu']=df['yWendu'].str.replace('℃','').astype('int32')
    3. df.head()
    4. df.dtypes

    aea2d976239a416c979866cc3002f766.png

     值得注意的是:

    AttributeError: Can only use .str accessor with string values!这种错误一般都是修改完之后了,不能在进行修改,说明已经修改过了

    2、使用单个label值查询数据

    行或列,都可以只传入单个值,实现精确匹配

     

    查询一个单元格,只会返回一个数字值

    1. #查询一个单元格,只会返回一个数字值
    2. df.loc['2018-01-01','bWendu']

    对于列的筛选,会产生一列,得到一个Series

    1. #对于列的筛选,会产生一列,得到一个Series
    2. df.loc['2018-01-01',['bWendu','yWendu']]

    8ee2d87bcc5849898840b98f06c585b9.png

    3、使用值列表批量查询 

    得到Series

    1. #得到Series
    2. df.loc[['2018-01-02','2018-01-03','2018-01-04'],'bWendu']

    得到DataFrame

    1. #得到DataFrame
    2. df.loc[['2018-01-02','2018-01-03','2018-01-04'],['bWendu','yWendu']]

    6af0f49c7cd9456f99a2b5c26766b76f.png

     

    4、使用数值区间进行范围查询

    注意:区间既包括开始,也包括结束

    行index按区间,切片操作的时候不用加双【】

    列index按区间

    行和列都按区间查询

    1. #行index按区间,切片操作的时候不用加双【】
    2. df.loc['2018-01-03':'2018-01-05','bWendu']
    1. #列index按区间
    2. df.loc['2018-01-03','bWendu':'fengxiang']
    1. #行和列都按区间查询
    2. df.loc['2018-01-03':'2018-01-05','bWendu':'fengxiang']

    603ad36b51484cd7b9dd285d81431d2e.png

     

    5、使用条件表达式查询

    bool列表的长度等于行数或者列数

    简单条件查询,最低温度低于-10度的列表

    1. #简单条件查询,最低温度低于-10度的列表
    2. df.loc[df['yWendu']<-10,:]

    观察这里的boolean条件

    1. #观察这里的boolean条件
    2. df['yWendu']<-10

    a02c9f34370c46fb8dedefe00fbfa0ec.png

     

    复杂条件查询,查完美天气

    注意,组合条件&符号合并,每个条件判断都得带括号

    查询最高温度小于30度,最低温度大于15度,晴天,天气为优的数据

    1. #查询最高温度小于30度,最低温度大于15度,晴天,天气为优的数据
    2. df.loc[(df['bWendu']<=30) & (df['yWendu']>=15) & (df['tianqi']=='晴') & (df['aqiLevel']==1),:]

    观察这里boolean的条件

    1. #观察这里boolean的条件
    2. (df['bWendu']<=30) & (df['yWendu']>=15) & (df['tianqi']=='晴') & (df['aqiLevel']==1)

    e73d5aa201cb432f8f75da27dfc18e9f.png

     6、调用函数查询

    直接写lambda表达式

    1. # 直接写lambda表达式
    2. df.loc[lambda df :(df['bWendu']<=30)&(df['yWendu']>=15),:]

    直接编写函数,查询9月份,空气质量好的数据

    1. #直接编写函数,查询9月份,空气质量好的数据
    2. def query_mydata(df):
    3. return df.index.str.startswith('2018-09')&df['aqiLevel']==1
    4. df.loc[query_mydata]

    7ce900a53af2485ea542be782eea62e9.png

     

    de8088810670481190e40a0de8ad7781.png

     

    注意:

    函数式编程的本质:函数自身可以像变量一样传递

     

    四、 Pandas怎样新增数据列?

    在进行数据分析时,经常需要按照一定条件创建新的数据列,然后进行进一步分析

    1.直接赋值
    2. df.apply方法
    3. df.assign方法
    4.按条件选择分组分别赋值

    import pandas as pd

    1、读取CSV数据到dataframe

    1. fpath='./datas/beijing_tianqi/beijing_tianqi_2018.csv'
    2. df=pd.read_csv(fpath)
    3. df.head()

    1c1e08521e9141e7b51a013e5454ef2e.png

    2、对数据进行一个预处理 

    清理温度列,变成一个数字类型

    1. df.loc[:,'bWendu']=df['bWendu'].str.replace('℃','').astype('int32')
    2. df.loc[:,'yWendu']=df['yWendu'].str.replace('℃','').astype('int32')
    3. df.head()
    4. #AttributeError: Can only use .str accessor with string values! 这种情况下语句代码只能运行一次,当运行第二次的时候,原存储的数据已经被改变了

    需要注意的是:AttributeError: Can only use .str accessor with string values!  这种情况下语句代码只能运行一次,当运行第二次的时候,原存储的数据已经被改变了

    3、直接赋值方法

    将温差加入表格当中,注意wencha是一个series,后面的减法返回的是一个series

    1. df.loc[:,'wencha']=df['bWendu']-df['yWendu']
    2. df.head()

    5be21d4f4893476dabc4173a67fe1ce9.png

    4、df.apply方法 

    Apply a function along an axis of the DataFrame.
    Objects passed to the function are Series objects whose index is either the DataFrame's index(axis=0) or the DataFrame's columns (axis=1).

    实例:添加─列温度类型:
            1.如果最高温度大于33度就是高温
            2.低于-10度是低温
            3.否则是常温

    1. def get_wendutype(x):
    2. if x['bWendu']>33:
    3. return '高温'
    4. if x['yWendu']<-10:
    5. return'低温'
    6. else:
    7. return '常温'
    8. df.loc[:,'wendutype']=df.apply(get_wendutype,axis=1)
    df['wendutype'].value_counts()

    6282c2b44a02434fb28dfbffb9180d58.png

    5、df.assign方法 

    Assign new columns to a DataFrame.
    Returns a new object with all original columns in addition to new ones.

    实例:将温度从摄氏度变成华氏度

    注意:df.assign可以同时添加多个列

    1. #df.assign可以同时添加多个列
    2. df.assign(
    3. yWendu_huashi=lambda x: x['yWendu']*9/5+32,
    4. bWendu_huashi=lambda x: x['bWendu']*9/5+32
    5. )

    b16c063b2aaf4f75ade935373c110f4a.png

    6、按条件选择分组分别赋值

    按条件先选择数据,然后对这部分数据赋值新列

    实例:高低温差大于10度,则认为温差大

    1. #先创建空列(第一种创建新列的方法)
    2. df['wencha']=''
    3. df.loc[df['bWendu']-df['yWendu']>10,'wencha']='温差大'
    4. df.loc[df['bWendu']-df['yWendu']<=10,'wencha']='温差正常'
    5. df['wencha'].value_counts()

    567e1c4e9e2d44b297dcfc3baeaa7320.png

     

    五、Pandas 数据统计函数

    1、汇总类统计

    2、唯一去重和按值计数

    3、相关系数和协方差

    import pandas as pd

    1、预备步骤,对数据进行读取和预处理(将温度都改为Int类型)

    1. fpath='./datas/beijing_tianqi/beijing_tianqi_2018.csv'
    2. df=pd.read_csv(fpath)
    3. df.head()

    8457fb1d579e43b788e062f0c35de730.png

     

    1. df.loc[:,'bWendu']=df['bWendu'].str.replace('℃','').astype('int32')
    2. df.loc[:,'yWendu']=df['yWendu'].str.replace('℃','').astype('int32')
    3. df.head()

    b5d2fd7de27e4e78a4a3a7d801c017cb.png

    2、对数据进行汇总类统计 

    1. #提取出所有数字列统计结果
    2. df.describe()

    0110f1dea51e4c3cb055a21db43c3d54.png

    查看单个Series的数据---最高温度的平均值---df['bWendu'].mean() 

    1. # 查看单个Series的数据---最高温度的平均值
    2. df['bWendu'].mean()

    查看最高温度----df['bWendu'].max()

    1. #查看最高温度
    2. df['bWendu'].max()

    最低温度----df['yWendu'].min()

    1. #最低温度
    2. df['yWendu'].min()

    b02689b019f34e0eb6f5bcd4b32ea57d.png

    3、唯一去重和按值计算

    3.1唯一去重性

    一般不用于数值列,而是枚举,分类列-----df[“  ” ].unique()

    1. df['fengxiang'].unique()
    2. df['tianqi'].unique()
    3. df['fengli'].unique()

     47e6cd9e001243dd8d8c6b1fbc04e622.png

    3.2 按值计数(对数据探索十分有用)  

    1. df['fengxiang'].value_counts()
    2. df['tianqi'].value_counts()
    3. df['fengli'].value_counts()

    b7435af183aa469ba7cafedfae8a35ab.png

    828347c214f84cf2a8645ce48f33f9b3.png

    5、相关系数和协方差用途(超级厉害)︰

    1.两只股票,是不是同涨同跌?程度多大?正相关还是负相关?

    2.产品销量的波动,跟哪些因素正相关、负相关,程度有多大?

    对于两个变量X、Y:

    1.协方差︰衡量同向反向程度,如果协方差为正,说明X,Y同向变化,协方差越大说明同向程度越高;如果协方差为负,说明×,Y反向运动,协方差越小说明反向程度越高。

    2.相关系数:衡量相似度程度,当他们的相关系数为1时,说明两个变量变化时的正向相似度最大,当相关系数为- 1时,说明两个变量变化的反向相似度最大

     协方差矩阵-----df.cov()

    1. #协方差矩阵
    2. df.cov()

    相关系数矩阵----df.corr()

    1. #相关系数矩阵
    2. df.corr()

    单独查看空气质量和最高温度的相关系数----df['aqi'].corr(df['bWendu'])

    1. #单独查看空气质量和最高温度的相关系数
    2. df['aqi'].corr(df['bWendu'])
    3. df['aqi'].corr(df['yWendu'])

    检测空气质量和温差的相关系数----df['aqi'].corr(df['bWendu']-df['yWendu'])

    1. #检测空气质量和温差的相关系数
    2. df['aqi'].corr(df['bWendu']-df['yWendu'])

    8cbf85016ded4dc2983d512aced4b255.png

    8f0eeaed85e84436aa69c04bb9a8e048.png

    以上就是特征方程对于机器学习重要性的一个例子 

    注:什么是特征方程?

    特征方程是为研究相应的数学对象而引入的一些等式,它因数学对象不同而不同,包括数列特征方程、矩阵特征方程、微分方程特征方程、积分方程特征方程等等。

    下面所介绍的仅仅是数列的特征方程。

    一个数列:

            711f6e58f09d4aa2a7ba0647f234e253.png

     

     

    设 有r,s使

    5a02e0ec79ad4eafa78a989b4df041cc.png

     

     

    所以

    d466bdcf29b94d83a4f1e4a6a94c1192.png

     

     

    e86baae5d86e4d9da706475d5a347614.png

    消去s就导出特征方程式

    18d3da59d1d94cda9f4effa84a7f9d50.png

    六、Pandas 三类函数对缺失值的处理

    Pandas使用这些函数处理缺失值:

    . isnull和notnull:检测是否是空值,可用于df和series. 
        dropna:丢弃、删除缺失值
             axis:删除行还是列,{0 or 'index',1 or 'columns'}, default 0
             how :如果等于any则任何值为空都删除,如果等于all则所有值都为空才删除
            inplace :如果为True则修改当前df,否则返回新的df
        . fillna:填充空值
             value:用于填充的值,可以是单个值,或者字典(key是列名,value是值)
             method :等于ffill使用前一个不为空的值填充forword fill;等于bfill使用后一个不为空的值填充backword fill
             axis:按行还是列填充,{0 or 'index',1 or 'columns'}
            inplace:如果为True则修改当前df,否则返回新的df

    import pandas as pd

    1、实例:特殊Excel的读取、清洗、处理

    步骤1:读取excel的时候,忽略前几个空行

    1. fpath='./datas/student_excel/student_excel.xlsx'
    2. df=pd.read_excel(fpath,skiprows=2)
    3. df

    1056af5e924e467599574f17912d8a72.png

    步骤2:检测空值--df.isnull()

    df.isnull()

    6deb5c4936b645dbad7e9d953ef4bf69.png

     以下两个函数输出的是相反的值:

    df['分数'].isnull()、df['分数'].notnull()

    1. df['分数'].isnull()
    2. df['分数'].notnull()

    6011b19e01cc45b3bb1e73f10a446958.png

    筛选出没有空分数的所有行---df.loc[df['分数'].notnull(),:] 

    1. #筛选出没有空分数的所有行
    2. df.loc[df['分数'].notnull(),:]

    752aae9ba73c4987982f1a1d73c8911f.png

     步骤3:删除掉全是空值的列

    1. df.dropna(axis='columns',how='all',inplace=True)
    2. df

    5e65eccb482b4fd7917223edae1f4172.png

    步骤4:删除掉全是空值的行 

    1. df.dropna(axis='index',how='all',inplace=True)
    2. df

    9200632f34bf40f7943e3035703f168d.png

    步骤5:将分数列为空的填充为0分 

    df.fillna({'分数':0})

    b28e757383c145c4b189c94026867379.png

     上述操作可以等于以下代码

    1. #上述操作可以等于一下代码
    2. df.loc[:,'分数']=df['分数'].fillna(0)
    3. df

    64cac57ea73e4d3a82e46c1f1f422ed4.png

     步骤6:将姓名的缺失值填充

    使用前面的有效值填充,用ffill:forward fill

    1. df.loc[:,'姓名']=df['姓名'].fillna(method='ffill')
    2. df

    b2e280752ea2429d8d29acd4554dce6a.png

     步骤7:将清洗号的excel保存

    df.to_excel('./datas/student_excel/student_excel_clean.xlsx',index=False)

    七、Pandas 的SettingWithCopyWarning 报警复现、原因、解决方案

    1、读取数据并对数据进行预处理操作

    1. fpath='./datas/beijing_tianqi/beijing_tianqi_2018.csv'
    2. df=pd.read_csv(fpath)
    3. df.head()
    4. df

    cfa2cebfab444ab6bb15835712d603de.png

    1. import pandas as pd
    2. df.loc[:,'bWendu']=df['bWendu'].str.replace('℃','').astype('int32')
    3. df.loc[:,'yWendu']=df['yWendu'].str.replace('℃','').astype('int32')
    4. df

     998092fb37b541078e67683a32073537.png

    2、复现错误 

    只选出3月份的数据用来分析

    1. #只选出3月份的数据用来分析
    2. condition=df['ymd'].str.startswith('2018-03')

    设置温差

    1. #设置温差
    2. df[condition]['wen_cha']=df['bWendu']-df['yWendu']

    900f602bd40048689caac587de3f183e.png

    值得注意的是报错: 

    SettingWithCopyWarning: 
    A value is trying to be set on a copy of a slice from a DataFrame.
    Try using .loc[row_indexer,col_indexer] = value instead
     发现:df[condition]['wen_cha']=df['bWendu']-df['yWendu']改句代码出错

    这里我们也可以查看官网网站去完成差错:Indexing and selecting data — pandas 1.4.4 documentation (pydata.org)

    查看是否修改成功

    1. #查看是否修改成功
    2. df[condition].head()

    048cd9a71153457b93e605c781c38647.png

     3、原因

    发出警告的代码: df[condition]['wen_cha']=df['bWendu']-df['yWendu']
    相当于: df.get(condition).set(wen_cha),第一步的get发出了报警
    链式操作其实是两个步骤,先get 后set,get得到的dateframe可能是View也可能是Copy、Pandas发出警告
    【先可以去官网查看原因】

    核心: pandas的dataframe的修改写操作,只允许在dataframe上进行,一步到位

     

    4、解决方法1

    将get+set 的两步操作,改成set的一步操作

    1. df.loc[condition,'wen_cha']=df['bWendu']-df['yWendu']
    2. df.head()
    df[condition].head()

    cb56594ef3de4fccb115d8432f905655.png

     5、解决方法2

    如果需要预选筛选数据做后续的处理分析,使用copy复制Dataframe

    1. df_month3=df[condition].copy()
    2. df_month3.head()

    b9c5ff9f951349b09e637adc40f715b3.png

    1. df_month3['wen_cha']=df['bWendu']-df['yWendu']
    2. df_month3.head()

     10a22312686a445cb433ef7c212dd9b7.png

    八、Pandas数据排序【Series和DataFrame的排序操作函数】

    1、Pandas数据排序:

    Series的排序:
        Series.sort_values(ascending=True, inplace=False)

    参数说明:
        ascending:默认为True升序排序,为False降序排序.
        inplace:是否修改原始Series

    DataFrame的排序:
        DataFrame.sort_values(by, ascending=True, inplace=False)

    参数说明:
        by:字符串或者List<字符串>,单列排序或者多列排序
        ascending: bool或者List,升序还是降序,如果是list对应by的多列. 
        inplace:是否修改原始DataFrame

    1.1、对数据进行读取和处理操作

    1. import pandas as pd
    2. fpath='./datas/beijing_tianqi/beijing_tianqi_2018.csv'
    3. df=pd.read_csv(fpath)
    4. df

    22d5f4a6daf34699b7adb26360438f04.png

     

    1. df.loc[:,'bWendu']=df['bWendu'].str.replace('℃','').astype('int32')
    2. df.loc[:,'yWendu']=df['yWendu'].str.replace('℃','').astype('int32
    df.head()

    a28c982cb06e4e5f8315d153619d426d.png

    2、Series排序

    df['aqi'].sort_values(ascending=False)

    1. ### 2、Series排序
    2. df['aqi'].sort_values(ascending=False)

    0a6f7b3cdef849fba1e7b45933643f40.png 

    默认为从低到高进行排序     df['aqi'].sort_values()

    1. #默认为从低到高进行排序
    2. df['aqi'].sort_values()

    cc24cb5a9cfa4dce90a7392c86a3160a.png

    也可以对非数字序列进行排序——下述演示的是字符串序列进行排序   df['tianqi'].sort_values() 

    1. #也可以对非数字序列进行排序——下述演示的是字符串序列进行排序
    2. df['tianqi'].sort_values()

    7cf8594548e2439da31fec34dfdc21aa.png

    3、DataFrame的排序

    3.1 单列排序

    默认天气状况从低到高进行排序   df.sort_values(by='aqi')

    1. #默认天气状况从低到高进行排序
    2. df.sort_values(by='aqi')

    5b3049fdeb0d4644a914694c4973625c.png

    df.sort_values(by='aqi',ascending=False)

     8b85d7c582b64572bcb306c2d68efb4b.png

    3.2多列排序 

     按空气质量等级、最高温度排序、默认升序

    1. #按空气质量等级、最高温度排序、默认升序
    2. df.sort_values(by=['aqiLevel','bWendu'])

    0a26a5482e7c45e9885ef3b151c0aef8.png

    两个字段都是降序排序  df.sort_values(by=['aqiLevel','bWendu'],ascending=False)

    1. #两个字段都是降序排序
    2. df.sort_values(by=['aqiLevel','bWendu'],ascending=False)

    e1bd094cc2634f2bb283c750839ac72a.png

    分别指定升序和降序
    df.sort_values(by=['aqiLevel','bWendu'],ascending=[True,False]

    1. #分别指定升序和降序
    2. df.sort_values(by=['aqiLevel','bWendu'],ascending=[True,False])

    af3e14ae4adb49fe9916520c2f8d2543.png

     

    九、Pandas 的字符串处理操作

     0、Pandas字符串处理

    前面我们已经使用了字符串的处理函数:
        df["bWendu"].str.replace("℃","").astype('int32')Pandas的字符串处理:

    1.使用方法:先获取Series的str属性,然后在属性上调用函数;

    2.只能在字符串列上使用,不能数字列上使用;

    3. Dataframe上没有str属性和处理方法

    4.Series.str并不是Python原生字符串,而是自己的一套方法,不过大部分和原生str很相似;

    内容如下:

    1.获取Series的str属性,然后使用各种字符串处理函数

    2.使用str的startswith、contains等bool类Series可以做条件查询

    3.需要多次str处理的链式操作

    4.使用正则表达式的处理

    1、分步骤读取数据

    1. import pandas as pd
    2. fpath='./datas/beijing_tianqi/beijing_tianqi_2018.csv'
    3. df=pd.read_csv(fpath)
    4. df.head()

    12b5169e8d6348d0af4ba8b3d06b45ad.png

    df.dtypes

    c8b58ee04f1444fbaa04594bd6f4e12f.png

     2、获取Series的str属性,使用各种字符串处理函数

    获取最高温度的Series的温度列

    1. #获取最高温度的Series的温度列
    2. df['bWendu'].str

    6e507b713a064a0f91ff0b7128a3c4f0.png

     

    字符串替换函数

    1. #字符串替换函数
    2. df['bWendu'].str.replace('℃','')

    bfc56c46ad814362ae9c52394c81ae73.png

     

    判断是不是数字

    1. #判断是不是数字
    2. df['bWendu'].str.isnumeric()


    684ce5783c5c403696c4c02b05691362.png

     

    1. df['aqi'].str.len()
    2. #AttributeError: Can only use .str accessor with string values! len()方法只能用于字符串类型的数据

    AttributeError: Can only use .str accessor with string values!  len()方法只能用于字符串类型的数据

    3、使用str 的startwith、contains等得到bool的Series可以做条件查询

    Pandas startswith()是另一种在系列或 DataFrame 中搜索和过滤文本数据的方法。此方法类似于Python的startswith()方法,但参数不同,并且仅适用于Pandas对象。因此,.str必须在每次调用此方法之前加上前缀,以便编译器知道它与默认函数不同。

    用法:Series.str.startswith(pat, na=nan)

    参数:
    pat:要搜索的字符串。 (不接受正则表达式)
    na:用于设置序列中的值为NULL时应显示的内容。

    返回类型:布尔序列,为True,其中值的开头是传递的字符串。

    从ymd这一列挑选出2018-03这类型的数据,返回的是一个Boolean类型

    1. #从ymd这一列挑选出2018-03这类型的数据,返回的是一个Boolean类型
    2. condition=df['ymd'].str.startswith('2018-03')
    3. condition

    3c718c1f9ee64760918040e48e81c310.png

     

    输出在condition条件下的df中的数据

    1. #输出在condition条件下的df中的数据
    2. df[condition].head()

    b0fc8b83898942d68b2469d95697b84f.png

    4、需要多次str处理的链式操作 

    1、先将日期2018-03-31替换成20180331的形式
    2、提取月份字符串201803

    df['ymd'].str.replace('-','')

    f983375ce75849c6a5ab1ef9840f4947.png

    问题:直接在Series上面调用方法的话,是否可行?

    答:不可行

    原因:每次调用函数,都会返回一个新的series
    df['ymd'].str.replace('-','').slice(0,6)
    'Series' object has no attribute 'slice'---意思就是series不能够直接去调用slice函数,必须经过str调用后才可以使用

    1. #原因:每次调用函数,都会返回一个新的series
    2. df['ymd'].str.replace('-','').slice(0,6)
    3. #'Series' object has no attribute 'slice'---意思就是series不能够直接去调用slice函数,必须经过str调用后才可以使用
    df['ymd'].str.replace('-','').str.slice(0,6)

    318b18b2ce694e2cbb5fa483c0f95e08.png

    slice是切片操作,也可以直接为str[0:6]
     

    1. #slice是切片操作,也可以直接为str[0:6]
    2. df['ymd'].str.replace('-','').str[0:6]

    66bee709b5614d9ca94c550ee4e4cc96.png

    5、使用正则表达式的处理 

    1. #添加新列
    2. def get_riqi(x):
    3. year,month,day=x['ymd'].split('-')
    4. return f'{year}{month}{day}日'
    5. df['中文日期']=df.apply(get_riqi,axis=1)
    6. df['中文日期']

    3b903f14db60481e8087878244412a00.png

    new question? -----如何将日期中,年月日三个字去除 

    方法1:链式replace

    1. #方法1:链式replace
    2. df['中文日期'].str.replace('年','').str.replace('月','').str.replace('日','')

    c54cb02f5e334d43adbe99c0bb9822ed.png

    Series.str默认开启了正则表达式模式 

    方法2:正则表达式替换
     

    1. #方法2:正则表达式替换
    2. df['中文日期'].str.replace('[年月日]','',regex=True)

    1c1d86ed81d54933a81c3e68d88ecb3f.png
     

    注:

    The default value of regex will change from True to False in a future version.
    在Pandas未来的版本中,.str.replace() 的regex的默认值将从True变为False
    而当regex=True时,单字符正则表达式不会被视为文本字符串
    因为我们是针对price中两个单个字符进行操作,因此设置regex=True 

    f722ce8f79024f7497a4d4ee3996b08a.png

    十、Pandas的axis参数【详解】--Pandas和Numpy的结合

     0、Pandas的axis参数怎么理解?

    . axis=O或者"index":
        ·如果是单行操作,就指的是某一行
        ·如果是聚合操作,指的是跨列cross columns
    . axis=1或者"columns":
        -如果是单列操作,就指的是某一列
        ·如果是聚合操作,指的是跨列cross columns

    按哪个axis,就是这个axis要动起来(类似被or遍历),其它的axis保持不动

    1. import pandas as pd
    2. import numpy as np
    3. df=pd.DataFrame(
    4. np.arange(12).reshape(3,4),
    5. columns=['A','B','C','D']
    6. )
    7. df

    0eb8ed3b0af14846970ccbc159141053.png

     1、单列drop,就是删除一列

    代表的就是删除某列

    1. #代表的就是删除某列
    2. df.drop('A',axis=1)

    e1cd2770fd58459bbf2a54376a6b7ae9.png

     

    2、单行drop,就是删除一行

    代表的就是删除某行
     

    1. #代表的就是删除某行
    2. df.drop(1,axis=0)

    b730caf780c640eaa93d24a35e922596.png

    3、按axis=0/index执行Mean聚合操作

    并不是像我们想象的那个样子,输出的是每列的结果!!!

    axis=0 or axis=index

    1. # axis=0 or axis=index
    2. df.mean(axis=0)

    6f0b9c33b8bb4112bd185bd7692a3b10.png
     

    0615ce32ae464f0e8dc803e9301f83c7.png

    指定了按那个axis,就是这个axis要动起来(类似被for遍历),其他的axis保持不动 

     

    4、按axis=1/colums执行mean聚合操作

    并不是像我们想象的那个样子,输出的是每行的结果!!

     axis=1 or axis=colums

    1. # axis=0 or axis=colums
    2. df.mean(axis=1)

    b7ac8ed49de343689fee478258b98f7c.png
     

    962eb89f899f46c3a47cf67f3aebe055.png 

     指定了按那个axis,就是这个axis要动起来(类似被for遍历),其他的axis保持不动

     

    5、举例证明

    1. def get_sum(x):
    2. return x['A']+x['B']+x['C']+x['D']
    3. df['sum']=df.apply(get_sum,axis=1)
    4. df
    5. #跨列相加

    60ceddd6ca2f48c8b9545aa298093cb7.png

     

    十一、Pandas的索引index所具备的四大性能

     0、Pandas的索引index

    Pandas的索引index的用途:

    把数据存储于普通的column列也能用于数据查询,那使用index有什么好处?

    index的用途总结:

    1.更方便的数据查询;

    2.使用index可以获得性能提升;

    3.自动的数据对齐功能;

    4.更多更强大的数据结构支持;

     

    1.更方便的数据查询

    1. import pandas as pd
    2. df=pd.read_csv('./datas/ml-latest-small/ratings.csv')
    3. df.head()

    0493490eae4a4924bc01ad22a7a47966.png

    查询index的数量:df.count()

    df.count()

    bc8bcd22d960427f98199421fb629491.png
     

    drop==False,让索引列还保持在column:意思就是使id这一列继续存在于数据当中

    1. #drop==False,让索引列还保持在column:意思就是使id这一列继续存在于数据当中
    2. df.set_index('userId',inplace=True,drop=False)
    3. df.head()

    0b5080e0e09241e9a36fb0bd8b786488.png

    df.index

     69a1876aebb544be98b89e6285fab17c.png

    第一种:使用index查询的方法---会使查询的代码比较简单
    df.loc[500].head() 

    1. #第一种:使用index查询的方法---会使查询的代码比较简单
    2. df.loc[500].head()

    78af2c5efe1c43409cb8e8618474fead.png

    第二种:使用column的condition查询方法
    condition=df['userId']
    df.loc[condition==500].head() 

    1. #第二种:使用column的condition查询方法
    2. condition=df['userId']
    3. df.loc[condition==500].head()

    a3fca61a7fce409e83609508698e869f.png

     

    2.使用index会提升查询性能

    如果index是唯一的,Pandas会使用哈希表优化,查询性能为O(1);

    如果index不是唯一的,但是有序,Pandas会使用二分查找算法,查询性能为O(logN);

    如果index是完全随机的,那么每次查询都要扫描全表,查询性能为O(N);

    123bc28678174a62bec1ffde832ec6f0.png

    实验1:完全随机的顺序查询 

    将数据随机打散

    1. !pip install sklearn
    2. #将数据随机打散
    3. from sklearn.utils import shuffle
    4. df_shuffle=shuffle(df)
    5. df_shuffle.head()

    61cc113af3f24d04942d8744adeb3c5a.png

    查询我们的索引是不是递增的
    df_shuffle.index.is_monotonic_increasing 

    1. #查询我们的索引是不是递增的
    2. df_shuffle.index.is_monotonic_increasing

    查询我们的索引是不是递减的
    df_shuffle.index.is_monotonic_decreasing

    1. #查询我们的索引是不是递减的
    2. df_shuffle.index.is_monotonic_decreasing

      %timeit 函数是经过大量运算,统计计算出平均运行所用的时间
     计时,查询id==500数据性能
    %timeit df_shuffle.loc[500]

    1. # %timeit 函数是经过大量运算,统计计算出平均运行所用的时间
    2. # 计时,查询id==500数据性能
    3. %timeit df_shuffle.loc[500]

    32b19a84293a47cbbf3ef6a13d019839.png

    实验2:将index排序后查询 

    调用sort函数默认为升序操作

    1. #调用sort函数默认为升序操作
    2. df_sorted=df_shuffle.sort_index()
    3. df_sorted.head()
    4. df_sorted.index.is_monotonic_increasing

    调用sort函数默认为降序操作 设置为ascending=False为降序操作
     

    1. #调用sort函数默认为降序操作 设置为ascending=False为降序操作
    2. df_sorted2=df_shuffle.sort_index(ascending=False)
    3. df_sorted2.index.is_monotonic_decreasing

    判断索引是不是唯一的
    df_sorted.index.is_unique

    1. #判断索引是不是唯一的
    2. df_sorted.index.is_unique

    如果index不是唯一的,但是有序,Pandas会使用二分查找算法,查询性能为O(logN);
    %timeit df_sorted.loc[500]

    1. #如果index不是唯一的,但是有序,Pandas会使用二分查找算法,查询性能为O(logN);
    2. %timeit df_sorted.loc[500]

    c1e3cff1c22b458b812f35940df63af2.png

    3、使用index能自动对齐数据

    包括series和dataframe

    index会自动对齐

    1. #index会自动对齐
    2. s1=pd.Series([1,2,3],index=list('abc'))
    3. s1
    1. s2=pd.Series([2,3,4],index=list('bcd'))
    2. s2

    当s1+s2中遇到另一方没有找到相同的索引时,会显示NaN,无法进行算术操作时
     

    1. #当s1+s2中遇到另一方没有找到相同的索引时,会显示NaN,无法进行算术操作时
    2. s1+s2

    96c0a90d09704092a1043f5caad51c7a.png
     

    4.使用index更多更强大的数据结构支持

    很多强大的索引数据结构

    Categoricallndex,基于分类数据的Index,提升性能;

    Multilndex,多维索引,用于groupby多维聚合后结果等;

    Datetimelndex,时间类型索引,强大的日期和时间的方法支持;

     

    十二、Pandas的Merge语法(内含设置行名方法)

    1、 Pandas怎样实现DataFrame的Merge

    Pandas的Merge,相当于Sql的Join,将不同的表按key关联到一个表

    merge的语法:

    pd.merge(left,right, how='nner , on=None,left_on=None, right_on=None,lef_index=False,right_index=False,sort=True, sufises=(‘_X’ ,“_Y” ), opy=Tue,indicator=False, validate=None)

     

    left,right:要merge的dataframe或者有name的Series.
    how: join类型,'left', 'right', 'outer', 'inner'
    on: join的key,left和right都需要有这个key. 
    left_on: left的df或者series的key
    right_on: right的df或者seires的key
    left_index,right_index:使用index而不是普通的column做join
    suffixes:两个元素的后缀,如果列有重名,自动添加后缀,默认是('_X','_y')

    本次讲解提纲:
        1.电影数据集的join实例
        2.理解merge时一对一、一对多、多对多的数量对齐关系
        3.理解left join、right join、inner join、outer join的区别
        4.如果出现非Key的字段重名怎么办

    1. import pandas as pd
    2. df_ratings=pd.read_csv(
    3. './datas/movielens-1m/ratings.dat',
    4. sep="::",#设置其分隔服为::
    5. engine='python',#因为pandas语法中sep为两个字符的时候,系统默认其为正则表达式,但是分隔符就是::不是正则表达式,所以加engine=python
    6. names='UserID::MovieID::Rating::Timestamp'.split('::')
    7. )
    8. df_ratings.head()

    5e93e4fb9597460a82be492855ad5f65.png

    1. df_users=pd.read_csv(
    2. './datas/movielens-1m/users.dat',
    3. sep="::",
    4. engine='python',
    5. names='UserID::Gender::Age::Occupation::Zip-code'.split('::')
    6. )
    7. df_users.head()

    a31a0a6c5c544d5da0a5ca5a7f20f74f.png

     

    1. df_movies=pd.read_csv(
    2. './datas/movielens-1m/movies.dat',
    3. sep='::',
    4. engine='python',
    5. names='MovieID::Tile::Genres'.split("::")
    6. )
    7. df_movies.head()

    09c894360a8a4c40ac010768306fdcf3.png

    1. df_ratings_users=pd.merge(
    2. df_ratings,df_users,on='UserID',how='inner'
    3. )
    4. df_ratings_users.head()

    140bd8157c564075960170833d9d3a37.png

    1. df_ratings_users_movies=pd.merge(
    2. df_ratings_users,df_movies,left_on='MovieID',right_on='MovieID',how='inner'
    3. )
    4. df_ratings_users_movies.head()

    df93b393feaf4c9ca7ccb674be094bfc.png

    2、理解merge时数量的对齐关系以下关系要正确理解:

    . one-to-one:—对一关系,关联的key都是唯一的

    .比如(学号,姓名) merge (学号,年龄)

    -结果条数为:1*1

    . one-to-many:一对多关系,左边唯一key,右边不唯一key

    -比如(学号,姓名) merge(学号,[语文成绩、数学成绩、英语成绩])

    结果条数为:1*N

    . many-to-many : [多对多关系,左边右边都不是唯一的

    ·比如(学号,[语文成绩、数学成绩、英语成绩])merge (学号,[篮球、足球、乒乓球)

    -结果条数为:M*N

    2.1 one-to-one 一对一关系的merge

    df358241e1ba41a1a235bc6b26458bc0.png

    1. left=pd.DataFrame({
    2. 'sno':[11,12,13,14],
    3. 'name':['name_a','name_b','name_c','name_d']
    4. }
    5. )
    6. left

     8d850fbf79944689a60eae462a5e6b70.png

    1. right=pd.DataFrame({
    2. 'sno':[11,12,13,14],
    3. 'age':['21','22','23','24']
    4. })
    5. right

     cb81d1fe932240fcb48ba5e709b54be0.png

    1. #一对一关系中:结果有四条
    2. pd.merge(left,right,on='sno')

    8ac227c47ee944e3818426209c6d0736.png

    2.2 one-to-many一对多关系的

    merge注意:数据会被制

    9e8145a1261e43198f50bed67a169702.png

    1. left=pd.DataFrame({
    2. 'sno':[11,12,13,14],
    3. 'name':['name_a','name_b','name_c','name_d']
    4. }
    5. )
    6. left

     c795b617215b49de81a4d446e8c0563f.png

     b91ed60f6c5d4ba8a7bc963cdffef394.png

    1. right=pd.DataFrame({
    2. 'sno':[11,11,11,12,12,13],
    3. 'grade':['英语:21','语文:22','数学:23','英语:24',"语文:11","数学:55"]
    4. })
    5. right

    0d2f1a0c5e4b4fbd9ab9840ca93af2e6.png

     

    1. #一对多的关系对name名字进行了复制
    2. pd.merge(left,right,on='sno')

    0dd6b0a337a44bcdae5fe464b7806730.png

     

    2.3 many-to-many多对多关系的merge

    注意:结果数量会出现乘法

    469338e5856041e791d144983e70f229.png

     

    1. left=pd.DataFrame({
    2. 'sno':[11,11,12,12,12],
    3. '爱好':['篮球','羽毛球','乒乓球','篮球','足球']
    4. }
    5. )
    6. left
    1. right=pd.DataFrame({
    2. 'sno':[11,11,11,12,12,13],
    3. 'grade':['英语:21','语文:22','数学:23','英语:24',"语文:11","数学:55"]
    4. })
    5. right

    5202cdddf5f043b39f3e9739b3c1b83e.png

    pd.merge(left,right,on='sno')

    aa9288f82b95492398580dca84180292.png

     3、理解left join、right join、inner join、outer join的区别

    888502f89f83450e9fbf19974f35d77c.png

    1. left=pd.DataFrame({
    2. 'key':['ko','k1','k2','k3'],
    3. 'A':['A0','A1','A2','A3'],
    4. 'B':['B0','B1','B2','B3']
    5. })
    6. right=pd.DataFrame({
    7. 'key':['k0','k1','k2','k3'],
    8. 'C':['C0','C1','C2','C3'],
    9. 'D':['D0','D1','D2','D3']
    10. })
    11. left

     720dc21c55474fa089d819c144921327.png

    3.1 inner join,默认

    左边和右边的key都有,才会出现在结果里

    pd.merge(left,right,how='inner')

    22a8621801ed4eed8a01671ebc79e0f6.png

    3.2 left join

    左边的都会出现在结果里,右边的如果无法匹配则为Null

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

    12cac8202ebc4f4683c71008a47bcd70.png

    3.3 right join

    右边的都会出现在结果里,左边的如果无法匹配则为Nul

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

    8bae8369168a4ab889a56fb795816426.png

    3.4 outer join

    左边、右边的都会出现在结果里,如果无法匹配则为Null

    pd.merge(left,right,how='outer')

    9d9601f8a697425f9520c312265680c0.png

     4、如果出现非Key的字段重名怎么办

    1. left=pd.DataFrame({
    2. 'key':['K0','k1','k2','k3'],
    3. 'A':['A0','A1','A2','A3'],
    4. 'B':['B0','B1','B2','B3']
    5. })
    6. right=pd.DataFrame({
    7. 'key':['K0','K1','K4','K5'],
    8. 'A':['A10','A11','A12','A13'],
    9. 'D':['D0','D1','D4','D5']
    10. })
    11. left

    b85e2208dfa3415abfaa6c0ff46db75d.png

     

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

    suffixes=('name1','name2')可以直接设置重名函数的函数名
    pd.merge(left,right,on='key',suffixes=('_left','_right'))

    1. #suffixes=('name1','name2')可以直接设置重名函数的函数名
    2. pd.merge(left,right,on='key',suffixes=('_left','_right'))

    ab8db2d9374541e6923572762aaea467.png

    十三、Pandas 的Concat合并【实现Concat合并】

    0、 Pandas实现数据的合并concat

    使用场景:

    批量合并相同格式的Excel、给DataFrame添加行、给DataFrame添加列

    一句话说明concat语法:

    。使用某种合并方式(inner/outer)

    ·沿着某个轴向(axis=0/1)

    ·把多个Pandas对象(DataFrame/Series)合并成一个。

    concat语法: pandas.concat(objs, axis=0, join='outer', ignore_index=False)

    . objs: 一个列表,内容可以是DataFrame或者Series,可以混合

    . axis: 默认是0代表按行合并,如果等于1代表按列合并

    . join:合并的时候索引的对齐方式,默认是outer join,也可以是inner join.

    ignore_index:是否忽略掉原来的数据索引

    append语法: DataFrame.append(other, ignore_index=False)

    append只有按行合并,没有按列合并,相当于concat按行的简写形式.

    other:单个dataframe、series、dict,或者列表

    ignore_index:是否忽略掉原来的数据索引

    1. import pandas as pd
    2. import warnings
    3. warnings.filterwarnings('ignore')

    1、使用pandas.concat合并数据

    1. df1=pd.DataFrame({
    2. 'A':['A0','A1','A2','A3'],
    3. 'B':['B0','B1','B2','B3'],
    4. 'C':['C0','C1','C2','C3'],
    5. 'D':['D0','D1','D2','D3'],
    6. 'E':['E0','E1','E2','E3']
    7. })
    8. df2=pd.DataFrame({
    9. 'A':['A4','A5','A6','A7'],
    10. 'B':['B4','B5','B6','B7'],
    11. 'C':['C4','C5','C6','C7'],
    12. 'D':['D4','D5','D6','D7'],
    13. 'F':['F4','F5','F6','F7']
    14. })
    15. df1

    9f6d9601e2d44cc8b249e1a711225ef6.png

    df2

     1、默认的concat,参数为axis=0、 join=outer、ignore_index=False

    因为默认axis=0,即第二个df2的值默认放在第一个df1内容的下面,即所谓的行合并
    pd.concat([df1,df2])

    1. #因为默认axis=0,即第二个df2的值默认放在第一个df1内容的下面,即所谓的行合并
    2. pd.concat([df1,df2])

    618ce7e3ff154c61859a7a3870654005.png

    2、使用ignore_index=True可以忽略原来的索引 

    忽略原来的缩影的列,从0,1,2,3........
    pd.concat([df1,df2],ignore_index=True)

    1730b164109647bfaf2264bed63611fb.png

    3、使用join=inner过滤掉不匹配的列 

    意思就是只要任意一组没有就进行过滤
    pd.concat([df1,df2],ignore_index=True,join='inner')

    1. #意思就是只要任意一组没有就进行过滤
    2. pd.concat([df1,df2],ignore_index=True,join='inner')

    9234065c4f444b56b5aa3083960b5d19.png

    4、使用axis=1相当于添加新列 

    df1

    351667037f004aa192eb625bfc05de8b.png

    A:添加一列Series 

    1. s1=pd.Series(list(range(4)),name='F')
    2. s1
    3. pd.concat([df1,s1],axis=1)

    081ba07b598648c3b5e8d0b09e1ee397.png

    B:添加多列Series 

    1. s2=df1.apply(lambda x:x["A"]+'_11',axis=1)
    2. s2
    1. s2.name='G'
    2. pd.concat([df1,s1,s2],axis=1)
    1. #列表中可以只有Series
    2. pd.concat([s1,s2],axis=1)
    1. #列表也可以是混合顺序的
    2. pd.concat([s1,df1,s2],axis=1)

    48f4a142fd0c434ab68474f052638a57.png

    4e1fc281f2034917a4aa4825a470cfcb.png

    二、使用DataFrame.append按行进行合并数据 

    1. df1=pd.DataFrame([[1,2],[3,4]],columns=list('AB'))
    2. df1
    1. df2=pd.DataFrame([[5,6],[7,8]],columns=list('AB'))
    2. df2

    9d28dccfa53d4cdfbfa3f4a05c09e212.png

     1、给一个dataframe添加另一个dataframe

    df1.append(df2)

    be0396e6e2fc4e26a75a31fae8f01334.png

     

    2、忽略原来的索引ignore_index=True

    df1.append(df2,ignore_index=True)

    27c106ea3c124daa94ce377979546240.png

     

    3、可以一行行的给DataFrame添加数据

    1. #一个空的df
    2. df=pd.DataFrame(columns=['A'])
    3. df

    d14f7bacefd94cb290321c5f8328288c.png

    A:低新能版本

    1. for i in range(5):
    2. #利用这种循环,每次都在复制
    3. df=df.append({'A':i},ignore_index=True)
    4. df

    68ff332358144c26988b829eb6a250fe.png

     

    B:高新能版本

    1. #第一个入参的是列表,避免了多次的复制,直接往里面添加就可以了
    2. pd.concat(
    3. [pd.DataFrame([i],columns=['A']) for i in range(5)],
    4. ignore_index=True
    5. )

    a2d0a4606ef34b53ae26441e15242ae8.png

    十四、Pandas批量拆分与合并Excel文件

    0、 Pandas批量拆分Excel与合并Excel

    实例演示:

    1.将一个大Excel等份拆成多个Excel

    2.将多个小Excel合并成一个大Excel并标记来源

    1. #本节课的数据目录work_dir
    2. work_dir='./course_datas/c15_excel_split_merge'
    3. #work_dir下面的splits目录,来放置拆分后的小文件
    4. splits_dir=f'{work_dir}/splits'
    5. import os
    6. #如果splits_dir目录不存在就创建一个小目录
    7. if not os.path.exists(splits_dir):
    8. os.mkdir(splits_dir)

    1、读取源Excel到Pandas

    1. import pandas as pd
    2. df_source=pd.read_excel(f'{work_dir}/crazyant_blog_articles_source.xlsx')
    3. df_source.head()

    40dee1841eb140f5bb75a7ed35c7da1c.png

    1. df_source.index
    2. df_source.shape
    3. total_row_count=df_source.shape[0]
    4. total_row_count

    7302cbb5aa49446cab0112c5a58a4a6d.png

     

    一、将一个大Excel等份拆成多个Excel

    1.使用df.iloc方法,将一个人的dataframe,拆分成多个小dataframe

    2.将使用dataframe.to_excel保存每个小Excel

    1、计算拆分后的每个excel的行数

    1. #将一个大的EXCEL文件拆分给这几个人
    2. user_name=['xiaohu','xiaoshuai','xiaolan','xiaofan','xiaok','xiaom']
    1. #每个人的任务数目
    2. splits_size=total_row_count//len(user_name)
    3. #判断每个人分配的任务数是否为整数,若不为整数则+1
    4. if total_row_count % len(user_name) !=0:
    5. splits_size+=1
    6. splits_size

    03c98955dca34a7b9bc94fda2a28e106.png

    2、拆分成多个dataframe

    1. #将拆出来的小的dataframe存在df_sub[]当中
    2. df_subs=[]
    3. for index,user_name in enumerate(user_name):
    4. #iloc的开始索引,从0开始进行索引
    5. begin=index*splits_size
    6. #iloc的结束索引
    7. end=begin+splits_size
    8. #实现df按照iloc拆分
    9. df_sub=df_source.iloc[begin:end]
    10. #将每个子df存入列表
    11. df_subs.append((index,user_name,df_sub))

    3、将每个datafame存入excel

    1. for index,user_name,df_sub in df_subs:
    2. file_name=f'{splits_dir}/crazyant_blog_articles_{index}_{user_name}.xlsx'
    3. df_sub.to_excel(file_name,index=False)

    二、合并多个小Excel到一个大Excel

    1.遍历文件夹,得到要合并的Excel文件列表

    2.分别读取到dataframe,给每个df添加—列用于标记来源

    3.使用pd.concat进行df批量合并

    4.将合并后的dataframe输出到excel

    1、遍历文件夹,得到要合并的Excel名称列表

    1. import os
    2. excel_names=[]
    3. for excel_name in os.listdir(splits_dir):
    4. excel_names.append(excel_name)
    5. excel_names
    6. #os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表。

    95b7c9d7d8724ddeb0ed6b055326941c.png

    2、分别读取到dataframe 

    1. df_list=[]
    2. for excel_name in excel_names:
    3. #将每个excel读取到df当中
    4. excel_path=f'{splits_dir}/{excel_name}'
    5. df_split=pd.read_excel(excel_path)
    6. #得到username
    7. username=excel_name.replace('crazyant_blog_articles_','').replace('.xlsx','')[2:]
    8. print(excel_name,username)
    9. #给每个df添加1列,即用户名字
    10. df_split['username']=username
    11. df_list.append(df_split)

    6b94d08b107a4545b3d7ad0b661d4b0e.png

    3、使用pd.concat进行合并 

    1. df_merged=pd.concat(df_list)
    2. df_merged.shape
    3. df_merged.head()

    e51a62b02326479a92daada4553bedc9.png

    df_merged['username'].value_counts()

     a16bfb7176574316892e8c710d432af1.png

    4、将合并后的dataframe输出到excel中 

    df_merged.to_excel(f'{work_dir}/crazyant_blog_articles_merged.xlsx',index=False)

     

    十五、Pandas怎样实现groupby分组统计

    0、 Pandas怎样实现groupby分组统计

    类似SQL: select city,max(temperature) from city_weather group by city;

    groupby:先对数据分组,然后在每个分组上应用聚合函数、转换函数

    本次演示:

    一、分组使用聚合函数做数据统计

    二、遍历groupby的结果理解执行流程

    三、实例分组探索天气数据

    1. import pandas as pd
    2. import numpy as np
    3. #在jupyter notebook中展示matplot图表
    4. %matplotlib inline
    1. df=pd.DataFrame({
    2. 'A':['foo','bar','foo','bar','foo','bar','foo','foo'],
    3. 'B':['one','one','two','three','one','one','two','three'],
    4. 'C':np.random.randn(8),
    5. 'D':np.random.randn(8)
    6. })
    7. df

    be3959c242864a46b0cfbe42bfb3b2c1.png

    1、分组使用聚合函数做数据统计

    1、单个列groupby,查询所有数据列的统计

    1. P=df.groupby('A').sum()
    2. #聚合操作后P仍然是一个Dataframe
    3. P

    8c92c1edf5d7465eb48d7a4ead1ec83d.png

    df.groupby('name').sum()

    Ps: 1、将name列的不同名称作为索引

    1. 2、忽略df中不是数字列的一列
    2. 3、对是数字列的一列进行累加
    3. 4、统计在name不同名称下的,其他值的和

    2、多个列groupby,查询所有数据列的统计

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

    baafc3a9808a454097d3ebb0d59223d9.png

     

    1、选取A、B两列的不同名称作为索引---在这里因为A列的bar没有B列中的two所以没有

    2、对数字列进行求取平均值

    3、统计在不同名下的平均值

    4、将A、B变成二级索引

    1. #设置as_index=False,取消A、B作为二级索引
    2. df.groupby(['A','B'],as_index=False).mean()

    c3808ed3196b4daca9e80adf8b432f78.png

    3、同时查看多种数据统计 

    df.groupby('A').agg([np.sum,np.mean,np.std])

    00b99851bc5245b8b0c2fb825e33f843.png

    1、将name列的不同名称作为索引

    1. 2、忽略df中不是数字列的一列
    2. 3、对是数字列的一列进行操作
    3. 4、统计在name不同名称下的,其他值的和

    列变成了多级索引

    4、查看单列的结果数据统计

    1. #方法1:预过滤,性能更好
    2. df.groupby('A')['C'].agg([np.sum,np.mean,np.std])

     45ffc204b2d4463684fba020714698e1.png

    1. #方法2:
    2. df.groupby('A').agg([np.sum,np.mean,np.std])['C']

    9ed4e1f8c97a4faab2e57ded9d9c2499.png

    5、不同列使用不同的聚合函数 

    1. df.groupby('A').agg({
    2. 'C':np.sum,
    3. 'D':np.mean
    4. })

     d642272fa91f47b98b570c3798f2551e.png

    二、遍历groupby的结果理解执行流程

    for循环可以直接遍历每个group

    1、遍历单个列聚合的分组

    1. g=df.groupby('A')
    2. g
    3. #相当于对A索引的不同值的列进行一个汇总,使数据看起来更加的清晰
    1. for name,group in g:
    2. print(name)
    3. print(group)
    4. print( )

    c407b3c7220749a0a376d73c218c3f02.png

    可以获取单个分组的数据 

    g.get_group('bar')

    00db952d8a7742e5affb1d10c886d9db.png

    2、遍历多个列聚合的分组 

    1. g=df.groupby(['A','B'])
    2. for name,group in g:
    3. print(name)
    4. print(group)
    5. print( )
    6. #name 是一个2个元素的元组,代表不同的列

    de6d8350e8604c26b3b1019520e4ccaf.png

    可以直接查询group后的某几列,生成Series或者子DataFrame 

    1. g['C']
    2. for name,group in g:
    3. print(name)
    4. print(group)
    5. print( )

    3dd2900bf0a145c29307fd770b84fc0a.png

    本质:所有的聚合统计,都是在dataframe和series上进行的

    三、实例分组探索天气数据

    1. fpath='./datas/beijing_tianqi/beijing_tianqi_2018.csv'
    2. df=pd.read_csv(fpath)
    3. df

     bd75956e0aec441eabb2353302a3b689.png

    1. #替换掉温度后缀℃
    2. df.loc[:,'bWendu']=df['bWendu'].str.replace('℃','')
    3. df.loc[:,'yWendu']=df['yWendu'].str.replace('℃','')
    4. df

    797e501e19804a8a852921e65159bbbc.png

    1. df2=df.drop(labels=['bWendu','yWendu'], axis=0, inplace=False)
    2. df2

    e12c739e2ba244dcb8e12fdced2ce271.png

    1. df2.loc[:,'bWendu']=df2['bWendu'].astype('int32')
    2. df2.loc[:,'yWendu']=df2['yWendu'].astype('int32')
    3. df2.head()

    d6e093a6bd064dd2876a3e203f48e2db.png

    1. #新增一列为月份
    2. df['month']=df['ymd'].str[:7]
    3. df.head()

     603a24d55f9149baaaba4d1632ebd302.png

     1、查看每个月的最高温度

    1. data=df.groupby('month')['bWendu'].max()
    2. data

    44a77da525304077bae06d56d3ebdac9.png

    1. type(data)
    2. data=data.astype(float)
    3. data.plot()

    c358e4d554ac49e381f43c6d4d83723d.png

     2、查看每个月的最高温度、最低温度、平均空气质量指数

    1. df.head()
    2. group_data=df.groupby('month').agg({'bWendu':np.max,'yWendu':np.min,'aqi':np.mean})
    3. group_data

    8f1c200883eb4defb53968906f896118.png

    91b2e8553930455695d83faaa2af46eb.png

    group_data.plot()

     8aa174433fc04be8a5c5ea9dfe0d47fc.png

     

    十六、Pandas的分层索引MultiIndex怎么用?

    0、 Pandas的分层索引Multilndex

    1为什么要学习分层索引Multilndex?

    1、分层索引:在一个轴向上拥有多个索引层级,可以表达更高维度数据的形式;

    2、方便的进行数据筛选,如果有序则性能更好;

    3、groupby等操作的结果,如果是多KEY,结果是分层索引,需要会使用。

    4、一般不需要自己创建分层索引(Multilndex有构造函数但一般不用)

    演示数据:百度、阿里巴巴、爱奇艺、京东四家公司的10天股票数据数据来自:英为财经

    —、Series的分层索引Multilndex

    二、Series有多层索引怎样筛选数据?

    三、DataFrame的多层索引Multilndex

    四、DataFrame有多层索引怎样筛选数据?

    1. import pandas as pd
    2. %matplotlib inline
    3. stocks=pd.read_excel('./datas/stocks/互联网公司股票.xlsx')
    4. stocks.shape
    stocks

    c3498eecb3764d98b65de9b2043025f4.png

     

    1. stocks['公司'].unique()
    2. stocks.index
    3. #计算每个公司收盘的平均值
    4. stocks.groupby('公司')['收盘'].mean()

    7a137812d7824162a1e4a7afa659cee2.png

    1、Series的分层索引MultiIndex 

    1. ser=stocks.groupby(['公司','日期'])['收盘'].mean()
    2. ser
    ser.index
    1. # unstack把二级索引变成列
    2. ser.unstack()
    3. ser
    1. #全部变成一维的普通索引模式
    2. ser.reset_index()

    76c0387e929549d79de717e9e7e791c2.png

     ba864af5686d4164bf04f854ef3941d0.png

    5a5ef5f84098469eb7c1140a0e531035.png 2、Series有多层索引Multilndex怎样筛选数据?

     

    1. ser
    2. ser.loc['BIDU']
    3. # 多层索引,可以用元组的形式进行筛选
    4. ser.loc[('BIDU','2019-10-02')]

    f85d891c11624f33bac198e2ddeaca8f.png

    1. #求所有公司中指定月份的收盘价
    2. ser.loc[:,'2019-10-02']

    6a7747ba665a43d8af9006895dbd6b20.png

     3、DataFrame的多层索引Multilndex

    1. stocks.head()
    2. stocks.set_index(['公司','日期'],inplace=True)
    3. stocks

    bdeab30dd06242fd9657297530a54707.png

    1. stocks.index
    2. #自动根据索引进行排序,默认为升序排列
    3. stocks.sort_index(inplace=True)
    4. stocks

    ae888f53f12c46bab8db78aeb89ed30e.png

     ad92d53f2ae7476abaa0dab95f49dd58.png

     

    4、DataFrame有多层索引Multilndex怎样筛选数据?

    【重要知识】在选择数据时:

    。元组(key1.key2)代表筛选多层索引,其中key1是索引第一级,key2是第二级,比如key1=JD, key2=2019-10-02

    ·列表[key1,key2]代表同一层的多个KEY,其中key1和key2是并列的同级索引,比如key1=JD, key2=BIDU

    stocks.loc['BIDU']

    821dfe667dcd4d358f78c7831bbf9768.png

    1. # 'BIDU'是一级索引 '2019-10-02'是二级索引
    2. stocks.loc[('BIDU','2019-10-02'),:]

     5e2d0bbe6f4e426f86ec687a8095006c.png

    stocks.loc[('BIDU','2019-10-02'),'开盘']

    f72b1bde7c1940ba8e2673df3ad8f86a.png

    1. #设置日期的同一级索引的格式
    2. stocks.loc[('BIDU',['2019-10-03','2019-10-02']),'收盘']

    d370cdc2c698433db106fcbdff4f4f31.png

    1. #slice(None)代表筛选中一索引的所有内容---在这里的意思就是筛选一级索引‘公司’的所有内容
    2. stocks.loc[(slice(None),['2019-10-03','2019-10-02']),:]

    774c7b0576ac42268e48eb965c87ce8c.png

     

    1. #将多重索引全部重置,转换为一维索引
    2. stocks.reset_index()

    41bc89889ce04bff9da89e6787086439.png

    十七、Pandas的数据转换函数--map、apply、applymap

     0、Pandas的数据转换函数map.apply、applymap

    数据转换函数对比: map、apply、applymap

    1.map用于Series值的转换

    实例:将股票代码英文转换成中文名字

    Series.map(dict) or Series.map(function)均可

    1. import pandas as pd
    2. stocks=pd.read_excel('./datas/stocks/互联网公司股票.xlsx')
    3. stocks.head()

    6098a53104cb48b2b1da6d13d1d4a996.png

    stocks['公司'].unique()
    1. #公司股票代码到中文的映射,注意这里要小写
    2. dict_company_names={
    3. 'bidu':'百度',
    4. 'baba':'阿里巴巴',
    5. 'iq':'爱奇艺',
    6. 'jd':'京东'
    7. }

    5ed6eeacb28a4ebc93dfc3b21231d7e4.png

    方法1:Series.map(dict) ----在map函数中传进去一个字典只用于Series 

    1. # stocks['公司'].str.lower()---将公司中的所有字母转换为小写字母
    2. # .map(dict_company_names)--把公司中所有对应的列转换为其对应的中文字母
    3. stocks['公司中文1']=stocks['公司'].str.lower().map(dict_company_names)
    4. stocks.head()

    8a3ed167b50341e68c57d2e3e97953f4.png

    方法2:Series.map(function) ----在map函数中传进去一个自定义函数只用于Series

    function的参数是Series的每个元素的值

    1. stocks['公司中文2']=stocks['公司'].map(lambda x:dict_company_names[x.lower()])
    2. stocks.head()

    b560541c47e241eea708f1656532a7b1.png

    2.apply用于Series和DataFrame的转换---既可以用于Series也可以用于DataFrame

    Series.apply(function),函数的参数是每个值.

    DataFrame.apply(function),函数的参数是Series

    Series.apply(function)

    function的参数是Series的每个值

    1. stocks['公司中文3']=stocks['公司'].apply(
    2. lambda x:dict_company_names[x.lower()]
    3. )
    4. stocks.head()

    c2c036e0a5144b47bb77d0054dac2f0e.png

    DataFrame.apply(function)

    function的参数是对应轴的Series

    1. stocks['公司中文4']=stocks.apply(
    2. lambda x:dict_company_names[x['公司'].lower()],
    3. axis=1
    4. )
    5. stocks.head()

     36356aea4b384370b70c3e493c328f63.png

     

    注意这个代码:

    1. 1、apply是在stocks这个DataFrame上调用;
    2. 2lambda x的x是一个Series,因为指定了axis=1所以Seires的key是列名,可以用x[公司"]获取

    3.applymap用于DataFrame所有值的转换

    1. sub_df=stocks[['收盘','开盘','高','低','交易量']]
    2. sub_df.head()

    2ec826eab60f4ff2aab6e78d43b3df73.png

    1. #将这些数字取整数,应用于所有元素
    2. sub_df.applymap(lambda x:int(x))

     23239aaf8e2f4851b86526033eef6664.png

    1. #直接修改原df的这几列
    2. stocks.loc[:,['收盘','开盘','高','低','交易量']]=sub_df.applymap(lambda x:int(x))
    3. stocks.head()

    257a8cbdeb5e40558b3aa5633d7a6fa7.png

    十八、Pandas如何对每个分组应用apply函数

    0、 Pandas怎样对每个分组应用apply函数?

    知识:Pandas的GroupBy遵从split、apply.combine模式

    71759e81209045579db47b0ea3c733f9.png

    这里的split指的是pandas的groupby,我们自己实现apply函数,apply返回的结果由pandas进行combine得到结果

    GroupBy.apply(function)

    . function的第一个参数是dataframe

    . function的返回结果,可是dataframe、series、单个值,甚至和输入dataframe完全没关系

    本次内容:

    1.怎样对数值列按分组的归—化?

    2.怎样取每个分组的TOPN数据?

    实例1:怎样对数值列按分组的归一化?

    将不同范围的数值列进行归一化,映射到[0,1]区间:

    ·更容易做数据横向对比,比如价格字段是几百到几千,增幅字段是0到100

    ·机器学习模型学的更快性能更好

    归一化的公式:

    8f6724b1db824e5082d3712712b3014a.png

    演示:用户对电影评分的归一化

    每个用户的评分不同,有的乐观派评分高,有的悲观派评分低,按用户做归—化
    1. import pandas as pd
    2. ratings=pd.read_csv(
    3. './datas/movielens-1m/ratings.dat',
    4. sep='::',
    5. engine='python',
    6. names='UserID::MovieID::Rating::Timestamp'.split('::')
    7. )
    8. ratings.head()

     eb233bfead7249a287ec2c04ea6d25b6.png

    1. #实现按照用户ID分组,然后对其中一列进行归一化
    2. def ratings_room(df):
    3. '''
    4. 每个用户分组的dataframe
    5. '''
    6. min_value=df['Rating'].min()
    7. max_value=df['Rating'].max()
    8. df['Rating_rooms']=df['Rating'].apply(
    9. lambda x:(x-min_value)/(max_value-min_value)
    10. )
    11. return df
    12. ratings=ratings.groupby('UserID').apply(ratings_room)
    13. ratings.head()

    97adf11b925740d7b878c04770729b67.png

    ratings[ratings['UserID']==1].head()

    510d3a6a58054332a2d2193e92c6eb67.png

    看到UserID==1这个用户,Rating==3是他的最低分,是个乐观派,我们归一化到0分

    实例2:怎样取每个分组的TOPN数据?

    获取2018年每个月温度最高的2天数据

    1. df=pd.read_csv(
    2. './datas/beijing_tianqi/beijing_tianqi_2018.csv'
    3. )
    4. df.loc[:,'bWendu']=df['bWendu'].str.replace('℃','').astype('int32')
    5. df.loc[:,'yWendu']=df['yWendu'].str.replace('℃','').astype('int32')
    6. #创建一个新的列为月份列
    7. df['month']=df['ymd'].str[:7]
    8. df

    a4f17b50116142039c95fcc0e09dfe17.png

    1. def getWenduTopn(df,topn):
    2. '''
    3. 这里的df,是每个月份分组的group的df
    4. '''
    5. df2=df.sort_values(by='bWendu')[['ymd','bWendu']][-topn:]
    6. return df2
    7. df.groupby('month').apply(getWenduTopn,topn=2).head()

    c5c9cb8a3b544f6696d5304697130e0f.png

    十九、Pandas使用stack和pivot实现数据透视

     0、Pandas的stack和pivot实现数据透视

    将列式数据变成二维交叉形式,便于分析,叫做重塑或透视

    4aad53c97cf74d12ac89b0bf86d6af40.png

    1.经过统计得到多维度指标数据

    2.使用unstack实现数据二维透视

    3.使用pivot简化透视

    4.stack、unstack、pivot的语法

    1.经过统计得到多维度指标数据

    非常场景的统计场景,指定多个维度,计算聚合后的指标

    实例:统计得到"电影评分数据集”,每个月份的每个分数被评分多少次:(月份、分数1~5、次数)

    1. import pandas as pd
    2. import numpy as np
    3. %matplotlib inline
    1. df=pd.read_csv(
    2. './datas/movielens-1m/ratings.dat',
    3. sep='::',
    4. engine='python',
    5. names='UserID::MovieID::Rating::Timestamp'.split('::')
    6. )
    7. df.head()

    afceacf02c0e403ebcfdaf86db4e58c4.png

    1. df['pdata']=pd.to_datetime(df['Timestamp'],unit='s')
    2. df.head()

     db7d76cb36de47979bcc7590e8bb8cfe.png

     

    df.dtypes
    1. #实现数据统计
    2. df_group=df.groupby([df['pdata'].dt.month,'Rating'])['UserID'].agg(pv=np.sum)
    3. df_group.head()

    b7327da6432e4720bc0d2eba61c42001.png

     

    对于这样的格式数据,查看按月份,不同评分的次数趋势,是没法实现的

    需要将数据变换成每个评分是一列才可以实现

    2.使用unstack实现数据二维透视

    目的:想要画图对比按照月份的不同评分的数量趋势

    1. df_stack=df_group.unstack()
    2. df_stack

    1cc8d909f6a0437f996baf5b553885dc.png

     

    df_stack.plot()

    d7cfacb00146415f9d022970548d057b.png

     

    1. #unstack和stack是互逆操作
    2. df_stack.stack().head()

    acb32051e9cf46c889947c5bbac2ff84.png

     3、使用pivot简化透视

    df_group.head()
    1. df_reset=df_group.reset_index()
    2. df_reset.head()

    1d43f21df9ac45a69e891a99188844eb.png

    1. #因为是二维的---pdata代表x轴,Rating代表y轴,pv代表数据
    2. df_pivot=df_reset.pivot('pdata','Rating','pv')
    3. df_pivot.head()

     af7814b0264144a2a8ae722a5c74aa50.png

    df_pivot.plot()

     b13ed55619ec4af5afc171f6907756d8.png

    pivot方法相当于对df使用set_index的创建分层索引,然后调用unstack

    4.stack、unstack、pivot的语法

    stack: DataFrame.stack(level=-1, dropna=True),将column变成index,类似把横放的书籍变成竖放

    level=-1代表多层索引的最内层,可以通过==0、1、2指定多层索引的对应层

     2dd53b9317de45899187ebb0279f3409.png

     

    unstack: DataFrame.unstack(level=-1, fill_value=None),将index变成column,类似把竖放的书籍变成横放

    b2d3d1eedfa84906bc8a6e532931e917.png

    pivot: DataFrame.pivot(index=None , columns=None, values=None),指定index、columns、values实现二维透视 

    61984caa568e4a8db87492d3c8aa35ed.png

     

     

  • 相关阅读:
    rsync远程同步
    java毕业设计爱宠医院管理系统mybatis+源码+调试部署+系统+数据库+lw
    低代码引擎半岁啦,来跟大家唠唠嗑...
    【Linux】环境变量
    Python内置函数/方法详解—元组tuple
    html静态网站基于动漫主题网站网页设计与实现共计10个页面——二次元漫画
    React魔法堂:echarts-for-react源码略读
    如何进行网站测试
    了解list
    【贪心 || 动态规划】最长对数链
  • 原文地址:https://blog.csdn.net/qq_46044325/article/details/126923779