[python]14、五万字详细讲解pandas的所有功能和用法以及安装jupyter

目录

1、安装jupyter

1.1、启用jupyter

2、 pandas介绍

2.1、pip3和pip的区别

2.2、pip或者pip3换源

2.2.1、临时修改

2.2.2、永久修改

2.2.3、国内其他pip源

3、Pandas数据结构

3.1、Series

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

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

3.1.3、使用python字典创建Series

3.1.4、 根据标签索引查询数据

3.2、DataFrame

3.2.1、根据多个字典序列创建dataframe

3.2.2、从文件、mysql中读取创建dataframe

4、pandas的基本功能(pandas命令总结)

4.1、命令执行

4.2、查看信息类函数

4.3、数据统计类函数

5、Pandas查询选取数据

5.1、Pandas查询数据的几种方法

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

5.2.1、df[]

5.2.2、df.loc方法查询

5.2.3、df.iloc方法查询

6、Pandas的数据转换函数map、apply、applymap  ⭐⭐⭐

6.1、map用于Series值的转化

6.1.1、方法1:Series.map(dict)

6.1.2、方法2:Series.map(function)

6.2、apply用于Series和DataFrame的转换

6.2.1、Series.apply(function)

6.2.2、DataFrame.apply(function)

6.3、applymap用于DataFrame所有值的转换

7、Pandas怎样新增数据列?

7.1、直接赋值的方法

7.2、df.apply方法

7.3、df.assign方法

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

8、Pandas对缺失值的处理

8.1、读取excel的时候,忽略前几个行

8.2、检测空值

8.3、删除掉全是空值的列

8.4、删除掉全是空值的行

8.5、将分数列为空的填充为0分

8.6、将姓名的缺失值填充

8.7、将清洗好的excel保存

9、Pandas数据排序

9.1、读取数据

9.2、Series的排序

9.3、DataFrame的排序

9.3.1、单排序

9.3.2、多列排序

10、Pandas怎样实现DataFrame的Merge

10.1、理解merge时数量的对齐关系

10.1.1、one-to-one 一对一关系的merge

10.1.2、one-to-many 一对多关系的merge

10.1.3、many-to-many 多对多关系的merge

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

10.2.1、inner join,默认为这个

10.2.2、left join

10.2.3、right join

10.2.4、outer join

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

11、Pandas实现数据的合并concat

11.1、使用pandas.concat合并数据

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

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

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

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

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

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

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

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

11.3、merge和concat的区别

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

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

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

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

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

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

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

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

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

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

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

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

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

13、Pandas处理日期数据

13.1、读取天气数据到dataframe

13.2、将日期列转换成pandas的日期

13.3、方便的对DatetimeIndex进行查询

13.4、生成日期范围

13.5、方便的获取周、月、季度

13.6、统计每周、每月、每个季度的最高温度

13.6.1、统计每周的数据

13.6.2、统计每个月的数据

13.6.3、统计每个季度的数据

13.7、python中时间日期格式化符号


思维导图:

准备工作:

链接:https://pan.baidu.com/s/1njXR5DK1REh5xqSMMrRUWw 
提取码:nlxx

下面的文件都需要用到这个文件夹

1、安装jupyter

在windows里使用"win+r",弹窗出来之后敲击"cmd",输入"pip install jupyter"就能够安装了。若是使用的是国外源且下载速度较慢的话,我们可以使用"pip install -i + 国内源 + jupyter",来切换国内源,这样的话,下载速度就比较快了。

1.1、启用jupyter

我们需要下载最上边提供的链接文件,并且在这个文件里"Git Bash Here"

进入Git之后,输入下面的内容

$ jupyter notebook

执行上边的代码之后,会弹出一个窗口,然后执行就会得到下边的内容

2、 pandas介绍

python数据分析三剑客:numpy、pandas、Matplotlib

NumPy(Numerical Python):Python语言的一个扩展程序库,支持大量的维度数据与矩阵运算,针对数组提供大量的数学函数库 Pandas是一个强大的分析结构化数据的工具集;它的使用基础是Numpy(提供高性能的矩阵运算);用于数据挖掘和数据分析,同时也提供数据清洗功能。 Matplotlib是一个python绘图包

pandas安装: 1、下载使用Python类库集成安装包:anaconda https://www.anaconda.com 当今最流行的Python数据分析发行版 已经安装了数据分析需要的几乎所有的类库

2、pip3 install pandas

本课程演示方式 使用jupyter Jupyter Notebook 的本质是一个 Web 应用程序,便于创建和共享文学化程序文档,支持实时代码,数学方程,可视化和 markdown。 安装: pip3 install jupyter(需要python3.3或更高版本,或python2.7) 运行: jupyter notebook

2.1、pip3和pip的区别

使用pip install XXX
新安装的库会放在这个目录下面
python2.7/site-packages
使用pip3 install XXX
新安装的库会放在这个目录下面
python3.6/site-packages
如果使用python3执行程序,那么就不能import python2.7/site-packages中的库
那么问题来了,我没有py2.7啊
经过实践发现应该是这样的,应该是将包安装在路径里面第一个检索到的pip系列软件在的地方。

由图可以看到,我在一个没有pip的地方pip3了selenium包,所以,它自动检索,将包安装在了pip3第一次出现的地方。 c:\users\challenger\appdata\local\programs\python\python36\lib\site-packages
而且你用pip show是看不到相关信息的,只有pip3 show才行。
而在使用 pip 安装后


大家可以看到,安装位置已经变成:Location: d:\program\anaconda\envs\python36fordrl\lib\site-packages
因此,这也提示我们在使用pip包安装的时候,应该想好用哪个命令
原理
这个是我想起c语言里面 include“”和inluce<>的异同,一个首先检索当前路径是否有相关文件,一个直接进path环境变量里的库检索文件。
而这里也是如此,如果环境里有相关函数则直接使用,没有则到path路径找第一个符合的函数

2.2、pip或者pip3换源

因为国外源下载很慢,所以我们需要换国内源下载

2.2.1、临时修改

# 临时换为清华源下载
pip3 install  库名 -i https://pypi.tuna.tsinghua.edu.cn/simple

2.2.2、永久修改

首先在当前用户目录下建立文件夹.pip,然后在文件夹中创建pip.conf文件,再将源地址加进去即可。

mkdir ~/.pip
vim ~/.pip/pip.conf
# 然后将下面这两行复制进去就好了
[global]
index-url = https://mirrors.aliyun.com/pypi/simple

注意:不管你用的是pip3还是pip,方法都是一样的,都是创建pip文件夹。

2.2.3、国内其他pip源

  • 清华大学:https://pypi.tuna.tsinghua.edu.cn/simple
  • 阿里云:http://mirrors.aliyun.com/pypi/simple/ 
  • 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/
  • 华中理工大学:http://pypi.hustunique.com/
  • 山东理工大学:http://pypi.sdutlinux.org/
  • 豆瓣:http://pypi.douban.com/simple/

3、Pandas数据结构

3.1、Series

Series是一种类似于一维数组的对象,它由一组数据(不同数据类型)以及一组与之相关的数据标签(即索引)组成。Seriers的交互式显示的字符串表示形式是索引在左边,值在右边。 类似一个有序的字典。

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

>>> import pandas as pd
>>> s1 = pd.Series([1,5,2,7,'a'])
>>> s1
0    1
1    5
2    2
3    7
4    a
dtype: object  
#查看每列数据类型,object为通用数据类型,一般某列中有多种数据类型,或者全为str,则类型为object。默认int、float类型的位数为操作系统位数。
########################
>>> s1 = pd.Series([1,5,2,7])
>>> s1
0    1
1    5
2    2
3    7
dtype: int64
######################
# 获得索引
>>> s1.index
RangeIndex(start=0, stop=4, step=1)
######################
# 获得数据
>>> s1.values
array([1, 5, 2, 7])
>>> s1[0]
1
>>> s1[1]
5

改变s1中的一些类型,会强制改变总的数据类型变为一致的。所以Series的数据类型是统一的。

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

>>> s2 = pd.Series([1, 'a', 5.2, 7], index=['d','b','a','c'])
>>> s2
d      1
b      a
a    5.2
c      7
dtype: object
>>> s2.index
Index(['d', 'b', 'a', 'c'], dtype='object')

# 可以重复标签
>>> s2 = pd.Series([1, 'a', 5.2, 7], index=['d','b','a','a'])
>>> s2
d      1
b      a
a    5.2
a      7
dtype: object

3.1.3、使用python字典创建Series

类似Python的字典dict

>>> sdata={"a":35000,"b":7200,"c":16000,"d":5000}
>>> sdata
{'a': 35000, 'b': 7200, 'c': 16000, 'd': 5000}
>>> s3 = pd.Series(sdata)
>>> s3
a    35000
b     7200
c    16000
d     5000
dtype: int64

3.1.4、 根据标签索引查询数据

>>> s2 = pd.Series([1, 'a', 5.2, 7], index=['d','b','a','c'])
>>> s2
d      1
b      a
a    5.2
c      7
dtype: object
>>> s2["a"]
5.2
>>> type(s2["a"])
<class 'float'>

>>> s2[["b","a"]]
b      a
a    5.2
dtype: object
>>> type(s2[["b","a"]])
<class 'pandas.core.series.Series'>

3.2、DataFrame

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

  • 每列可以是不同的值类型(数值、字符串、布尔值等)
  • 既有行索引index,也有列索引columns
  • 可以被看做由Series组成的字典

3.2.1、根据多个字典序列创建dataframe

>>> data={
...         'state':['Ohio','Ohio','Ohio','Nevada','Nevada'],
...         'year':[2000,2001,2002,2001,2002],
...         'pop':[1.5,1.7,3.6,2.4,2.9]
...     }
>>> df = pd.DataFrame(data)
>>> df
    state  year  pop
0    Ohio  2000  1.5
1    Ohio  2001  1.7
2    Ohio  2002  3.6
3  Nevada  2001  2.4
4  Nevada  2002  2.9
>>> df.dtypes
state     object
year       int64
pop      float64
dtype: object
>>> df.columns  # 查看有几个列
Index(['state', 'year', 'pop'], dtype='object')
>>> df.index
RangeIndex(start=0, stop=5, step=1)
>>> df['state']
0      Ohio
1      Ohio
2      Ohio
3    Nevada
4    Nevada
Name: state, dtype: object
>>> df['state'][1]
'Ohio'
>>> df[['state','year']]  # 拿多列的话,要使用"[[]]"
    state  year
0    Ohio  2000
1    Ohio  2001
2    Ohio  2002
3  Nevada  2001
4  Nevada  2002

3.2.2、从文件、mysql中读取创建dataframe

  • 读取csv、txt文件 --> read_csv() 
  • 读取xlsx文件 --> read_excel() 
  • 读取mysql数据库 --> read_sql()
  • 从网页读取table -->read_html()
>>> fpath = '/root/linux/script/pass_parameter/datas/read_test.csv'  
>>> df = pd.read_csv(fpath)
>>> df
          date   prov    isp    pv    uv
0   2020-04-26  hunan  cmnet  2000  1000
1   2020-04-26  hunan  cmnet  3000  1500
2   2020-04-26  hunan   cmcc  4000  1000
3   2020-04-26  hubei    ctc  2500  1000
4   2020-04-26  hubei   cmcc  2000  1000
5   2020-04-26  hubei    ctc  2100  1600
6   2020-04-27  hunan  cmnet  4000  1700
7   2020-04-27  hunan  cmnet  3200  1500
8   2020-04-27  hunan   cmcc  2800  1600
9   2020-04-27  hubei    ctc  2600  1400
10  2020-04-27  hubei   cmcc  3800  1900
11  2020-04-27  hubei    ctc  2400  1900

🚀[从网页中拉取table数据]🚀

>>> url = 'http://ranking.promisingedu.com/qs'
>>> df = pd.read_html(url)[0]
>>> df
     Ranking                      University English Name  ... Overall Score  Free
0          1  Massachusetts Institute of Technology (MIT)  ...         100.0  免费评估
1          2                     牛津大学University of Oxford  ...          99.5  免费评估
2          3                          Stanford University  ...          98.7  免费评估
3          3                  剑桥大学University of Cambridge  ...          98.7  免费评估
4          5                           Harvard University  ...          98.0  免费评估
..       ...                                          ...  ...           ...   ...
496      494                           Dongguk University  ...          24.1  免费评估
497      494                        Iowa State University  ...          24.1  免费评估
498      494                            Sogang University  ...          24.1  免费评估
499      494             University of Rome "Tor Vergata"  ...          24.1  免费评估
500      494                              York University  ...          24.1  免费评估

[501 rows x 11 columns]

🚀[从数据库中拉取]🚀

🚀[新加内容到数据库里边]🚀

4、pandas的基本功能(pandas命令总结)

  1. DataFrame() 创建一个DataFrame对象
  2. df.values 返回ndarray类型的对象
  3. df.shape 返回行列数
  4. df.index 获取行索引
  5. df.set_index 设置索引
  6. df.reset_index 重制索引
  7. df.columns 获取列索引
  8. df.rename 重新设置列名
  9. df.dtypes 查看每列数据类型
  10. df.axes 获取行及列索引
  11. df.T 行与列对调
  12. df.info() 打印DataFrame对象的信息
  13. df.head(i) 显示前 i 行数据
  14. df.tail(i) 显示后 i 行数据
  15. df.count() # 返回每一列中的非空值的个数
  16. df.value_counts() # 按值计数
  17. df.unique() # 唯一去重
  18. df.describe() 查看数据按列的统计信息
  19. df.sum() # 返回每一列的和, 无法计算返回空, 下同
  20. df.sum(numeric_only=True) # numeric_only=True代表只计算数字型元素, 下同
  21. df.max() # 返回每一列的最大值
  22. df.min() # 返回每一列的最小值
  23. df.argmax() # 返回最大值所在的自动索引位置,就是从0开始的系统下标
  24. df.argmin() # 返回最小值所在的自动索引位置
  25. df.idxmax() # 返回最大值所在的自定义索引位置
  26. df.idxmin() # 返回最小值所在的自定义索引位置
  27. df.mean() # 返回每一列的均值
  28. df.median() # 返回每一列的中位数
  29. df.var() # 返回每一列的方差
  30. df.std() # 返回每一列的标准差
  31. df.isnull() # 检查df中空值, NaN为True, 否则False, 返回一个布尔数组
  32. df.notnull() # 检查df中空值, 非NaN为True, 否则False, 返回一个布尔数组

4.1、命令执行

pf是一个可变数据类型,若是我们使用"df2=df"的形式来给df2赋值的话,df改变那么df2也会发生改变

>>> fpath = '/root/linux/script/pass_parameter/datas/read_test.csv'  # 这个路径是安装本文章中最上边这个链接的文件路径
>>> df = pd.read_csv(fpath) # 用csv格式打开这个文件
>>> df
          date   prov    isp    pv    uv
0   2020-04-26  hunan  cmnet  2000  1000
1   2020-04-26  hunan  cmnet  3000  1500
2   2020-04-26  hunan   cmcc  4000  1000
3   2020-04-26  hubei    ctc  2500  1000
4   2020-04-26  hubei   cmcc  2000  1000
5   2020-04-26  hubei    ctc  2100  1600
6   2020-04-27  hunan  cmnet  4000  1700
7   2020-04-27  hunan  cmnet  3200  1500
8   2020-04-27  hunan   cmcc  2800  1600
9   2020-04-27  hubei    ctc  2600  1400
10  2020-04-27  hubei   cmcc  3800  1900
11  2020-04-27  hubei    ctc  2400  1900

[把df赋值给其他变量]

>>> df
          date   prov    isp    pv    uv
0   2020-04-26  hunan  cmnet  2000  1000
1   2020-04-26  hunan  cmnet  3000  1500
2   2020-04-26  hunan   cmcc  4000  1000
3   2020-04-26  hubei    ctc  2500  1000
4   2020-04-26  hubei   cmcc  2000  1000
5   2020-04-26  hubei    ctc  2100  1600
6   2020-04-27  hunan  cmnet  4000  1700
7   2020-04-27  hunan  cmnet  3200  1500
8   2020-04-27  hunan   cmcc  2800  1600
9   2020-04-27  hubei    ctc  2600  1400
10  2020-04-27  hubei   cmcc  3800  1900
11  2020-04-27  hubei    ctc  2400  1900

4.2、查看信息类函数

# 返回ndarray类型的对象
>>> df.values  
array([['2020-04-26', 'hunan', 'cmnet', 2000, 1000],
       ['2020-04-26', 'hunan', 'cmnet', 3000, 1500],
       ['2020-04-26', 'hunan', 'cmcc', 4000, 1000],
       ['2020-04-26', 'hubei', 'ctc', 2500, 1000],
       ['2020-04-26', 'hubei', 'cmcc', 2000, 1000],
       ['2020-04-26', 'hubei', 'ctc', 2100, 1600],
       ['2020-04-27', 'hunan', 'cmnet', 4000, 1700],
       ['2020-04-27', 'hunan', 'cmnet', 3200, 1500],
       ['2020-04-27', 'hunan', 'cmcc', 2800, 1600],
       ['2020-04-27', 'hubei', 'ctc', 2600, 1400],
       ['2020-04-27', 'hubei', 'cmcc', 3800, 1900],
       ['2020-04-27', 'hubei', 'ctc', 2400, 1900]], dtype=object)
# 查看数据的形状,返回(行数、列数)
>>> df.shape
(12, 5)
#查看行索引
>>> df.index
RangeIndex(start=0, stop=12, step=1)
>>> df2 = df.set_index('date')  # 以"date"作为key排序
>>> df2
             prov    isp    pv    uv
date                                
2020-04-26  hunan  cmnet  2000  1000
2020-04-26  hunan  cmnet  3000  1500
2020-04-26  hunan   cmcc  4000  1000
2020-04-26  hubei    ctc  2500  1000
2020-04-26  hubei   cmcc  2000  1000
2020-04-26  hubei    ctc  2100  1600
2020-04-27  hunan  cmnet  4000  1700
2020-04-27  hunan  cmnet  3200  1500
2020-04-27  hunan   cmcc  2800  1600
2020-04-27  hubei    ctc  2600  1400
2020-04-27  hubei   cmcc  3800  1900
2020-04-27  hubei    ctc  2400  1900
# "inplace=True"表示在原基础上作出修改;"drop=True",表示把行标去掉
>>> df2.reset_index(inplace = True, drop = True)
>>> df2
     prov    isp    pv    uv
0   hunan  cmnet  2000  1000
1   hunan  cmnet  3000  1500
2   hunan   cmcc  4000  1000
3   hubei    ctc  2500  1000
4   hubei   cmcc  2000  1000
5   hubei    ctc  2100  1600
6   hunan  cmnet  4000  1700
7   hunan  cmnet  3200  1500
8   hunan   cmcc  2800  1600
9   hubei    ctc  2600  1400
10  hubei   cmcc  3800  1900
11  hubei    ctc  2400  1900
# 获得列索引
>>> df.columns
Index(['date', 'prov', 'isp', 'pv', 'uv'], dtype='object')
#重新设置列表名,必须要对应输入所有的列
df2 = df.copy()  # 因为DataFrame是可变的数据类型,所以我们要使用copy拷贝他的值
df2.columns=['a','b','c','d','e']
df2

#重新设置列表名,可以只设置一部分
>>>df2.rename(columns = {'a':'日期','b':'省份','c':'运营商','d':'pv','e':'uv'}, inplace = True)
>>> df2
            日期     省份    运营商    pv    uv
0   2020-04-26  hunan  cmnet  2000  1000
1   2020-04-26  hunan  cmnet  3000  1500
2   2020-04-26  hunan   cmcc  4000  1000
3   2020-04-26  hubei    ctc  2500  1000
4   2020-04-26  hubei   cmcc  2000  1000
5   2020-04-26  hubei    ctc  2100  1600
6   2020-04-27  hunan  cmnet  4000  1700
7   2020-04-27  hunan  cmnet  3200  1500
8   2020-04-27  hunan   cmcc  2800  1600
9   2020-04-27  hubei    ctc  2600  1400
10  2020-04-27  hubei   cmcc  3800  1900
11  2020-04-27  hubei    ctc  2400  1900
#查看每列数据类型,object为通用数据类型,一般某列中有多种数据类型,或者全为str,则类型为object。默认int、float类型的位数为操作系统位数。
>>> df.dtypes
date    object
prov    object
isp     object
pv       int64
uv       int64
dtype: object
##################################
# 显示行和列表以及类型
>>> df.axes
[RangeIndex(start=0, stop=12, step=1), Index(['date', 'prov', 'isp', 'pv', 'uv'], dtype='object')]
#############################
# 转置,没有在原来基础上做出改变
>>> df.T
              0           1           2           3   ...          8           9           10          11
date  2020-04-26  2020-04-26  2020-04-26  2020-04-26  ...  2020-04-27  2020-04-27  2020-04-27  2020-04-27
prov       hunan       hunan       hunan       hubei  ...       hunan       hubei       hubei       hubei
isp        cmnet       cmnet        cmcc         ctc  ...        cmcc         ctc        cmcc         ctc
pv          2000        3000        4000        2500  ...        2800        2600        3800        2400
uv          1000        1500        1000        1000  ...        1600        1400        1900        1900

[5 rows x 12 columns]
###########################
>>> df.head(5)
         date   prov    isp    pv    uv
0  2020-04-26  hunan  cmnet  2000  1000
1  2020-04-26  hunan  cmnet  3000  1500
2  2020-04-26  hunan   cmcc  4000  1000
3  2020-04-26  hubei    ctc  2500  1000
4  2020-04-26  hubei   cmcc  2000  1000
>>> df.tail(5)
          date   prov    isp    pv    uv
7   2020-04-27  hunan  cmnet  3200  1500
8   2020-04-27  hunan   cmcc  2800  1600
9   2020-04-27  hubei    ctc  2600  1400
10  2020-04-27  hubei   cmcc  3800  1900
11  2020-04-27  hubei    ctc  2400  1900
# 只对数值类进行计算。这些百分号表示箱型图的意思
>>> df.describe()
                pv           uv
count    12.000000    12.000000
mean   2866.666667  1425.000000
std     743.863787   346.738046
min    2000.000000  1000.000000
25%    2325.000000  1000.000000
50%    2700.000000  1500.000000
75%    3350.000000  1625.000000
max    4000.000000  1900.000000

4.3、数据统计类函数

# 返回每一列中的非空值的个数
>>> df.count()
date    12
prov    12
isp     12
pv      12
uv      12
dtype: int64
##########################
# 按值计数
>>> df["prov"].value_counts()
hunan    6
hubei    6
Name: prov, dtype: int64
#############
# 唯一去重
>>> df["prov"].unique()
array(['hunan', 'hubei'], dtype=object)

5、Pandas查询选取数据

5.1、Pandas查询数据的几种方法

  1. df[]按行列选取,这种情况一次只能选取行或者列
  2. df.loc方法,根据行、列的标签值查询
  3. df.iloc方法,根据行、列的数字位置查询,根据索引定位
  4. df.query方法

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

  1. 使用单个label值查询数据
  2. 使用值列表批量查询
  3. 使用数值区间进行范围查询
  4. 使用条件表达式查询
  5. 调用函数查询

注意:以上查询方法,既适用于行,也适用于列

5.2.1、df[]

df[]按行列选取,这种情况一次只能选取行或者列

>>> df = pd.DataFrame(np.random.rand(25).reshape([5, 5]), index=['A', 'B', 'C', 'D', 'E'], columns=['c1', 'c2', 'c3', 'c4', 'c5'])
>>> df
         c1        c2        c3        c4        c5
A  0.678642  0.600271  0.715437  0.613857  0.618137
B  0.326720  0.742239  0.124217  0.844608  0.560314
C  0.199805  0.614843  0.521589  0.530966  0.166661
D  0.575750  0.592821  0.492156  0.200419  0.437495
E  0.863142  0.480158  0.339556  0.904514  0.955364

###################
# 获取c1列
>>> df.c1
A    0.678642
B    0.326720
C    0.199805
D    0.575750
E    0.863142
Name: c1, dtype: float64

###################
# 获取c1、c2两列
>>> df[["c1","c2"]]
         c1        c2
A  0.678642  0.600271
B  0.326720  0.742239
C  0.199805  0.614843
D  0.575750  0.592821
E  0.863142  0.480158

##########################
# 获取索引为A-C行数据
>>> df["A":"C"]
         c1        c2        c3        c4        c5
A  0.678642  0.600271  0.715437  0.613857  0.618137
B  0.326720  0.742239  0.124217  0.844608  0.560314
C  0.199805  0.614843  0.521589  0.530966  0.166661

##########################
# 获取2-3行数据,左闭右开
>>> df[1:3]
         c1        c2        c3        c4        c5
B  0.326720  0.742239  0.124217  0.844608  0.560314
C  0.199805  0.614843  0.521589  0.530966  0.166661

5.2.2、df.loc方法查询

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

(1)使用数据值区间进行范围查询

有点类似list的切片

# 前边确定行,后边确定列
>>> df.loc["A":"D", :]
         c1        c2        c3        c4        c5
A  0.678642  0.600271  0.715437  0.613857  0.618137
B  0.326720  0.742239  0.124217  0.844608  0.560314
C  0.199805  0.614843  0.521589  0.530966  0.166661
D  0.575750  0.592821  0.492156  0.200419  0.437495
>>> df.loc["A":"D","c1"]
A    0.678642
B    0.326720
C    0.199805
D    0.575750
Name: c1, dtype: float64
>>> df.loc["A":"D","c1":"c3"]
         c1        c2        c3
A  0.678642  0.600271  0.715437
B  0.326720  0.742239  0.124217
C  0.199805  0.614843  0.521589
D  0.575750  0.592821  0.492156

(2)单个label值查询

>>> df.loc["A","c2"]
0.6002706557290689

(3)使用列表批量查询

>>> df.loc['B':'D','c5':'c1':-1]
         c5        c4        c3        c2        c1
B  0.560314  0.844608  0.124217  0.742239  0.326720
C  0.166661  0.530966  0.521589  0.614843  0.199805
D  0.437495  0.200419  0.492156  0.592821  0.575750

(4)使用条件表达式查询

# 找出c2中所有大于0.5的值,并且输出符合条件的全部表格内容
>>> df.loc[df["c2"]>0.5,:]
         c1        c2        c3        c4        c5
A  0.678642  0.600271  0.715437  0.613857  0.618137
B  0.326720  0.742239  0.124217  0.844608  0.560314
C  0.199805  0.614843  0.521589  0.530966  0.166661
D  0.575750  0.592821  0.492156  0.200419  0.437495
#########################
>>> df.loc[(df["c2"]>0.2) & (df["c3"]< 0.8)]
         c1        c2        c3        c4        c5
A  0.678642  0.600271  0.715437  0.613857  0.618137
B  0.326720  0.742239  0.124217  0.844608  0.560314
C  0.199805  0.614843  0.521589  0.530966  0.166661
D  0.575750  0.592821  0.492156  0.200419  0.437495
E  0.863142  0.480158  0.339556  0.904514  0.955364

(5)使用函数查询

>>> def query_my_data(df):
...     return ((df['c3']>0.2) & (df["c4"]<0.8))
... 
##################
>>> query_my_data
<function query_my_data at 0x7f24aff36d08>
######################
>>> df.loc[query_my_data, :]
         c1        c2        c3        c4        c5
A  0.678642  0.600271  0.715437  0.613857  0.618137
C  0.199805  0.614843  0.521589  0.530966  0.166661
D  0.575750  0.592821  0.492156  0.200419  0.437495

5.2.3、df.iloc方法查询

同df.loc类似,根据索引定位 

# 提取2-3行,1-2列的数据
>>> df.iloc[1:3,0:2]
         c1        c2
B  0.326720  0.742239
C  0.199805  0.614843
##############################
# 提取第二第三行,第4列数据
>>> df.iloc[[1,2],[3]]
         c4
B  0.844608
C  0.530966
########################
# 提取指定位置单个数据
>>> df.iloc[3,4]
0.43749457263810054

6、Pandas的数据转换函数map、apply、applymap  ⭐⭐⭐

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

  1. map:只用于Series,实现每个值->值的映射;
  2. apply:用于Series实现每个值的处理,用于Dataframe实现某个轴的Series的处理;
  3. applymap:只能用于DataFrame,用于处理该DataFrame的每个元素;

准备工作

>>> import pandas as pd
>>> df = pd.read_csv("read_test.csv")
>>> df.head()
         date   prov    isp    pv    uv
0  2020-04-26  hunan  cmnet  2000  1000
1  2020-04-26  hunan  cmnet  3000  1500
2  2020-04-26  hunan   cmcc  4000  1000
3  2020-04-26  hubei    ctc  2500  1000
4  2020-04-26  hubei   cmcc  2000  1000

6.1、map用于Series值的转化

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

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

isp中文映射,注意这里是小写

>>> dict_isp_names = {
...     "cmnet": "中国移动",
...     "cmcc": "中国联通",
...     "ctc": "中国电信"
... }

6.1.1、方法1:Series.map(dict)

# map函数只对Series生效
>>> df["isp1"]=df["isp"].map(dict_isp_names)
>>> df.head()
         date   prov    isp    pv    uv  isp1
0  2020-04-26  hunan  cmnet  2000  1000  中国移动
1  2020-04-26  hunan  cmnet  3000  1500  中国移动
2  2020-04-26  hunan   cmcc  4000  1000  中国联通
3  2020-04-26  hubei    ctc  2500  1000  中国电信
4  2020-04-26  hubei   cmcc  2000  1000  中国联通

6.1.2、方法2:Series.map(function)

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

>>> df["isp2"]=df["isp"].map(lambda x : dict_isp_names[x])
>>> df.head()
         date   prov    isp    pv    uv  isp1  isp2
0  2020-04-26  hunan  cmnet  2000  1000  中国移动  中国移动
1  2020-04-26  hunan  cmnet  3000  1500  中国移动  中国移动
2  2020-04-26  hunan   cmcc  4000  1000  中国联通  中国联通
3  2020-04-26  hubei    ctc  2500  1000  中国电信  中国电信
4  2020-04-26  hubei   cmcc  2000  1000  中国联通  中国联通
>>> df['float_column'] = 5.67435  # 没有那列的话,会自动添加
>>> df.head()
         date   prov    isp    pv    uv  isp1  isp2  float_column
0  2020-04-26  hunan  cmnet  2000  1000  中国移动  中国移动       5.67435
1  2020-04-26  hunan  cmnet  3000  1500  中国移动  中国移动       5.67435
2  2020-04-26  hunan   cmcc  4000  1000  中国联通  中国联通       5.67435
3  2020-04-26  hubei    ctc  2500  1000  中国电信  中国电信       5.67435
4  2020-04-26  hubei   cmcc  2000  1000  中国联通  中国联通       5.67435
>>> df['float_column_1'] = df['float_column'].map(lambda x: '%.3f'%x)
>>> df.head()
         date   prov    isp    pv    uv  isp1  isp2  float_column float_column_1
0  2020-04-26  hunan  cmnet  2000  1000  中国移动  中国移动       5.67435          5.674
1  2020-04-26  hunan  cmnet  3000  1500  中国移动  中国移动       5.67435          5.674
2  2020-04-26  hunan   cmcc  4000  1000  中国联通  中国联通       5.67435          5.674
3  2020-04-26  hubei    ctc  2500  1000  中国电信  中国电信       5.67435          5.674
4  2020-04-26  hubei   cmcc  2000  1000  中国联通  中国联通       5.67435          5.674

6.2、apply用于Series和DataFrame的转换

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

6.2.1、Series.apply(function)

function的参数是Series的每个值

>>> df["isp3"]=df["isp"].apply(lambda x : dict_isp_names[x])
>>> df.head()
         date   prov    isp    pv    uv  isp1  isp2  float_column float_column_1  isp3
0  2020-04-26  hunan  cmnet  2000  1000  中国移动  中国移动       5.67435          5.674  中国移动
1  2020-04-26  hunan  cmnet  3000  1500  中国移动  中国移动       5.67435          5.674  中国移动
2  2020-04-26  hunan   cmcc  4000  1000  中国联通  中国联通       5.67435          5.674  中国联通
3  2020-04-26  hubei    ctc  2500  1000  中国电信  中国电信       5.67435          5.674  中国电信
4  2020-04-26  hubei   cmcc  2000  1000  中国联通  中国联通       5.67435          5.674  中国联通

6.2.2、DataFrame.apply(function)

function的参数是对应轴的Series

>>> df["total"]=df[["pv","uv"]].apply(lambda x : x.sum(), axis=1)
>>> df.head()
         date   prov    isp    pv    uv  isp1  isp2  float_column float_column_1  isp3  total
0  2020-04-26  hunan  cmnet  2000  1000  中国移动  中国移动       5.67435          5.674  中国移动   3000
1  2020-04-26  hunan  cmnet  3000  1500  中国移动  中国移动       5.67435          5.674  中国移动   4500
2  2020-04-26  hunan   cmcc  4000  1000  中国联通  中国联通       5.67435          5.674  中国联通   5000
3  2020-04-26  hubei    ctc  2500  1000  中国电信  中国电信       5.67435          5.674  中国电信   3500
4  2020-04-26  hubei   cmcc  2000  1000  中国联通  中国联通       5.67435          5.674  中国联通   3000

注意这个代码:
1、apply是在df[['pv','uv']]这个DataFrame上调用;
2、lambda x的x是一个Series,axis=1表示跨列,axis=0 表示跨行 

>>> df.loc['total'] = df[['pv','uv']].apply(lambda x : x.sum(), axis = 0)
>>> df.tail()
             date   prov   isp       pv       uv  isp1  isp2  float_column float_column_1  isp3   total
8      2020-04-27  hunan  cmcc   2800.0   1600.0  中国联通  中国联通       5.67435          5.674  中国联通  4400.0
9      2020-04-27  hubei   ctc   2600.0   1400.0  中国电信  中国电信       5.67435          5.674  中国电信  4000.0
10     2020-04-27  hubei  cmcc   3800.0   1900.0  中国联通  中国联通       5.67435          5.674  中国联通  5700.0
11     2020-04-27  hubei   ctc   2400.0   1900.0  中国电信  中国电信       5.67435          5.674  中国电信  4300.0
total         NaN    NaN   NaN  34400.0  17100.0   NaN   NaN           NaN            NaN   NaN     NaN

6.3、applymap用于DataFrame所有值的转换

>>> sub_df = df[['pv', 'uv']]
>>> sub_df.head()
       pv      uv
0  2000.0  1000.0
1  3000.0  1500.0
2  4000.0  1000.0
3  2500.0  1000.0
4  2000.0  1000.0
############################
# 将这些数字取整数,应用于所有元素
>>> sub_df = sub_df.applymap(lambda x : int(x))

# 直接修改原df的这几列
>>> sub_df.head()
     pv    uv
0  2000  1000
1  3000  1500
2  4000  1000
3  2500  1000
4  2000  1000

7、Pandas怎样新增数据列?

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

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

准备工作

>>> import pandas as pd

# 读取csv数据到DataFrame
>>> fpath = "beijing_tianqi_2018.csv"
>>> df = pd.read_csv(fpath)
>>> df.head()
          ymd bWendu yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel
0  2018-01-01     3℃    -6℃   晴~多云       东北风   1-2级   59       良         2
1  2018-01-02     2℃    -5℃   阴~多云       东北风   1-2级   49       优         1
2  2018-01-03     2℃    -5℃     多云        北风   1-2级   28       优         1
3  2018-01-04     0℃    -8℃      阴       东北风   1-2级   28       优         1
4  2018-01-05     3℃    -6℃   多云~晴       西北风   1-2级   50       优         1

7.1、直接赋值的方法

实例:清理温度列,变成数据类型

# 替换掉温度的后缀℃
>>> df["bWendu"] = df["bWendu"].str.replace("℃", "").astype('int64')
>>> df["yWendu"] = df["yWendu"].str.replace("℃", "").astype('int64')
>>> df.head()
          ymd  bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel
0  2018-01-01       3      -6   晴~多云       东北风   1-2级   59       良         2
1  2018-01-02       2      -5   阴~多云       东北风   1-2级   49       优         1
2  2018-01-03       2      -5     多云        北风   1-2级   28       优         1
3  2018-01-04       0      -8      阴       东北风   1-2级   28       优         1
4  2018-01-05       3      -6   多云~晴       西北风   1-2级   50       优         1

实例:计算温差

# 注意,df["bWendu"]其实是一个Series,后边的减法返回的是Series
>>> df["wencha"] = df["bWendu"] - df["yWendu"]
>>> df.head()
          ymd  bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel  wencha
0  2018-01-01       3      -6   晴~多云       东北风   1-2级   59       良         2       9
1  2018-01-02       2      -5   阴~多云       东北风   1-2级   49       优         1       7
2  2018-01-03       2      -5     多云        北风   1-2级   28       优         1       7
3  2018-01-04       0      -8      阴       东北风   1-2级   28       优         1       8
4  2018-01-05       3      -6   多云~晴       西北风   1-2级   50       优         1       9

7.2、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. 否则是常温
>>> def get_wendu_type(x):
...     if x["bWendu"] > 33:
...             return "高温"
...     if x["yWendu"] < -10:
...             return '低温'
...     return "常温"
... 

# 注意需要设置axis==1,这是series的index是columns
>>> df["wendu_type"] = df.apply(get_wendu_type,axis=1)

>>> df.head()
          ymd  bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel  wencha wendu_type
0  2018-01-01       3      -6   晴~多云       东北风   1-2级   59       良         2       9         常温
1  2018-01-02       2      -5   阴~多云       东北风   1-2级   49       优         1       7         常温
2  2018-01-03       2      -5     多云        北风   1-2级   28       优         1       7         常温
3  2018-01-04       0      -8      阴       东北风   1-2级   28       优         1       8         常温
4  2018-01-05       3      -6   多云~晴       西北风   1-2级   50       优         1       9         常温

###################
# 查看温度类型的计数
>>> df["wendu_type"].value_counts()
常温    328
高温     29
低温      8
Name: wendu_type, dtype: int64


>>> df2 = df["wendu_type"].value_counts()
>>> for k,v in df2.iteritems():
...     print(k,v)
... 
常温 328
高温 29
低温 8

7.3、df.assign方法

Assign new columns to a DataFrame.(将新列分配给DataFrame。  )

Returns a new object with all original columns in addition to new ones.(返回一个新对象,除新列外,还包含所有原始列 )

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

>>> df.assign(
...     yWendu_huashi = lambda x : x["yWendu"] * 9 / 5 + 32,
...     bWendu_huashi = lambda x : x["bWendu"] * 9 / 5 + 32
... ).head()
          ymd  bWendu  yWendu tianqi fengxiang  ... aqiLevel  wencha wendu_type  yWendu_huashi  bWendu_huashi
0  2018-01-01       3      -6   晴~多云       东北风  ...        2       9         常温           21.2           37.4
1  2018-01-02       2      -5   阴~多云       东北风  ...        1       7         常温           23.0           35.6
2  2018-01-03       2      -5     多云        北风  ...        1       7         常温           23.0           35.6
3  2018-01-04       0      -8      阴       东北风  ...        1       8         常温           17.6           32.0
4  2018-01-05       3      -6   多云~晴       西北风  ...        1       9         常温           21.2           37.4

[5 rows x 13 columns]

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

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

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

# 先创建空列(这是第一种创建新列的方法)
>>> df["wencha_type"] = ''
>>> df.loc[df["bWendu"]-df["yWendu"] > 10, "wencha_type"] = "温差大"
>>> df.loc[df["bWendu"]-df["yWendu"] <= 10, "wencha_type"] = "温差正常"
>>> df.head()
          ymd  bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel  wencha wendu_type wencha_type
0  2018-01-01       3      -6   晴~多云       东北风   1-2级   59       良         2       9         常温        温差正常
1  2018-01-02       2      -5   阴~多云       东北风   1-2级   49       优         1       7         常温        温差正常
2  2018-01-03       2      -5     多云        北风   1-2级   28       优         1       7         常温        温差正常
3  2018-01-04       0      -8      阴       东北风   1-2级   28       优         1       8         常温        温差正常
4  2018-01-05       3      -6   多云~晴       西北风   1-2级   50       优         1       9         常温        温差正常

##############
>>> df["wencha_type"].value_counts()
温差正常    187
温差大     178
Name: wencha_type, dtype: int64

8、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

实列:特殊Excel的读取、清洗、处理。前提准备:安装openpyxl或者xlrd

8.1、读取excel的时候,忽略前几个行

import pandas as pd
########################
>>> studf = pd.read_excel("student_excel.xlsx")
>>> studf
    Unnamed: 0 Unnamed: 1 Unnamed: 2 Unnamed: 3
0          NaN        NaN        NaN        NaN
1          NaN         姓名         科目         分数
2          NaN         小明         语文         85
3          NaN        NaN         数学         80
4          NaN        NaN         英语         90
5          NaN        NaN        NaN        NaN
6          NaN         小王         语文         85
7          NaN        NaN         数学        NaN
8          NaN        NaN         英语         90
9          NaN        NaN        NaN        NaN
10         NaN         小刚         语文         85
11         NaN        NaN         数学         80
12         NaN        NaN         英语         90

############################
>>> studf = pd.read_excel("student_excel.xlsx", skiprows=1)
>>> studf
    Unnamed: 0 Unnamed: 1 Unnamed: 2 Unnamed: 3
0          NaN         姓名         科目         分数
1          NaN         小明         语文         85
2          NaN        NaN         数学         80
3          NaN        NaN         英语         90
4          NaN        NaN        NaN        NaN
5          NaN         小王         语文         85
6          NaN        NaN         数学        NaN
7          NaN        NaN         英语         90
8          NaN        NaN        NaN        NaN
9          NaN         小刚         语文         85
10         NaN        NaN         数学         80
11         NaN        NaN         英语         90


#########################
# skiprows=2,跳过前边两行
studf = pd.read_excel("student_excel.xlsx", skiprows=2)
>>> studf
    Unnamed: 0   姓名   科目    分数
0          NaN   小明   语文  85.0
1          NaN  NaN   数学  80.0
2          NaN  NaN   英语  90.0
3          NaN  NaN  NaN   NaN
4          NaN   小王   语文  85.0
5          NaN  NaN   数学   NaN
6          NaN  NaN   英语  90.0
7          NaN  NaN  NaN   NaN
8          NaN   小刚   语文  85.0
9          NaN  NaN   数学  80.0
10         NaN  NaN   英语  90.0

读取的时候,若是出现“xlrd.biffh.XLRDError: Excel xlsx file; not supported”的情况,那就是你的xlrd版本过高我安装的xlrd版本为2以上的版本,程序报错主要是xlrd的2.0以上版本不支持后缀名.xlsx文件的读取,支持.xls文件的读取。

或者你也可以这么使用

# 两个命令,选其中一个就行了
studf = pd.read_excel("student_excel.xlsx", skiprows=2,engine="openpyxl")
# 或者安装"pip3 install xlrd==1.2.0"的版本,再执行下面那个命令
studf = pd.read_excel("student_excel.xlsx", skiprows=2)

8.2、检测空值

# 没有空值的就为False,有就为True
>>> studf.isnull()
    Unnamed: 0     姓名     科目     分数
0         True  False  False  False
1         True   True  False  False
2         True   True  False  False
3         True   True   True   True
4         True  False  False  False
5         True   True  False   True
6         True   True  False  False
7         True   True   True   True
8         True  False  False  False
9         True   True  False  False
10        True   True  False  False
########################################################
>>> studf["分数"].isnull()
0     False
1     False
2     False
3      True
4     False
5      True
6     False
7      True
8     False
9     False
10    False
Name: 分数, dtype: bool
################################################
>>> studf["分数"].notnull()
0      True
1      True
2      True
3     False
4      True
5     False
6      True
7     False
8      True
9      True
10     True
Name: 分数, dtype: bool
###########################
# 筛选没有空分数的所有行
>>> studf.loc[studf["分数"].notnull(), :]
    Unnamed: 0   姓名  科目    分数
0          NaN   小明  语文  85.0
1          NaN  NaN  数学  80.0
2          NaN  NaN  英语  90.0
4          NaN   小王  语文  85.0
6          NaN  NaN  英语  90.0
8          NaN   小刚  语文  85.0
9          NaN  NaN  数学  80.0
10         NaN  NaN  英语  90.0

8.3、删除掉全是空值的列

# 当列全为NAN就删除这列;当axis为0或者index,则对应行;当为1或者columns,则对应列
>>> studf.dropna(axis="columns", how="all", inplace=True)
>>> studf
     姓名   科目    分数
0    小明   语文  85.0
1   NaN   数学  80.0
2   NaN   英语  90.0
3   NaN  NaN   NaN
4    小王   语文  85.0
5   NaN   数学   NaN
6   NaN   英语  90.0
7   NaN  NaN   NaN
8    小刚   语文  85.0
9   NaN   数学  80.0
10  NaN   英语  90.0

8.4、删除掉全是空值的行

# 用这个方法不会重置原来索引号
>>> studf.dropna(axis="index", how='all', inplace=True)
>>> studf
     姓名  科目    分数
0    小明  语文  85.0
1   NaN  数学  80.0
2   NaN  英语  90.0
4    小王  语文  85.0
5   NaN  数学   NaN
6   NaN  英语  90.0
8    小刚  语文  85.0
9   NaN  数学  80.0
10  NaN  英语  90.0

8.5、将分数列为空的填充为0分

#下面两个命令都可以执行
# studf.loc[:, '分数'] = studf['分数'].fillna(0)
>>> studf["分数"] = studf["分数"].fillna(0)
>>> studf
     姓名  科目    分数
0    小明  语文  85.0
1   NaN  数学  80.0
2   NaN  英语  90.0
4    小王  语文  85.0
5   NaN  数学   0.0
6   NaN  英语  90.0
8    小刚  语文  85.0
9   NaN  数学  80.0
10  NaN  英语  90.0

#############
# method2
>>> studf.fillna({"分数":0})
     姓名  科目    分数
0    小明  语文  85.0
1   NaN  数学  80.0
2   NaN  英语  90.0
4    小王  语文  85.0
5   NaN  数学   0.0
6   NaN  英语  90.0
8    小刚  语文  85.0
9   NaN  数学  80.0
10  NaN  英语  90.0

# method3
>>> studf["分数"].fillna(0)
0     85.0
1     80.0
2     90.0
4     85.0
5      0.0
6     90.0
8     85.0
9     80.0
10    90.0
Name: 分数, dtype: float64

8.6、将姓名的缺失值填充

使用前面的有效值填充,用ffill:forward fill 向后填充,用bfill:before fill,向前填充

>>> studf['姓名'] = studf['姓名'].fillna(method="ffill")
>>> studf
    姓名  科目    分数
0   小明  语文  85.0
1   小明  数学  80.0
2   小明  英语  90.0
4   小王  语文  85.0
5   小王  数学   1.0
6   小王  英语  90.0
8   小刚  语文  85.0
9   小刚  数学  80.0
10  小刚  英语  90.0

8.7、将清洗好的excel保存

studf.to_excel("./datas/student_excel_clean.xlsx", index=False)

9、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

9.1、读取数据

>>> import pandas as pd
>>> fpath = "beijing_tianqi_2018.csv"
>>> df = pd.read_csv(fpath)
>>> df["bWendu"] = df["bWendu"].str.replace("℃", "").astype('int64')
>>> df["yWendu"] = df["yWendu"].str.replace("℃", "").astype('int64')
>>> df.head()
          ymd  bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel
0  2018-01-01       3      -6   晴~多云       东北风   1-2级   59       良         2
1  2018-01-02       2      -5   阴~多云       东北风   1-2级   49       优         1
2  2018-01-03       2      -5     多云        北风   1-2级   28       优         1
3  2018-01-04       0      -8      阴       东北风   1-2级   28       优         1
4  2018-01-05       3      -6   多云~晴       西北风   1-2级   50       优         1

9.2、Series的排序

>>> df["aqi"].sort_values()
271     21
281     21
249     22
272     22
301     22
      ... 
317    266
71     287
91     287
72     293
86     387
Name: aqi, Length: 365, dtype: int64
####################################
>>> df["aqi"].sort_values(ascending=False)
86     387
72     293
91     287
71     287
317    266
      ... 
301     22
272     22
249     22
281     21
271     21
Name: aqi, Length: 365, dtype: int64
####################################
# 用中文的万国码排序的,默认升序
>>> df["tianqi"].sort_values()
225     中雨~小雨
230     中雨~小雨
197    中雨~雷阵雨
196    中雨~雷阵雨
112        多云
        ...  
191    雷阵雨~大雨
219     雷阵雨~阴
335      雾~多云
353         霾
348         霾
Name: tianqi, Length: 365, dtype: object

9.3、DataFrame的排序

9.3.1、单排序

>>> df.sort_values(by='aqi')
            ymd  bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel
271  2018-09-29      22      11      晴        北风   3-4级   21       优         1
281  2018-10-09      15       4   多云~晴       西北风   4-5级   21       优         1
249  2018-09-07      27      16      晴       西北风   3-4级   22       优         1
272  2018-09-30      19      13     多云       西北风   4-5级   22       优         1
301  2018-10-29      15       3      晴        北风   3-4级   22       优         1
..          ...     ...     ...    ...       ...    ...  ...     ...       ...
317  2018-11-14      13       5     多云        南风   1-2级  266    重度污染         5
71   2018-03-13      17       5   晴~多云        南风   1-2级  287    重度污染         5
91   2018-04-02      26      11     多云        北风   1-2级  287    重度污染         5
72   2018-03-14      15       6   多云~阴       东北风   1-2级  293    重度污染         5
86   2018-03-28      25       9   多云~晴        东风   1-2级  387    严重污染         6

[365 rows x 9 columns]
###################################
# 降序排序
>>> df.sort_values(by="aqi", ascending=False)
            ymd  bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel
86   2018-03-28      25       9   多云~晴        东风   1-2级  387    严重污染         6
72   2018-03-14      15       6   多云~阴       东北风   1-2级  293    重度污染         5
71   2018-03-13      17       5   晴~多云        南风   1-2级  287    重度污染         5
91   2018-04-02      26      11     多云        北风   1-2级  287    重度污染         5
317  2018-11-14      13       5     多云        南风   1-2级  266    重度污染         5
..          ...     ...     ...    ...       ...    ...  ...     ...       ...
249  2018-09-07      27      16      晴       西北风   3-4级   22       优         1
301  2018-10-29      15       3      晴        北风   3-4级   22       优         1
272  2018-09-30      19      13     多云       西北风   4-5级   22       优         1
271  2018-09-29      22      11      晴        北风   3-4级   21       优         1
281  2018-10-09      15       4   多云~晴       西北风   4-5级   21       优         1

[365 rows x 9 columns]

9.3.2、多列排序

# 按空气质量等级、最高温度排序,默认升序
>>> df.sort_values(by=["aqiLevel","bWendu"])
            ymd  bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel
360  2018-12-27      -5     -12   多云~晴       西北风     3级   48       优         1
22   2018-01-23      -4     -12      晴       西北风   3-4级   31       优         1
23   2018-01-24      -4     -11      晴       西南风   1-2级   34       优         1
340  2018-12-07      -4     -10      晴       西北风     3级   33       优         1
21   2018-01-22      -3     -10  小雪~多云        东风   1-2级   47       优         1
..          ...     ...     ...    ...       ...    ...  ...     ...       ...
71   2018-03-13      17       5   晴~多云        南风   1-2级  287    重度污染         5
90   2018-04-01      25      11   晴~多云        南风   1-2级  218    重度污染         5
91   2018-04-02      26      11     多云        北风   1-2级  287    重度污染         5
85   2018-03-27      27      11      晴        南风   1-2级  243    重度污染         5
86   2018-03-28      25       9   多云~晴        东风   1-2级  387    严重污染         6

[365 rows x 9 columns]
############################################
# 两个字段都是降序
>>> df.sort_values(by=["aqiLevel","bWendu"],ascending=False)
            ymd  bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel
86   2018-03-28      25       9   多云~晴        东风   1-2级  387    严重污染         6
85   2018-03-27      27      11      晴        南风   1-2级  243    重度污染         5
91   2018-04-02      26      11     多云        北风   1-2级  287    重度污染         5
90   2018-04-01      25      11   晴~多云        南风   1-2级  218    重度污染         5
71   2018-03-13      17       5   晴~多云        南风   1-2级  287    重度污染         5
..          ...     ...     ...    ...       ...    ...  ...     ...       ...
362  2018-12-29      -3     -12      晴       西北风     2级   29       优         1
22   2018-01-23      -4     -12      晴       西北风   3-4级   31       优         1
23   2018-01-24      -4     -11      晴       西南风   1-2级   34       优         1
340  2018-12-07      -4     -10      晴       西北风     3级   33       优         1
360  2018-12-27      -5     -12   多云~晴       西北风     3级   48       优         1

[365 rows x 9 columns]
################################
# 分别指定升序和降序
>>> df.sort_values(by=["aqiLevel","bWendu"],ascending=[True,False])
            ymd  bWendu  yWendu  tianqi fengxiang fengli  aqi aqiInfo  aqiLevel
178  2018-06-28      35      24    多云~晴        北风   1-2级   33       优         1
149  2018-05-30      33      18       晴        西风   1-2级   46       优         1
206  2018-07-26      33      25  多云~雷阵雨       东北风   1-2级   40       优         1
158  2018-06-08      32      19  多云~雷阵雨       西南风   1-2级   43       优         1
205  2018-07-25      32      25      多云        北风   1-2级   28       优         1
..          ...     ...     ...     ...       ...    ...  ...     ...       ...
317  2018-11-14      13       5      多云        南风   1-2级  266    重度污染         5
329  2018-11-26      10       0      多云       东南风     1级  245    重度污染         5
335  2018-12-02       9       2    雾~多云       东北风     1级  234    重度污染         5
57   2018-02-27       7       0       阴        东风   1-2级  220    重度污染         5
86   2018-03-28      25       9    多云~晴        东风   1-2级  387    严重污染         6

[365 rows x 9 columns]

10、Pandas怎样实现DataFrame的Merge

merge的语法:

pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=True, suffixes=('_x', '_y'), copy=True, 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')

文档地址:pandas.DataFrame.merge — pandas 1.4.2 documentation

准备工作

>>> left = pd.DataFrame({'A': ['a0', 'a1', 'a2', 'a3'],
...                      'B': ['b0', 'b1', 'b2', 'b3'],
...                      'k1': ['x', 'x', 'y', 'y']})
>>> right = pd.DataFrame({'C': ['c1', 'c2', 'c3', 'c4'],
...                       'D': ['d1', 'd2', 'd3', 'd4'],
...                       'k1': ['y', 'y', 'z', 'z']})
>>> left
    A   B k1
0  a0  b0  x
1  a1  b1  x
2  a2  b2  y
3  a3  b3  y
>>> right
    C   D k1
0  c1  d1  y
1  c2  d2  y
2  c3  d3  z
3  c4  d4  z
# 默认inner,即取交集
>>> pd.merge(left,right,on="k1")
    A   B k1   C   D
0  a2  b2  y  c1  d1
1  a2  b2  y  c2  d2
2  a3  b3  y  c1  d1
3  a3  b3  y  c2  d2

可以看到只有left和right的key1=y的行保留了下来,即默认合并后只保留有共同列项并且值相等行(即交集)。

本例中left和right的k1=y分别有2个,最终构成了2*2=4行

若是左右的key不一样的话,比如下面这种情况

>>> left = pd.DataFrame({'A': ['a0', 'a1', 'a2', 'a3'],
...                      'B': ['b0', 'b1', 'b2', 'b3'],
...                      'k1': ['x', 'x', 'y', 'y']})
>>> right = pd.DataFrame({'C': ['c1', 'c2', 'c3', 'c4'],
...                       'D': ['d1', 'd2', 'd3', 'd4'],
...                       'k2': ['y', 'y', 'z', 'z']})
########################################
>>> right
    C   D k2
0  c1  d1  y
1  c2  d2  y
2  c3  d3  z
3  c4  d4  z
>>> left
    A   B k1
0  a0  b0  x
1  a1  b1  x
2  a2  b2  y
3  a3  b3  y
#######################################
# 就用left_on和right_on,区别基准
>>> pd.merge(left,right,left_on='k1',right_on='k2')
    A   B k1   C   D k2
0  a2  b2  y  c1  d1  y
1  a2  b2  y  c2  d2  y

10.1、理解merge时数量的对齐关系

以下关系要正确理解:

  • one-to-one:一对一关系,关联的key都是唯一的
    • 比如(学号,姓名) merge (学号,年龄)
    • 结果条数为:1*1
  • one-to-many:一对多关系,左边唯一key,右边不唯一key
    • 比如(学号,姓名) merge (学号,[语文成绩、数学成绩、英语成绩])
    • 结果条数为:1*N
  • many-to-many:多对多关系,左边右边都不是唯一的
    • 比如(学号,[语文成绩、数学成绩、英语成绩]) merge (学号,[篮球、足球、乒乓球])
    • 结果条数为:M*N

10.1.1、one-to-one 一对一关系的merge

>>> left = pd.DataFrame({'sno': [11, 12, 13, 14],
...                       'name': ['name_a', 'name_b', 'name_c', 'name_d']
...                     })
>>> left
   sno    name
0   11  name_a
1   12  name_b
2   13  name_c
3   14  name_d
########################
>>> right = pd.DataFrame({'sno':[11,12,13,14],'age':['21','22','23','24']})
>>> right
   sno age
0   11  21
1   12  22
2   13  23
3   14  24
#########################
# 一对一关系,结果中有4条
>>> pd.merge(left,right,on='sno')
   sno    name age
0   11  name_a  21
1   12  name_b  22
2   13  name_c  23
3   14  name_d  24

10.1.2、one-to-many 一对多关系的merge

注意:数据会被复制

>>> left = pd.DataFrame({'sno': [11, 12, 13, 14],
...                       'name': ['name_a', 'name_b', 'name_c', 'name_d']
...                     })
>>> left
   sno    name
0   11  name_a
1   12  name_b
2   13  name_c
3   14  name_d
################################################
>>> right = pd.DataFrame({'sno': [11, 11, 11, 12, 12, 13],
...                        'grade': ['语文88', '数学90', '英语75','语文66', '数学55', '英语29']
...                      })
>>> right
   sno grade
0   11  语文88
1   11  数学90
2   11  英语75
3   12  语文66
4   12  数学55
5   13  英语29
############################
>>> pd.merge(left,right,on='sno')
   sno    name grade
0   11  name_a  语文88
1   11  name_a  数学90
2   11  name_a  英语75
3   12  name_b  语文66
4   12  name_b  数学55
5   13  name_c  英语29

10.1.3、many-to-many 多对多关系的merge

>>> left = pd.DataFrame({'sno': [11, 11, 12, 12,12],
...                       '爱好': ['篮球', '羽毛球', '乒乓球', '篮球', "足球"]
...                     })
>>> left
   sno   爱好
0   11   篮球
1   11  羽毛球
2   12  乒乓球
3   12   篮球
4   12   足球
>>> right = pd.DataFrame({'sno': [11, 11, 11, 12, 12, 13],
...                        'grade': ['语文88', '数学90', '英语75','语文66', '数学55', '英语29']
...                      })
>>> right
   sno grade
0   11  语文88
1   11  数学90
2   11  英语75
3   12  语文66
4   12  数学55
5   13  英语29
>>> pd.merge(left, right, on='sno')
    sno   爱好 grade
0    11   篮球  语文88
1    11   篮球  数学90
2    11   篮球  英语75
3    11  羽毛球  语文88
4    11  羽毛球  数学90
5    11  羽毛球  英语75
6    12  乒乓球  语文66
7    12  乒乓球  数学55
8    12   篮球  语文66
9    12   篮球  数学55
10   12   足球  语文66
11   12   足球  数学55

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

>>> left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
...                       'A': ['A0', 'A1', 'A2', 'A3'],
...                       'B': ['B0', 'B1', 'B2', 'B3']})
>>> 
>>> right = pd.DataFrame({'key': ['K0', 'K1', 'K4', 'K5'],
...                       'C': ['C0', 'C1', 'C4', 'C5'],
...                       'D': ['D0', 'D1', 'D4', 'D5']})
>>> left
  key   A   B
0  K0  A0  B0
1  K1  A1  B1
2  K2  A2  B2
3  K3  A3  B3
>>> right
  key   C   D
0  K0  C0  D0
1  K1  C1  D1
2  K4  C4  D4
3  K5  C5  D5

10.2.1、inner join,默认为这个

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

>>> pd.merge(left,right,how='inner')
  key   A   B   C   D
0  K0  A0  B0  C0  D0
1  K1  A1  B1  C1  D1

10.2.2、left join

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

>>> pd.merge(left,right,how='left')
  key   A   B    C    D
0  K0  A0  B0   C0   D0
1  K1  A1  B1   C1   D1
2  K2  A2  B2  NaN  NaN
3  K3  A3  B3  NaN  NaN

10.2.3、right join

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

>>> pd.merge(left,right,how='right')
  key    A    B   C   D
0  K0   A0   B0  C0  D0
1  K1   A1   B1  C1  D1
2  K4  NaN  NaN  C4  D4
3  K5  NaN  NaN  C5  D5

10.2.4、outer join

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

>>> pd.merge(left,right,how='outer')
  key    A    B    C    D
0  K0   A0   B0   C0   D0
1  K1   A1   B1   C1   D1
2  K2   A2   B2  NaN  NaN
3  K3   A3   B3  NaN  NaN
4  K4  NaN  NaN   C4   D4
5  K5  NaN  NaN   C5   D5

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

>>> left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
...                       'A': ['A0', 'A1', 'A2', 'A3'],
...                       'B': ['B0', 'B1', 'B2', 'B3']})
>>> 
>>> right = pd.DataFrame({'key': ['K0', 'K1', 'K4', 'K5'],
...                       'A': ['A10', 'A11', 'A12', 'A13'],
...                       'D': ['D0', 'D1', 'D4', 'D5']})
>>> left
  key   A   B
0  K0  A0  B0
1  K1  A1  B1
2  K2  A2  B2
3  K3  A3  B3
>>> right
  key    A   D
0  K0  A10  D0
1  K1  A11  D1
2  K4  A12  D4
3  K5  A13  D5
>>> pd.merge(left,right,on='key')
  key A_x   B  A_y   D
0  K0  A0  B0  A10  D0
1  K1  A1  B1  A11  D1
#####################################
# suffixes:两个元素的后缀,如果列有重名,自动添加后缀,默认是('_x', '_y')
>>> pd.merge(left, right, on='key', suffixes=('_left', '_right'))
  key A_left   B A_right   D
0  K0     A0  B0     A10  D0
1  K1     A1  B1     A11  D1

11、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:是否忽略掉原来的数据索引

参考文档:

准备工作

>>> import pandas as pd
>>> import warnings
>>> warnings.filterwarnings('ignore')

11.1、使用pandas.concat合并数据

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

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

>>> pd.concat([df1,df2])
    A   B   C   D    E    F
0  A0  B0  C0  D0   E0  NaN
1  A1  B1  C1  D1   E1  NaN
2  A2  B2  C2  D2   E2  NaN
3  A3  B3  C3  D3   E3  NaN
0  A4  B4  C4  D4  NaN   F4
1  A5  B5  C5  D5  NaN   F5
2  A6  B6  C6  D6  NaN   F6
3  A7  B7  C7  D7  NaN   F7

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

>>> pd.concat([df1,df2], ignore_index=True)
    A   B   C   D    E    F
0  A0  B0  C0  D0   E0  NaN
1  A1  B1  C1  D1   E1  NaN
2  A2  B2  C2  D2   E2  NaN
3  A3  B3  C3  D3   E3  NaN
4  A4  B4  C4  D4  NaN   F4
5  A5  B5  C5  D5  NaN   F5
6  A6  B6  C6  D6  NaN   F6
7  A7  B7  C7  D7  NaN   F7

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

>>> pd.concat([df1,df2], ignore_index=True, join='inner')
    A   B   C   D
0  A0  B0  C0  D0
1  A1  B1  C1  D1
2  A2  B2  C2  D2
3  A3  B3  C3  D3
4  A4  B4  C4  D4
5  A5  B5  C5  D5
6  A6  B6  C6  D6
7  A7  B7  C7  D7

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

>>> df1
    A   B   C   D   E
0  A0  B0  C0  D0  E0
1  A1  B1  C1  D1  E1
2  A2  B2  C2  D2  E2
3  A3  B3  C3  D3  E3

(1)添加一列Series

>>> s1 = pd.Series(list(range(4)), name="F")
>>> pd.concat([df1,s1], axis=1)
    A   B   C   D   E  F
0  A0  B0  C0  D0  E0  0
1  A1  B1  C1  D1  E1  1
2  A2  B2  C2  D2  E2  2
3  A3  B3  C3  D3  E3  3

(2)添加多列Series

>>> s2 = df1.apply(lambda x:x["A"]+"_GG",axis=1)
>>> s2
0    A0_GG
1    A1_GG
2    A2_GG
3    A3_GG
dtype: object
>>> s2.name="G"

# 原来基础上并没有发生改变
>>> pd.concat([df1,s1,s2], axis=1)
    A   B   C   D   E  F      G
0  A0  B0  C0  D0  E0  0  A0_GG
1  A1  B1  C1  D1  E1  1  A1_GG
2  A2  B2  C2  D2  E2  2  A2_GG
3  A3  B3  C3  D3  E3  3  A3_GG
# 列表可以只有Series
>>> pd.concat([s1,s2], axis=1)
   F      G
0  0  A0_GG
1  1  A1_GG
2  2  A2_GG
3  3  A3_GG
##########################
# 列表是可以混合顺序的
>>> pd.concat([s1,df1,s2], axis=1)
   F   A   B   C   D   E      G
0  0  A0  B0  C0  D0  E0  A0_GG
1  1  A1  B1  C1  D1  E1  A1_GG
2  2  A2  B2  C2  D2  E2  A2_GG
3  3  A3  B3  C3  D3  E3  A3_GG

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

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

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

>>> df1.append(df2)
   A  B
0  1  2
1  3  4
0  5  6
1  7  8

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

>>> df1.append(df2, ignore_index=True)
   A  B
0  1  2
1  3  4
2  5  6
3  7  8

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

>>> df = pd.DataFrame(columns=['A'])
>>> df
Empty DataFrame
Columns: [A]
Index: []

(1)低性能版本

for i in range(5):
    # 注意这里每次都在复制
    df = df.append({'A': i}, ignore_index=True)
df
>>> for i in range(5):
...     df = df.append({'A':i}, ignore_index=True)
... 
>>> df
   A
0  0
1  1
2  2
3  3
4  4

(2)性能好的版本

# 传入的参数是一个列表,避免了多次复制
pd.concat(
    [pd.DataFrame([i], columns=['A']) for i in range(5)],
    ignore_index=True
)
#####################
>>> pd.concat(
...     [pd.DataFrame([i], columns=['A']) for i in range(5)],
...     ignore_index=True
... )
   A
0  0
1  1
2  2
3  3
4  4

11.3、merge和concat的区别

merge一次只能操作两个DataFrame,但是concat能操作多个

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

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

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

本次演示:
一、分组使用聚合函数做数据统计
二、遍历groupby的结果理解执行流程
三、实例分组探索天气数据

准备工作

>>> import pandas as pd
>>> import numpy as np
>>> df = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'],
...                    'B': ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],
...                    'C': np.random.randn(8),
...                    'D': np.random.randn(8)})
>>> df
     A      B         C         D
0  foo    one  0.943498 -1.057291
1  bar    one -0.201177 -0.293867
2  foo    two -0.089857  0.190784
3  bar  three -0.805926  0.892312
4  foo    two -0.343189  0.747129
5  bar    two  1.635383  0.101340
6  foo    one  2.403976 -0.893356
7  foo  three  0.169233  0.694649

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

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

>>> df.groupby("A").sum()
           C         D
A                     
bar  0.62828  0.699785
foo  3.08366 -0.318085

我们看到:

  1. groupby中的'A'变成了数据的索引列
  2. 因为要统计sum,但B列不是数字,所以被自动忽略掉

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

>>> df.groupby(["A","B"]).sum()
                  C         D
A   B                        
bar one   -0.201177 -0.293867
    three -0.805926  0.892312
    two    1.635383  0.101340
foo one    3.347473 -1.950647
    three  0.169233  0.694649
    two   -0.433046  0.937913

# 我们看到:('A','B')成对变成了二级索引
>>> df.groupby(['A','B'], as_index=False).mean()
     A      B         C         D
0  bar    one -0.201177 -0.293867
1  bar  three -0.805926  0.892312
2  bar    two  1.635383  0.101340
3  foo    one  1.673737 -0.975324
4  foo  three  0.169233  0.694649
5  foo    two -0.216523  0.468957

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

>>> df.groupby('A').agg([np.sum, np.mean, np.std])
           C                             D                    
         sum      mean       std       sum      mean       std
A                                                             
bar  0.62828  0.209427  1.271394  0.699785  0.233262  0.603993
foo  3.08366  0.616732  1.109278 -0.318085 -0.063617  0.862098

我们看到:列变成了多级索引

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

# method1:预过滤,性能更好
>>> df.groupby("A")["C"].agg([np.sum, np.mean, np.std])
         sum      mean       std
A                               
bar  0.62828  0.209427  1.271394
foo  3.08366  0.616732  1.109278
####################
# method2
>>> df.groupby('A').agg([np.sum, np.mean, np.std])['C']
         sum      mean       std
A                               
bar  0.62828  0.209427  1.271394
foo  3.08366  0.616732  1.109278

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

>>> df.groupby('A').agg({'C':np.sum, 'D':np.mean})
           C         D
A                     
bar  0.62828  0.233262
foo  3.08366 -0.063617

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

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

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

>>> g = df.groupby('A')
>>> g
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x7fc7c448e710>

>>> for name,group in g:
...     print(name)
...     print(group)
...     print()
... 
bar
     A      B         C         D
1  bar    one -0.201177 -0.293867
3  bar  three -0.805926  0.892312
5  bar    two  1.635383  0.101340

foo
     A      B         C         D
0  foo    one  0.943498 -1.057291
2  foo    two -0.089857  0.190784
4  foo    two -0.343189  0.747129
6  foo    one  2.403976 -0.893356
7  foo  three  0.169233  0.694649

可以获取单个分组的数据

# 里边填写的是组名,即上边的name
>>> g.get_group("bar")
     A      B         C         D
1  bar    one -0.201177 -0.293867
3  bar  three -0.805926  0.892312
5  bar    two  1.635383  0.101340

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

>>> g = df.groupby(['A', 'B'])
>>> for name,group in g:
...     print(name)
...     print(group)
...     print()
... 
('bar', 'one')
     A    B         C         D
1  bar  one -0.201177 -0.293867

('bar', 'three')
     A      B         C         D
3  bar  three -0.805926  0.892312

('bar', 'two')
     A    B         C        D
5  bar  two  1.635383  0.10134

('foo', 'one')
     A    B         C         D
0  foo  one  0.943498 -1.057291
6  foo  one  2.403976 -0.893356

('foo', 'three')
     A      B         C         D
7  foo  three  0.169233  0.694649

('foo', 'two')
     A    B         C         D
2  foo  two -0.089857  0.190784
4  foo  two -0.343189  0.747129

# 可以看到,name是一个2个元素的tuple,代表不同的列
# 可以直接查询group后的某几列,生成Series或者子DataFrame
>>> g.get_group(('foo', 'one'))
     A    B         C         D
0  foo  one  0.943498 -1.057291
6  foo  one  2.403976 -0.893356
# 其实所有的聚合统计,都是在dataframe和series上进行的
>>> g['C']
<pandas.core.groupby.generic.SeriesGroupBy object at 0x7fc7c497a828>
>>> for name, group in g['C']:
...     print(name)
...     print(group)
...     print(type(group))
...     print()
... 
('bar', 'one')
1   -0.201177
Name: C, dtype: float64
<class 'pandas.core.series.Series'>

('bar', 'three')
3   -0.805926
Name: C, dtype: float64
<class 'pandas.core.series.Series'>

('bar', 'two')
5    1.635383
Name: C, dtype: float64
<class 'pandas.core.series.Series'>

('foo', 'one')
0    0.943498
6    2.403976
Name: C, dtype: float64
<class 'pandas.core.series.Series'>

('foo', 'three')
7    0.169233
Name: C, dtype: float64
<class 'pandas.core.series.Series'>

('foo', 'two')
2   -0.089857
4   -0.343189
Name: C, dtype: float64
<class 'pandas.core.series.Series'>

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

>>> fpath = "beijing_tianqi_2018.csv"
>>> df = pd.read_csv(fpath)
# 替换掉温度的后缀℃
>>> df.loc[:, "bWendu"] = df["bWendu"].str.replace("℃", "").astype('int32')
>>> df.loc[:, "yWendu"] = df["yWendu"].str.replace("℃", "").astype('int32')
>>> df.head()
          ymd  bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel
0  2018-01-01       3      -6   晴~多云       东北风   1-2级   59       良         2
1  2018-01-02       2      -5   阴~多云       东北风   1-2级   49       优         1
2  2018-01-03       2      -5     多云        北风   1-2级   28       优         1
3  2018-01-04       0      -8      阴       东北风   1-2级   28       优         1
4  2018-01-05       3      -6   多云~晴       西北风   1-2级   50       优         1
# 这里是切片df["ymd"]的从第1为位到第7位,下标为[0:6]
# 新增一列为月份
>>> df['month'] = df['ymd'].str[:7]
>>> df.head()
          ymd  bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel    month
0  2018-01-01       3      -6   晴~多云       东北风   1-2级   59       良         2  2018-01
1  2018-01-02       2      -5   阴~多云       东北风   1-2级   49       优         1  2018-01
2  2018-01-03       2      -5     多云        北风   1-2级   28       优         1  2018-01
3  2018-01-04       0      -8      阴       东北风   1-2级   28       优         1  2018-01
4  2018-01-05       3      -6   多云~晴       西北风   1-2级   50       优         1  2018-01

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

>>> data = df.groupby('month')['bWendu'].max()
>>> data
month
2018-01     7
2018-02    12
2018-03    27
2018-04    30
2018-05    35
2018-06    38
2018-07    37
2018-08    36
2018-09    31
2018-10    25
2018-11    18
2018-12    10
Name: bWendu, dtype: int32

########
>>> type(data)
<class 'pandas.core.series.Series'>

 画图功能在linux实现不了,但是可以在jupyter里边实现

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

>>> df.head()
          ymd  bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel    month
0  2018-01-01       3      -6   晴~多云       东北风   1-2级   59       良         2  2018-01
1  2018-01-02       2      -5   阴~多云       东北风   1-2级   49       优         1  2018-01
2  2018-01-03       2      -5     多云        北风   1-2级   28       优         1  2018-01
3  2018-01-04       0      -8      阴       东北风   1-2级   28       优         1  2018-01
4  2018-01-05       3      -6   多云~晴       西北风   1-2级   50       优         1  2018-01
>>> group_data = df.groupby('month').agg({"bWendu":np.max, "yWendu":np.min, "aqi":np.mean})
>>> group_data
         bWendu  yWendu         aqi
month                              
2018-01       7     -12   60.677419
2018-02      12     -10   78.857143
2018-03      27      -4  130.322581
2018-04      30       1  102.866667
2018-05      35      10   99.064516
2018-06      38      17   82.300000
2018-07      37      22   72.677419
2018-08      36      20   59.516129
2018-09      31      11   50.433333
2018-10      25       1   67.096774
2018-11      18      -4  105.100000
2018-12      10     -12   77.354839

  

13、Pandas处理日期数据

Pandas日期处理的作用:将2018-01-01、1/1/2018等多种日期格式映射成统一的格式对象,在该对象上提供强大的功能支持

几个概念:

  1. pd.to_datetime:pandas的一个函数,能将字符串、列表、series变成日期形式
  2. Timestamp:pandas表示日期的对象形式
  3. DatetimeIndex:pandas表示日期的对象列表形式

其中:

  • DatetimeIndex是Timestamp的列表形式
  • pd.to_datetime对单个日期字符串处理会得到Timestamp
  • pd.to_datetime对日期字符串列表处理会得到DatetimeIndex

问题:怎样统计每周、每月、每季度的最高温度?

13.1、读取天气数据到dataframe

>>> import pandas as pd
>>> fpath = "beijing_tianqi_2018.csv"
>>> df = pd.read_csv(fpath)

# 替换掉温度的后缀℃
>>> df.loc[:, "bWendu"] = df["bWendu"].str.replace("℃", "").astype('int32')
>>> df.loc[:, "yWendu"] = df["yWendu"].str.replace("℃", "").astype('int32')
>>> df.head()
          ymd  bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel
0  2018-01-01       3      -6   晴~多云       东北风   1-2级   59       良         2
1  2018-01-02       2      -5   阴~多云       东北风   1-2级   49       优         1
2  2018-01-03       2      -5     多云        北风   1-2级   28       优         1
3  2018-01-04       0      -8      阴       东北风   1-2级   28       优         1
4  2018-01-05       3      -6   多云~晴       西北风   1-2级   50       优         1

13.2、将日期列转换成pandas的日期

>>> pd.to_datetime(df["ymd"], format="%Y-%m-%d")
0     2018-01-01
1     2018-01-02
2     2018-01-03
3     2018-01-04
4     2018-01-05
         ...    
360   2018-12-27
361   2018-12-28
362   2018-12-29
363   2018-12-30
364   2018-12-31
Name: ymd, Length: 365, dtype: datetime64[ns]
# 把ymd变成索引
>>> df.set_index(pd.to_datetime(df["ymd"]), inplace=True)
>>> df.head()
                   ymd  bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel       ymd2
ymd                                                                                             
2018-01-01  2018-01-01       3      -6   晴~多云       东北风   1-2级   59       良         2 2018-01-01
2018-01-02  2018-01-02       2      -5   阴~多云       东北风   1-2级   49       优         1 2018-01-02
2018-01-03  2018-01-03       2      -5     多云        北风   1-2级   28       优         1 2018-01-03
2018-01-04  2018-01-04       0      -8      阴       东北风   1-2级   28       优         1 2018-01-04
2018-01-05  2018-01-05       3      -6   多云~晴       西北风   1-2级   50       优         1 2018-01-05
>>> df.index
DatetimeIndex(['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04',
               '2018-01-05', '2018-01-06', '2018-01-07', '2018-01-08',
               '2018-01-09', '2018-01-10',
               ...
               '2018-12-22', '2018-12-23', '2018-12-24', '2018-12-25',
               '2018-12-26', '2018-12-27', '2018-12-28', '2018-12-29',
               '2018-12-30', '2018-12-31'],
              dtype='datetime64[ns]', name='ymd', length=365, freq=None)
########################
# DatetimeIndex是Timestamp的列表形式
>>> df.index[0]
Timestamp('2018-01-01 00:00:00')
############################
>>> df.index.strftime('%y/%m/%d')
Index(['18/01/01', '18/01/02', '18/01/03', '18/01/04', '18/01/05', '18/01/06',
       '18/01/07', '18/01/08', '18/01/09', '18/01/10',
       ...
       '18/12/22', '18/12/23', '18/12/24', '18/12/25', '18/12/26', '18/12/27',
       '18/12/28', '18/12/29', '18/12/30', '18/12/31'],
      dtype='object', name='ymd', length=365)

13.3、方便的对DatetimeIndex进行查询

# 筛选固定的某天
>>> df.loc['2018-01-05']
ymd                   2018-01-05
bWendu                         3
yWendu                        -6
tianqi                      多云~晴
fengxiang                    西北风
fengli                      1-2级
aqi                           50
aqiInfo                        优
aqiLevel                       1
ymd2         2018-01-05 00:00:00
Name: 2018-01-05 00:00:00, dtype: object

# 日期区间
>>> df.loc['2018-01-05':'2018-01-10']
                   ymd  bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel       ymd2
ymd                                                                                             
2018-01-05  2018-01-05       3      -6   多云~晴       西北风   1-2级   50       优         1 2018-01-05
2018-01-06  2018-01-06       2      -5   多云~阴       西南风   1-2级   32       优         1 2018-01-06
2018-01-07  2018-01-07       2      -4   阴~多云       西南风   1-2级   59       良         2 2018-01-07
2018-01-08  2018-01-08       2      -6      晴       西北风   4-5级   50       优         1 2018-01-08
2018-01-09  2018-01-09       1      -8      晴       西北风   3-4级   34       优         1 2018-01-09
2018-01-10  2018-01-10      -2     -10      晴       西北风   1-2级   26       优         1 2018-01-10

# 按月份前缀筛选
>>> df['2018-03'].head()
                   ymd  bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel       ymd2
ymd                                                                                             
2018-03-01  2018-03-01       8      -3     多云       西南风   1-2级   46       优         1 2018-03-01
2018-03-02  2018-03-02       9      -1   晴~多云        北风   1-2级   95       良         2 2018-03-02
2018-03-03  2018-03-03      13       3   多云~阴        北风   1-2级  214    重度污染         5 2018-03-03
2018-03-04  2018-03-04       7      -2   阴~多云       东南风   1-2级  144    轻度污染         3 2018-03-04
2018-03-05  2018-03-05       8      -3      晴        南风   1-2级   94       良         2 2018-03-05

# 按索引号进行搜索
>>> df.loc["2018-07":"2018-09"].index
DatetimeIndex(['2018-07-01', '2018-07-02', '2018-07-03', '2018-07-04',
               '2018-07-05', '2018-07-06', '2018-07-07', '2018-07-08',
               '2018-07-09', '2018-07-10', '2018-07-11', '2018-07-12',
               '2018-07-13', '2018-07-14', '2018-07-15', '2018-07-16',
               '2018-07-17', '2018-07-18', '2018-07-19', '2018-07-20',
               '2018-07-21', '2018-07-22', '2018-07-23', '2018-07-24',
               '2018-07-25', '2018-07-26', '2018-07-27', '2018-07-28',
               '2018-07-29', '2018-07-30', '2018-07-31', '2018-08-01',
               '2018-08-02', '2018-08-03', '2018-08-04', '2018-08-05',
               '2018-08-06', '2018-08-07', '2018-08-08', '2018-08-09',
               '2018-08-10', '2018-08-11', '2018-08-12', '2018-08-13',
               '2018-08-14', '2018-08-15', '2018-08-16', '2018-08-17',
               '2018-08-18', '2018-08-19', '2018-08-20', '2018-08-21',
               '2018-08-22', '2018-08-23', '2018-08-24', '2018-08-25',
               '2018-08-26', '2018-08-27', '2018-08-28', '2018-08-29',
               '2018-08-30', '2018-08-31', '2018-09-01', '2018-09-02',
               '2018-09-03', '2018-09-04', '2018-09-05', '2018-09-06',
               '2018-09-07', '2018-09-08', '2018-09-09', '2018-09-10',
               '2018-09-11', '2018-09-12', '2018-09-13', '2018-09-14',
               '2018-09-15', '2018-09-16', '2018-09-17', '2018-09-18',
               '2018-09-19', '2018-09-20', '2018-09-21', '2018-09-22',
               '2018-09-23', '2018-09-24', '2018-09-25', '2018-09-26',
               '2018-09-27', '2018-09-28', '2018-09-29', '2018-09-30'],
              dtype='datetime64[ns]', name='ymd', freq=None)

######
# 按年份进行索引
>>> df.loc["2018"].head()
                   ymd  bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel       ymd2
ymd                                                                                             
2018-01-01  2018-01-01       3      -6   晴~多云       东北风   1-2级   59       良         2 2018-01-01
2018-01-02  2018-01-02       2      -5   阴~多云       东北风   1-2级   49       优         1 2018-01-02
2018-01-03  2018-01-03       2      -5     多云        北风   1-2级   28       优         1 2018-01-03
2018-01-04  2018-01-04       0      -8      阴       东北风   1-2级   28       优         1 2018-01-04
2018-01-05  2018-01-05       3      -6   多云~晴       西北风   1-2级   50       优         1 2018-01-05
# 过滤掉指定日期之前的内容
>>> df.truncate(before="2018-2-25").head()
                   ymd  bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel       ymd2
ymd                                                                                             
2018-02-25  2018-02-25       6      -4     多云       西南风   1-2级   73       良         2 2018-02-25
2018-02-26  2018-02-26      12      -1   晴~多云       西南风   1-2级  157    中度污染         4 2018-02-26
2018-02-27  2018-02-27       7       0      阴        东风   1-2级  220    重度污染         5 2018-02-27
2018-02-28  2018-02-28       9      -2   多云~晴       西南风   3-4级  139    轻度污染         3 2018-02-28
2018-03-01  2018-03-01       8      -3     多云       西南风   1-2级   46       优         1 2018-03-01

##############
#过滤掉之后的
>>> df.truncate(after='2018-2-25').tail()
                   ymd  bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel       ymd2
ymd                                                                                             
2018-02-21  2018-02-21       8      -4      晴        南风   1-2级   53       良         2 2018-02-21
2018-02-22  2018-02-22       9      -4     多云       西南风   1-2级   42       优         1 2018-02-22
2018-02-23  2018-02-23      10      -4     多云       东北风   1-2级   45       优         1 2018-02-23
2018-02-24  2018-02-24       3      -6   多云~晴        南风   1-2级   66       良         2 2018-02-24
2018-02-25  2018-02-25       6      -4     多云       西南风   1-2级   73       良         2 2018-02-25

13.4、生成日期范围

pandas.date_range(start=None, end=None, periods=None, freq='D', tz=None, normalize=False, name=None, closed=None, **kwargs)

该函数主要用于生成一个固定频率的时间索引,在调用构造方法时,必须指定start、end、periods中的两个参数值,否则报错. start: 起始时间 end: 末尾时间 periods: 要生成的时段数 freq: 日期偏移量,取值为string或DateOffset,默认为'D' freq 参数详解:pandas.date_range freq参数枚举_浪_沏沙的博客-CSDN博客_date_range freq

# 默认都是一个单位为一天
>>> pd.date_range(start='20180101',end='20180110')
DatetimeIndex(['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04',
               '2018-01-05', '2018-01-06', '2018-01-07', '2018-01-08',
               '2018-01-09', '2018-01-10'],
              dtype='datetime64[ns]', freq='D')
>>> pd.date_range(start='20180101',periods=3)
DatetimeIndex(['2018-01-01', '2018-01-02', '2018-01-03'], dtype='datetime64[ns]', freq='D')

##############
>>> pd.date_range(start='20180101',end='20180110' , periods=3)
DatetimeIndex(['2018-01-01 00:00:00', '2018-01-05 12:00:00',
               '2018-01-10 00:00:00'],
              dtype='datetime64[ns]', freq=None)

################
>>> pd.date_range(start="201801010000", end="201801010100", freq="300s")
DatetimeIndex(['2018-01-01 00:00:00', '2018-01-01 00:05:00',
               '2018-01-01 00:10:00', '2018-01-01 00:15:00',
               '2018-01-01 00:20:00', '2018-01-01 00:25:00',
               '2018-01-01 00:30:00', '2018-01-01 00:35:00',
               '2018-01-01 00:40:00', '2018-01-01 00:45:00',
               '2018-01-01 00:50:00', '2018-01-01 00:55:00',
               '2018-01-01 01:00:00'],
              dtype='datetime64[ns]', freq='300S')

13.5、方便的获取周、月、季度

Timestamp、DatetimeIndex支持大量的属性可以获取日期分量:
Time series / date functionality — pandas 1.4.2 documentation

>>> df.index.week
__main__:1: FutureWarning: weekofyear and week have been deprecated, please use DatetimeIndex.isocalendar().week instead, which returns a Series.  To exactly reproduce the behavior of week and weekofyear and return an Index, you may call pd.Int64Index(idx.isocalendar().week)
Int64Index([ 1,  1,  1,  1,  1,  1,  1,  2,  2,  2,
            ...
            51, 51, 52, 52, 52, 52, 52, 52, 52,  1],
           dtype='int64', name='ymd', length=365)


# 使用提示的语法,结果是这样的
>>> df.index.isocalendar()
            year  week  day
ymd                        
2018-01-01  2018     1    1
2018-01-02  2018     1    2
2018-01-03  2018     1    3
2018-01-04  2018     1    4
2018-01-05  2018     1    5
...          ...   ...  ...
2018-12-27  2018    52    4
2018-12-28  2018    52    5
2018-12-29  2018    52    6
2018-12-30  2018    52    7
2018-12-31  2019     1    1

[365 rows x 3 columns]
>>> df.index.isocalendar().week
ymd
2018-01-01     1
2018-01-02     1
2018-01-03     1
2018-01-04     1
2018-01-05     1
              ..
2018-12-27    52
2018-12-28    52
2018-12-29    52
2018-12-30    52
2018-12-31     1
Name: week, Length: 365, dtype: UInt32
>>> df.ymd2.dt.week
__main__:1: FutureWarning: Series.dt.weekofyear and Series.dt.week have been deprecated.  Please use Series.dt.isocalendar().week instead.
ymd
2018-01-01     1
2018-01-02     1
2018-01-03     1
2018-01-04     1
2018-01-05     1
              ..
2018-12-27    52
2018-12-28    52
2018-12-29    52
2018-12-30    52
2018-12-31     1
Name: ymd2, Length: 365, dtype: int64

# 使用提示语法
>>> df.ymd2.dt.isocalendar()
            year  week  day
ymd                        
2018-01-01  2018     1    1
2018-01-02  2018     1    2
2018-01-03  2018     1    3
2018-01-04  2018     1    4
2018-01-05  2018     1    5
...          ...   ...  ...
2018-12-27  2018    52    4
2018-12-28  2018    52    5
2018-12-29  2018    52    6
2018-12-30  2018    52    7
2018-12-31  2019     1    1

[365 rows x 3 columns]
# 月数字列表
>>> df.index.month
Int64Index([ 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
            ...
            12, 12, 12, 12, 12, 12, 12, 12, 12, 12],
           dtype='int64', name='ymd', length=365)


#############
# 季度数字列表
>>> df.index.quarter
Int64Index([1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
            ...
            4, 4, 4, 4, 4, 4, 4, 4, 4, 4],
           dtype='int64', name='ymd', length=365)

13.6、统计每周、每月、每个季度的最高温度

13.6.1、统计每周的数据

>>> df.groupby(df.index.week)["bWendu"].max().head()
__main__:1: FutureWarning: weekofyear and week have been deprecated, please use DatetimeIndex.isocalendar().week instead, which returns a Series.  To exactly reproduce the behavior of week and weekofyear and return an Index, you may call pd.Int64Index(idx.isocalendar().week)
ymd
1    3
2    6
3    7
4   -1
5    4
Name: bWendu, dtype: int32


# 使用提示语句后的结果
>>> df.groupby(df.index.isocalendar().week)["bWendu"].max().head()
week
1    3
2    6
3    7
4   -1
5    4
Name: bWendu, dtype: int32

13.6.2、统计每个月的数据

>>> df.groupby(df.index.month)["bWendu"].max()
ymd
1      7
2     12
3     27
4     30
5     35
6     38
7     37
8     36
9     31
10    25
11    18
12    10
Name: bWendu, dtype: int32

13.6.3、统计每个季度的数据

>>> df.groupby(df.index.quarter)["bWendu"].max()
ymd
1    27
2    38
3    37
4    25
Name: bWendu, dtype: int32

13.7、python中时间日期格式化符号

%y 两位数的年份表示(00-99) %Y 四位数的年份表示(000-9999) %m 月份(01-12) %d 月内中的一天(0-31) %H 24小时制小时数(0-23) %I 12小时制小时数(01-12) %M 分钟数(00=59) %S 秒(00-59) %a 本地简化星期名称 %A 本地完整星期名称 %b 本地简化的月份名称 %B 本地完整的月份名称 %c 本地相应的日期表示和时间表示 %j 年内的一天(001-366) %p 本地A.M.或P.M.的等价符 %U 一年中的星期数(00-53)星期天为星期的开始 %w 星期(0-6),星期天为星期的开始 %W 一年中的星期数(00-53)星期一为星期的开始 %x 本地相应的日期表示 %X 本地相应的时间表示 %Z 当前时区的名称 %% %号本身

  • 0
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FanMY_71

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值