《对比Excel,轻松学习Python数据分析》笔记

说明

本书还是一本基础入门的书,里面关于数据分析的思想对于初学者入门还是很有帮助的。

另外本书中的案例基本都是使用Excel与Python分别实现的,本笔记只记录了Python的实现方式。

本书也很有趣味性,将数据分析比喻为做菜,用做菜的步骤类比数据分析的过程,理解起来很方便:

  • 熟悉锅——Python基础知识+Pandas数据结构
  • 准备食材——获取数据源
  • 淘米洗菜——数据预处理
  • 菜品挑选——数据选择
  • 切配菜品——数值操作
  • 开始烹调——数据运算
  • 炒菜计时器——时间序列
  • 菜品分类——数据分组/数据透视表
  • 水果拼盘——多表拼接
  • 盛菜装盘——结果导出
  • 菜品摆放——数据可视化

第1章 数据分析基础

1.1 数据分析是什么

数据分析是指利用合适的工具在统计学理论的支撑下,对数据进行一定程度的预处理,然后结合具体业务分析数据,帮助相关业务部门监控、定位、分析、解决问题,从而帮助企业高效决策,提高经营效率,发现业务机会点,让企业获得持续竞争的优势。

1.2 为什么要做数据分析

做一件事情之前我们首先得弄清楚为什么要做,或者说做了这件事以后有什么好处,这样我们才能更好地坚持下去

啤酒和尿布的问题大家应该都听过,如果没有数据分析,相信大家是怎么也不会发现买尿布的人一般也会顺带买啤酒,现在各大电商网站都会卖各种套餐,相关商品搭配销售能大大提高客单价,增加收益,这些套餐的搭配都是基于历史用户购买数据得出来的。如果没有数据分析,可能很难想到要把商品搭配销售,或者不知道该怎么搭配。

数据分析可以把隐藏在大量数据背后的信息提炼出来,总结出数据的内在规律。代替了以前那种拍脑袋、靠经验做决策的做法,因此越来越多的企业重视数据分析。具体来说,数据分析在企业日常经营分析中有三大作用,即现状分析原因分析预测分析

现状分析

现状分析可以告诉你业务在过去发生了什么,具体体现在两个方面。

第一,告诉你现阶段的整体运营情况,通过各个关键指标的表现情况来衡量企业的运营状况,掌握企业目前的发展趋势。

第二,告诉你企业各项业务的构成,通常公司的业务并不是单一的,而是由很多分支业务构成的,通过现状分析可以让你了解企业各项分支业务的发展及变动情况,对企业运营状况有更深入的了解。

现状分析一般通过日常报表来实现,如日报、周报、月报等形式。

例如,电商网站日报中的现状分析会包括订单数、新增用户数、活跃率、留存率等指标同比、环比上涨/下跌了多少。如果将公司的业务划分为华北、东北、华中、华东、华南、西南、西北几个片区,那么通过现状分析,你可以很清楚地知道哪些区域做得比较好,哪些区域做得比较差。

原因分析

原因分析可以告诉你某一现状为什么会存在

经过现状分析,我们对企业的运营情况有了基本了解,知道哪些指标呈上升趋势,哪些指标呈下降趋势,或者是哪些业务做得好,哪些做得不好。但是我们还不知道那些做得好的业务为什么会做得好,做得差的业务的原因又是什么

找原因的过程就是原因分析

原因分析一般通过专题分析来完成,根据企业运营情况选择针对某一现状进行原因分析。

例如,在某一天的电商网站日报中,某件商品销量突然大增,那么就需要针对这件销量突然增加的商品做专题分析,看看是什么原因促成了商品销量大增。

预测分析

预测分析会告诉你未来可能发生什么

在了解企业经营状况以后,有时还需要对企业未来发展趋势做出预测,为制订企业经营目标及策略提供有效的参考与决策依据,以保证企业的可持续健康发展

例如,通过上述的原因分析,我们就可以有针对性地实施一些策略。比如通过原因分析,我们得知在台风来临之际面包的销量会大增,那么我们在下次台风来临之前就应该多准备一些面包,同时为了获得更多的销量做一系列准备。

1.3 数据分析究竟在分析什么

数据分析的重点在分析而不在工具,那么我们究竟该分析什么呢?

总体概览指标

总体概览指标又称统计绝对数,是反映某一数据指标的整体规模大小,总量多少的指标。

例如,当日销售额为60万元,当日订单量为2万,购买人数是1.5万人,这些都是概览指标,用来反映某个时间段内某项业务的某些指标的绝对量。

例如,当日销售额为60万元,当日订单量为2万,购买人数是1.5万人,这些都是概览指标,用来反映某个时间段内某项业务的某些指标的绝对量。

对比性指标

对比性指标是说明现象之间数量对比关系的指标,常见的就是同比环比这几个指标。

同比是指相邻时间段内某一共同时间点上指标的对比;

环比就是相邻时间段内指标的对比;

就是两个时间段内的指标直接做差;

差的绝对值就是两个时间段内指标的变化量。

例如,2018年和2017年是相邻时间段,那么2018年的第26周和2017年的第26周之间的对比就是同比,而2018年的第26周和第25周的对比就是环比。

集中趋势指标

集中趋势指标是用来反映某一现象在一定时间段内所达到的一般水平,通常用平均指标来表示。平均指标分为数值平均和位置平均。例如,某地的平均工资就是一个集中趋势指标。

数值平均是统计数列中所有数值平均的结果,有普通平均数加权平均数两种。普通平均的所有数值的权重都是1,而加权平均中不同数值的权重是不一样的,在算平均值时不同数值要乘以不同的权重。

假如你要算一年中每月的月平均销量,这个时候一般就用数值平均,直接把12个月的销量相加除以12即可。

假如你要算一个人的平均信用得分情况,由于影响信用得分的因素有多个,而且不同因素的权重占比是不一样的,这个时候就需要使用加权平均。

位置平均/众数/中位数的概念

位置平均是基于某个特殊位置上的数或者普遍出现的数,即用出现次数最多的数值来作为这一系列数值的整体一般水平。

基于位置的指标最常用的就是中位数基于出现次数最多的指标就是众数

众数是一系列数值中出现次数最多的数值,是总体中最普遍的值,因此可以用来代表一般水平。如果数据可以分为多组,则为每组找出一个众数。注意,众数只有在总体内单位足够多时才有意义

中位数是将一系列值中的每一个值按照从小到大顺序排列,处于中间位置的数值就是中位数。因为处于中间位置,有一半变量值大于该值,一半小于该值,所以可以用这样的中等水平来表示整体的一般水平。

离散程度指标

离散程度指标是用来表示总体分布的离散(波动)情况的指标,如果这个指标较大,则说明数据波动比较大,反之则说明数据相对比较稳定。

全距(又称极差)方差标准差等几个指标用于衡量数值的离散情况。

全距

全距:由于平均数让我们确定一批数据的中心,但是无法知道数据的变动情况,因此引入全距。

全距的计算方法是用数据集中最大数(上界)减去数据集中最小数(下界)。

全距存在的问题主要有两方面:

  • 问题1:容易受异常值影响。
  • 问题2:全距只表示了数据的宽度,没有描述清楚数据上下界之间的分布形态。

对于问题1我们引入四分位数的概念。四分位数将一些数值从小到大排列,然后一分为四,最小的四分位数为下四分位数,最大的四分位数为上四分位数,中间的四分位数为中位数。

对于问题2我们引入了方差标准差两个概念来衡量数据的分散性。

方差与标准差

方差是每个数值与均值距离的平方的平均值,方差越小说明各数值与均值之间的差距越小,数值越稳定

标准差是方差的开方,表示数值与均值距离的平均值

相关性指标

上面提到的几个维度是对数据整体的情况进行描述,但是我们有的时候想看一下数据整体内的变量之间存在什么关系,一个变化时会引起另一个怎么变化,我们把用来反映这种关系的指标叫做相关系数,相关系数常用r来表示。

8cfc81d985f62e7bbaaec572581d5571.png

其中,Cov(X,Y)为X与Y的协方差Var[X]为X的方差Var[Y]为Y的方差

关于相关系数需要注意以下几点。

  • 相关系数r的范围为[-1,1]。
  • r的绝对值越大,表示相关性越强。
  • r的正负代表相关性的方向,正代表正相关,负代表负相关。

相关关系与因果关系

相关关系不等于因果关系,相关关系只能说明两件事情有关联,而因果关系是说明一件事情导致了另一件事情的发生,不要把这两种关系混淆使用。

例如,啤酒和尿布是具有相关关系的,但是不具有因果关系;而流感疾病和关键词检索量上涨是具有因果关系的。

在实际业务中会遇到很多相关关系,但是具有相关关系的两者不一定有因果关系,一定要注意区分。

1.4 数据分析的常规流程

数据分析是借助合适的工具去帮助公司发现数据背后隐藏的信息,对这些隐藏的信息进行挖掘,从而促进业务发展。基于此,可以将数据分析分为以下几个步骤:

6ffa25f86a32619486b9e5f4fc333ae3.png

熟悉工具

数据分析是利用合适的工具和合适的理论挖掘隐藏在数据背后的信息,因此数据分析的第一步就是要熟悉工具。工欲善其事,必先利其器,只有熟练使用工具,才能更好地处理数据、分析数据。

明确目的

做任何事情都要目的明确,数据分析也一样,首先要明确数据分析的目的,即希望通过数据分析得出什么。例如,希望通过数据分析发现流失用户都有哪些特征,希望通过数据分析找到销量上涨的原因。

获取数据

目的明确后我们就要获取数据,在获取数据之前还需要明确以下几点:

  • 需要什么指标。
  • 需要什么时间段的数据。
  • 这些数据都存在哪个数据库或哪个表中。
  • 怎么提取,是自己写Sql还是可以直接从ERP系统中下载。

熟悉数据

拿到数据以后,我们要去熟悉数据,熟悉数据就是看一下有多少数据,这些数据是类别型还是数值型的;每个指标大概有哪些值,这些数据能不能满足我们的需求,如果不够,那么还需要哪些数据。

获取数据熟悉数据是一个双向的过程,当你熟悉完数据以后发现当前数据维度不够,那就需要重新获取;当你获取到新的数据以后,需要再去熟悉,所以获取数据和熟悉数据会贯穿在整个数据分析过程中

处理数据

获取到的数据是原始数据,这些数据中一般会有一些特殊数据,我们需要对这些数据进行提前处理,常见的特殊数据主要有以下几种:

  • 异常数据。
  • 重复数据。(需要删除)
  • 缺失数据。
  • 测试数据。(需要删除)

对于重复数据、测试数据我们一般都是做删除处理的。

对于缺失数据,如果缺失比例高于30%,那么我们会选择放弃这个指标,即做删除处理。而对于缺失比例低于30%的指标,我们一般进行填充处理,即使用0、均值或者众数等进行填充。

对于异常数据,需要结合具体业务进行处理,如果你是一个电商平台的数据分析师,你要找出平台上的刷单商户,那么异常值就是你要重点研究的对象了;假如你要分析用户的年龄,那么一些大于100或者是小于0的数据,就要删除。

分析数据

分析数据主要围绕上节介绍的数据分析指标展开。在分析过程中经常采用的一个方法就是下钻法,例如当我们发现某一天的销量突然上涨/下滑时,我们会去看是哪个地区的销量上涨/下滑,进而再看哪个品类、哪个产品的销量出现上涨/下滑,层层下钻,最后找到问题产生的真正原因。

得出结论

通过分析数据,我们就可以得出结论。

验证结论

有的时候即使是通过数据分析出来的结论也不一定成立,所以我们要把数据分析和实际业务相联系,去验证结论是否正确。

例如,做新媒体数据分析,你通过分析发现情感类文章的点赞量、转发量更高,这只是你的分析结论,但是这个结论正确吗?你可以再写几篇情感类文章验证一下。

展示结论

我们在分析出结论,并且结论得到验证以后就可以把这个结论分享给相关人员,例如领导或者业务人员。这个时候就需要考虑如何展示结论,以什么样的形式展现,这就要用到数据可视化了。

1.5 数据分析工具:Excel与Python

同一个操作可以使用不同的工具实现,不同工具的实现方式是不一样的,Excel 是通过鼠标点选的方式来操作数据,而 Python需要通过具体的代码来操作数据。虽然两者的操作方式是不一样的,但都可以达到导入外部数据这一操作的目的。Python在数据分析领域只不过是和Excel类似的一个数据分析工具而已。

本书的编写都是按照这种方式进行的,针对数据分析中的每一个操作,分别用Excel和Pyhon对比实现。

第2章 Python基础知识

(略)

第3章 Pandas数据结构

前面讲了Python的基础知识,从这一章开始进入正式的数据分析过程中,主要讲述每个数据分析过程都会用到什么操作,这些操作用 Excel 是怎么实现的,如果用Python,那么代码应该怎么写。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

3.1 Series数据结构

Series是什么

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

3b656dcc7d50d177032c076e09c81614.png

上面这样的数据结构就是Series,第一列数字是数据标签第二列是具体的数据,数据标签与数据是一一对应的。

上面的数据用Excel表展示如下表所示。

e4541a99ba3b44001826a80284b5c0ea.png

创建一个Series

创建一个Series利用的方法是pd.Series(),通过给Series()方法传入不同的对象即可实现。

传入一个列表

如果只是传入一个列表不指定数据标签,那么Series会默认使用从0开始的数做数据标签,上面的0、1、2、3就是默认的数据标签。

# -*- coding:utf-8 -*-
import pandas as pd

s1 = pd.Series(["a","b","c"])
print(s1)
"""
0    a
1    b
2    c
dtype: object
"""
指定索引

直接传入一个列表会使用默认索引,也可以通过设置index参数来自定义索引。

# -*- coding:utf-8 -*-
import pandas as pd

s1 = pd.Series(["whw","naruto","sasuke"],index=["a","b","c"])
print(s1)
"""
a    whw
b    naruto
c    sasuke
dtype: object
"""
传入一个字典

也可以将数据与数据标签以key:value(字典)的形式传入,这样字典的key值就是数据标签,value就是数据值。

# -*- coding:utf-8 -*-
import pandas as pd

s1 = pd.Series({"a":"whw","b":"sakura","c":"hahaha"})
print(s1)
"""
a    whw
b    sakura
c    hahaha
dtype: object
"""

利用index方法获取Series的索引

获取一组数据的索引是比较常见的需求,直接利用 index 方法就可以获取 Series的索引值,代码如下所示。

# -*- coding:utf-8 -*-
import pandas as pd

s1 = pd.Series({"a":"whw","b":"sakura","c":"hahaha"})
print(s1.index) # Index(['a', 'b', 'c'], dtype='object')
print(s1.index[0]) # a
print(s1.index[1]) # b
print(s1.index[2]) # c
# 超出范围会报错
print(s1.index[3]) #  IndexError: index 3 is out of bounds for axis 0 with size 3

利用values方法获取Series的值

与索引值对应的就是获取Series的值,使用的方法是values方法。

# -*- coding:utf-8 -*-
import pandas as pd

s1 = pd.Series({"a":"whw","b":"sakura","c":"hahaha"})
print(s1.values,type(s1.values)) # ['whw' 'sakura' 'hahaha'] <class 'numpy.ndarray'>
print(s1.values[1]) # sakura

3.2 DataFrame表格型数据结构

DataFrame是什么

Series是由一组数据与一组索引(行索引)组成的数据结构,而DataFrame是由一组数据与一对索引(行索引和列索引)组成的表格型数据结构。

之所以叫表格型数据结构,是因为DataFrame的数据形式和Excel的数据存储形式很相近,接下来的章节主要围绕DataFrame这种表格型数据结构展开。下面就是一个简单的DataFrame数据结构。

79ea4ffdfb64adf5f557bae99b24e069.png

上面这种数据结构和Excel的数据结构很像,既有行索引又有列索引,由行索引和列索引确定唯一值。如果把上面这种结构用Excel表展示如下表所示。

7e09bf6af55505f1c437fb8c8378f06f.png

创建一个DataFrame

创建DataFrame使用的方法是pd.DataFrame(),通过给DataFrame()方法传入不同的对象即可实现。

传入一个列表

只传入一个单一列表时,该列表的值会显示成一列,且行和列都是从0开始的默认索引。

# -*- coding:utf-8 -*-
import pandas as pd

df1 = pd.DataFrame(["aa","bb","cc"])
print(df1)
"""
    0
0  aa
1  bb
2  cc
"""
传入一个嵌套列表 *

当传入一个嵌套列表时,会根据嵌套列表数显示成多列数据,行、列索引同样是从0开始的默认索引。列表里面嵌套的列表也可以换成元组

# -*- coding:utf-8 -*-
import pandas as pd

df1 = pd.DataFrame([["aa","A"],["bb","B"],["cc","C"]])
print(df1)
"""
    0  1
0  aa  A
1  bb  B
2  cc  C
"""
指定行、列的索引 *

如果只给DataFrame()方法传入列表,DataFrame()方法的行、列索引都是默认值,则可以通过设置columns参数自定义列索引,设置index参数自定义行索引

# -*- coding:utf-8 -*-
import pandas as pd

# 设置列索引
df31 = pd.DataFrame([["aa","A"],["bb","B"],["cc","C"]],columns=["小写","大写"])
print(df31)
"""
   小写 大写
0  aa  A
1  bb  B
2  cc  C
"""

# 设置行索引
df41 = pd.DataFrame([["aa","A"],["bb","B"],["cc","C"]],index=["一","二","三"])
print(df41)
"""
    0  1
一  aa  A
二  bb  B
三  cc  C
"""

# 同时设置行 列索引
df51 = pd.DataFrame([["aa","A"],["bb","B"],["cc","C"]],
                    columns=["小写","大写"],
                    index=["一","二","三"])
print(df51)
"""
   小写 大写
一  aa  A
二  bb  B
三  cc  C
"""
传入一个字典

直接以字典的形式传入DataFrame时,字典的key值就相当于列索引,这个时候如果没有设置行索引,行索引还是使用从0开始的默认索引,同样可以使用index参数自定义行索引,代码如下:

# -*- coding:utf-8 -*-
import pandas as pd

# 字典的key是列索引 行索引不指定的话默认从0开始 也可以指定行索引
data = pd.DataFrame({"name":["whw","naruto","sasuke"],"age":[18,29,22]},
                    index=["一","二","三"])
print(data)
"""
     name  age
一     whw   18
二  naruto   29
三  sasuke   22
"""

获取DataFrame行、列索引

使用columns方法获取DataFrame的列索引

使用index方法获取DataFrame的行索引

# -*- coding:utf-8 -*-
import pandas as pd

# 字典的key是列索引 行索引不指定的话默认从0开始 也可以指定行索引
data = pd.DataFrame({"name":["whw","naruto","sasuke"],"age":[18,29,22]},
                    index=["一","二","三"])
# 列索引
print(data.columns) # Index(['name', 'age'], dtype='object')

# 行索引
print(data.index) # Index(['一', '二', '三'], dtype='object')

获取DataFrame的值

获取DataFrame的值就是获取DataFrame中的某些行或列,有关行、列的选择在第6章会有详细讲解。

第4章 获取数据源

4.1 导入外部数据(.xlsx文件)

导入数据主要用到的是Pandas里的read_x()方法,x表示待导入文件的格式。

导入.xlsx文件

在 Excel 中导入.xlsx 格式的文件很简单,双击打开即可。在 Python 中导入.xlsx文件的方法是read_excel()。

test.xlsx中的内容如下:

d97209b190c38e6b863e72c37f44c24e.png

基本导入

不指定sheet_name参数时,那么默认导入的都是第一个Sheet的文件

# -*- coding:utf-8 -*-
import pandas as pd

# 读取excel中的内容 路径放在了桌面下
df = pd.read_excel(r"~/Desktop/test.xlsx")
print(df)
"""
   编号      姓名    年龄       注册日期
0  A1       whw     22        2020-10-12
1  A2    naruto     23        2020-10-12
2  A3    sasuke     24        2020-10-12
"""

指定导入哪个Sheet

.xlsx格式的文件可以有多个Sheet,你可以通过设定sheet_name参数来指定要导入哪个Sheet的文件。

# -*- coding:utf-8 -*-
import pandas as pd

### 方法一 指定Sheet的名称
df = pd.read_excel(r"~/Desktop/test.xlsx",sheet_name="Sheet1")
print(df)
"""
   编号      姓名    年龄       注册日期
0  A1       whw     22        2020-10-12
1  A2    naruto     23        2020-10-12
2  A3    sasuke     24        2020-10-12
"""

### 方法二 传入Sheet的顺序 —— 从0开始计数 导入第1个Sheet
df2 = pd.read_excel(r"~/Desktop/test.xlsx",sheet_name=0)
print(df2)
"""
   编号      姓名    年龄       注册日期
0  A1       whw     22        2020-10-12
1  A2    naruto     23        2020-10-12
2  A3    sasuke     24        2020-10-12
"""

指定行索引

将本地文件导入DataFrame时,行索引使用的从0开始的默认索引,可以通过设置index_col参数来设置。

# -*- coding:utf-8 -*-
import pandas as pd

# 指定行索引 —— 就是将那一列当作行索引 —— 将第2列作为行索引(索引从0开始)
df = pd.read_excel(r"~/Desktop/test.xlsx",sheet_name="Sheet1",index_col=1)
print(df)
"""
        编号  年龄       注册日期
姓名                       
whw     A1   22       2020-10-12
naruto  A2   23       2020-10-12
sasuke  A3   24       2020-10-12
"""

指定列索引

将本地文件导入DataFrame时,默认使用源数据表的第一行作为列索引,也可以通过设置header参数来设置列索引。

header参数值默认为0,即用第一行作为列索引;也可以是其他行,只需要传入具体的那一行即可;也可以使用默认从0开始的数作为列索引。

# -*- coding:utf-8 -*-
import pandas as pd

# 使用第一行作为列索引
df = pd.read_excel(r"~/Desktop/test.xlsx",sheet_name=0,header=0)
print(df)
"""
   编号      姓名  年龄       注册日期
0  A1     whw  22 2020-10-12
1  A2  naruto  23 2020-10-12
2  A3  sasuke  24 2020-10-12
"""

# 使用第三行作为列索引
df2 = pd.read_excel(r"~/Desktop/test.xlsx",sheet_name=0,header=2)
print(df2)
"""
   A2  naruto  23 2020-10-12 00:00:00
0  A3  sasuke  24          2020-10-12
"""

# 使用默认从0开始的数作为列索引
df3 = pd.read_excel(r"~/Desktop/test.xlsx",sheet_name=0,header=None)
print(df3)
"""
    0       1       2                       3
0  编号     姓名   年龄                 注册日期
1  A1     whw     22               2020-10-12 00:00:00
2  A2  naruto     23               2020-10-12 00:00:00
3  A3  sasuke     24               2020-10-12 00:00:00
"""

指定导入列

有的时候本地文件的列数太多,而我们又不需要那么多列时,我们就可以通过设定usecols参数来指定要导入的列。

# -*- coding:utf-8 -*-
import pandas as pd

# 指定导入的列
df = pd.read_excel(r"~/Desktop/test.xlsx",usecols=[1,3])
print(df)
"""
       姓名       注册日期
0     whw     2020-10-12
1  naruto     2020-10-12
2  sasuke     2020-10-12
"""

4.1 导入外部数据(.csv文件)

在 Excel 中导入.csv 格式的文件和打开.xlsx 格式的文件一样,双击即可。

tt.csv文件中的内容如下:

c5f1a9de90f9ac6238f5ed2c9f611c75.png

在 Excel 中导入.csv 格式的文件和打开.xlsx 格式的文件一样,双击即可。而在Python中导入.csv文件用的方法是read_csv()

直接导入

# -*- coding:utf-8 -*-
import pandas as pd

# 直接指定文件路径即可
df = pd.read_csv(r"~/Desktop/tt.csv")
print(df)
"""
     name  age  gender
0     whw   19    male
1  naruto   22    male
2  sakura   22  female
"""

指明分隔符号

在Excel和DataFrame中的数据都是很规整的排列的,这都是工具在后台根据某条规则进行切分的。read_csv()默认文件中的数据都是以逗号分开的,但是有的文件不是用逗号分开的,这个时候就需要人为指定分隔符号,否则就会报错。

将之前的文件的分隔符按照 | 分隔:

fd4bab5911605db6b57311de6a576162.png

如果用默认的逗号作为分隔符号,我们看到所有的数据还是一个整体,并没有被分开~

# -*- coding:utf-8 -*-
import pandas as pd

# 默认使用逗号分隔,如果原文件不是使用逗号分隔的就会出问题:没有将文件内容分开
df = pd.read_csv(r"~/Desktop/tt.csv")
print(df)
"""
    name|age|gender
0       whw|19|male
1    naruto|22|male
2  sakura|22|female
"""

指定分隔符号试试:

# -*- coding:utf-8 -*-
import pandas as pd

# 指定分隔符号
df = pd.read_csv(r"~/Desktop/tt.csv",sep="|")
print(df)
"""
     name  age  gender
0     whw   19    male
1  naruto   22    male
2  sakura   22  female
"""

常见的分隔符号除了逗号、空格,还有制表符(\t)

指明读取行数

假设现在有一个几百兆的文件,你想了解一下这个文件里有哪些数据,那么这个时候你就没必要把全部数据都导入,你只要看到前面几行即可,因此只要设置nrows参数即可。

# -*- coding:utf-8 -*-
import pandas as pd

# 指定读取的行数
df = pd.read_csv(r"~/Desktop/tt.csv",sep="|",nrows=1)
print(df)
"""
  name  age gender
0  whw   19   male
"""

指定编码格式

Python用得比较多的两种编码格式是UTF-8和gbk,默认编码格式是UTF-8

我们要根据导入文件本身的编码格式进行设置,通过设置参数encoding设置导入的编码格式

有的时候两个文件看起来一样,它们的文件名一样,格式也一样,但如果它们的编码格式不一样,也是不一样的文件,比如当你把一个Excel文件另存为时会出现两个选项,虽然都是.csv文件,但是这两种格式代表两种不同的文件。

# -*- coding:utf-8 -*-
import pandas as pd

# 指定编码格式
df = pd.read_csv(r"~/Desktop/tt.csv",sep="|",nrows=1,encoding="utf-8")
print(df)
"""
  name  age gender
0  whw   19   male
"""

engine指定 *

文件路径或者文件名包含中文时,如果还用上面的导入方式就会报错。

这个时候我们就可以通过设置engine参数来消除这个错误。

这个错误产生的原因是当调用read_csv()方法时,默认使用C语言作为解析语言,我们只需要把默认值C更改为Python就可以了

如果文件格式是CSV UTF-8(逗号分隔)(*.csv),那么编码格式也需要跟着变为utf-8-sig,如果文件格式是CSV(逗号分隔)(*.csv)格式,对应的编码格式则为gbk。

# -*- coding:utf-8 -*-
import pandas as pd

# 文件名包含中文
df = pd.read_csv(r"~/Desktop/王宏伟测试.csv",engine="python",encoding="utf-8-sig")
print(df)
"""
     姓名  年龄
0   whw  12
1   www  22
2  wwwa  33
"""

4.1 导入外部数据(.txt文件)

(略 有需要再看) —— 现在数据基本不往txt里存了吧!

4.1 导入外部数据(.sql文件)

(略)—— 可以利用Python操作MySQL:SQLAlchemy、pymysql等~

4.2 新建数据

这里的新建数据主要指新建 DataFrame 数据,我们在第3章的时候讲过,利用pd.DataFrame()方法进行新建。

4.3 熟悉数据

# -*- coding:utf-8 -*-
import pandas as pd

# 文件名包含中文
df = pd.read_csv(r"~/Desktop/王宏伟测试.csv",engine="python",encoding="utf-8-sig")
print(df)
"""
     姓名  年龄
0   whw  12
1   www  22
2  wwwa  33
"""

# head()方法控制显示的行数
print(df.head(2))
"""
    姓名  年龄
0  whw  12
1  www  22
"""

# shape获取数据表的大小
print(df.shape)
"""
(3, 2)
"""

# info()获取数据类型
print(df.info())
"""
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3 entries, 0 to 2
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype 
---  ------  --------------  ----- 
 0   姓名      3 non-null      object
 1   年龄      3 non-null      int64 
dtypes: int64(1), object(1)
memory usage: 176.0+ bytes
None
"""

# describe()获取数值分布情况
print(df.describe())
"""
              年龄
count   3.000000
mean   22.333333
std    10.503968
min    12.000000
25%    17.000000
50%    22.000000
75%    27.500000
max    33.000000
"""

第5章 数据预处理

从菜市场买来的菜,总有一些不太好的,所以把菜买回来以后要先做一遍预处理,把那些不太好的部分扔掉。现实中大部分的数据都类似于菜市场的菜品,拿到以后都要先做一次预处理。

常见的不规整数据主要有缺失数据重复数据异常数据几种,在开始正式的数据分析之前,我们需要先把这些不太规整的数据处理掉。

5.1 缺失值处理

缺失值就是由某些原因导致部分数据为空,对于为空的这部分数据我们一般有两种处理方式,一种是删除,即把含有缺失值的数据删除另一种是填充,即把缺失的那部分数据用某个值代替

缺失值查看

info()方法 ———— 上面的代码有介绍!

对缺失值进行处理,首先要把缺失值找出来,也就是查看哪列有缺失值。

文件中的内容如下(年龄少了一个值):

fc085e935cc45ba11a083506af0a72ec.png

使用info()方法获取到的结果:

173886c0366c2ef715393031db73c80d.png

isnull()方法

# 使用isnull()判断数据缺失情况
print(df.isnull())
"""
      姓名     年龄
0  False  False
1  False   True # 这里的年龄是空的
2  False  False
"""

缺失值删除

缺失值分为两种,一种是一行中某个字段是缺失值;另一种是一行中的字段全部为缺失值,即为一个空白行。

在Python中,我们利用的是dropna()方法,dropna()方法默认删除含有缺失值的行,也就是只要某一行有缺失值就把这一行删除

# -*- coding:utf-8 -*-
import pandas as pd

# 文件名包含中文
df = pd.read_csv(r"~/Desktop/王宏伟测试.csv",engine="python",encoding="utf-8-sig")
print(df)
"""
     姓名  年龄
0   whw  12
1   www  NaN
2  wwwa  33
"""

# 删除空行显示
print(df.dropna())
"""
     姓名    年龄
0   whw  12.0
2  wwwa  33.0
"""

如果想删除空白行,只要给dropna()方法传入一个参数how="all"即可,这样就会只删除那些全为空值的行,不全为空值的行就不会被删除

# -*- coding:utf-8 -*-
import pandas as pd

# 文件名包含中文
df = pd.read_csv(r"~/Desktop/王宏伟测试.csv",engine="python",encoding="utf-8-sig")
print(df)
"""
     姓名  年龄
0   whw  12
1   www  NaN
2  wwwa  33
"""

# 只删除全是空白的行
print(df.dropna(how="all"))
"""
     姓名    年龄
0   whw  12.0
1   www   NaN
2  wwwa  33.0
"""

缺失值填充

上面介绍了缺失值的删除,但是数据是宝贵的,一般情况下只要数据缺失比例不是过高(不大于30%),尽量别删除,而是选择填充。

在Python中,我们利用的fillna()方法对数据表中的所有缺失值进行填充,在fillna后面的括号中输入要填充的值即可。

# -*- coding:utf-8 -*-
import pandas as pd

# 文件名包含中文
df = pd.read_csv(r"~/Desktop/王宏伟测试.csv",engine="python",encoding="utf-8-sig")
print(df)
"""
     姓名  年龄
0   whw  12
1   www  NaN
2  wwwa  33
"""

# 删除空行显示
print(df.fillna(18))
"""
     姓名    年龄
0   whw  12.0
1   www  18.0
2  wwwa  33.0
"""

5.2 重复值处理

重复数据就是同样的记录有多条,对于这样的数据我们一般做删除处理

在Python中我们利用drop_duplicates()方法,该方法默认对所有值进行重复值判断,且默认保留第一个(行)值。

# -*- coding:utf-8 -*-
import pandas as pd

# 文件名包含中文
df = pd.read_csv(r"~/Desktop/王宏伟测试.csv",engine="python",encoding="utf-8-sig")
print(df)
"""
     姓名  年龄
0   whw  12
1   www  19
2  wwwa  33
3  wwwa  33
4   www  19
"""

# 删除重复值
print(df.drop_duplicates())
"""
     姓名  年龄
0   whw  12
1   www  19
2  wwwa  33
"""

上面的代码是针对所有字段进行的重复值判断,我们同样也可以只针对某一列或某几列进行重复值删除的判断,只需要在drop_duplicates()方法中指明要判断的列名即可。

# -*- coding:utf-8 -*-
# -*- coding:utf-8 -*-
import pandas as pd

# 文件名包含中文
df = pd.read_csv(r"~/Desktop/王宏伟测试.csv",engine="python",encoding="utf-8-sig")
print(df)
"""
     姓名  年龄
0   whw  12
1   www  19
2  wwwa  33
3  wwwa  33
4   www  19
"""

# 删除重复值 指定列名
print(df.drop_duplicates(subset=["姓名","年龄"]))
"""
     姓名  年龄
0   whw  12
1   www  19
2  wwwa  33
"""

还可以自定义删除重复项时保留哪个,默认保留第一个,也可以设置保留最后一个,或者全部不保留。通过传入参数keep进行设置,参数keep默认值是first,即保留第一个值;也可以是last,保留最后一个值;还可以是False,即把重复值全部删除。

# -*- coding:utf-8 -*-
import pandas as pd

# 文件名包含中文
df = pd.read_csv(r"~/Desktop/王宏伟测试.csv",engine="python",encoding="utf-8-sig")
print(df)
"""
     姓名  年龄
0   whw  12
1   www  19
2  wwwa  33
3  wwwa  33
4   www  19
"""

# 删除重复值 指定列名
print(df.drop_duplicates(subset=["姓名","年龄"],keep=False))
"""
    姓名  年龄
0  whw  12
"""

5.3 异常值的检测与处理

异常值就是相比正常数据而言过高或过低的数据,比如一个人的年龄是0岁或者300岁都算是一个异常值,因为这和实际情况差距过大。

异常值检测

要处理异常值首先要检测,也就是发现异常值,发现异常值的方式主要有以下三种。

  • 根据业务经验划定不同指标的正常范围,超过该范围的值算作异常值。
  • 通过绘制箱形图,把大于(小于)箱形图上边缘(下边缘)的点称为异常值。
  • 如果数据服从正态分布,则可以利用3σ 原则;如果一个数值与平均值之间的偏差超过3倍标准差,那么我们就认为这个值是异常值。

箱形图如下图所示,关于箱形图的绘制方法我们会在第13章介绍。

40a2281015be26151f865e3bfb41035a.png

下图为正态分布图,我们把大于μ+3σ的值称为异常值。

2cdf63f52bc8c5aec625cd36541d0b08.png

异常值处理

对于异常值一般有以下几种处理方式。

  • 最常用的处理方式就是删除。
  • 把异常值当作缺失值来填充。
  • 把异常值当作特殊情况,研究异常值出现的原因。

在Python中,删除异常值用到的方法和Excel中的方法原理类似,Python中是通过过滤的方法对异常值进行删除。比如 df 表中有年龄这个指标,要把年龄大于200的值删掉,你可以通过筛选把年龄不大于200的筛出来,筛出来的部分就是删除大于200的值以后的新表。

对异常值进行填充,就是对异常值进行替换,利用replace()方法可以对特定的值进行替换。

关于数据筛选和数据替换会在接下来的章节介绍。

5.4 数据类型转换

数据类型

Pandas不像Excel分得那么详细,它主要有6种数据类型,如下表所示。

430b57bc9219c8358553b79d21ed0851.png

在 Python 中,不仅可以用 info()方法获取每一列的数据类型,还可以通过 dtype方法来获取某一列的数据类型。

# -*- coding:utf-8 -*-
import pandas as pd

# 文件名包含中文
df = pd.read_csv(r"~/Desktop/王宏伟测试.csv",engine="python",encoding="utf-8-sig")
print(df)
"""
     姓名  年龄
0   whw  12
1   www  19
2  wwwa  33
3  wwwa  33
4   www  19
"""

# dtype方法获取某一列的数据类型
print(df["姓名"].dtype) # object
print(df["年龄"].dtype) # int64

类型转换

在Python中,我们利用astype()方法对数据类型进行转换,astype后面的括号里指明要转换的目标类型即可

# -*- coding:utf-8 -*-
import pandas as pd

# 文件名包含中文
df = pd.read_csv(r"~/Desktop/王宏伟测试.csv",engine="python",encoding="utf-8-sig")
print(df)
"""
     姓名  年龄
0   whw  12
1   www  19
2  wwwa  33
3  wwwa  33
4   www  19
"""

# astype方法对数据类型进行转换
# 注意得获取返回值!!不会在源数据上修改!!!
ret = df["年龄"].astype("float64")
print(ret)
"""
0    12.0
1    19.0
2    33.0
3    33.0
4    19.0
Name: 年龄, dtype: float64
"""

5.5 索引设置

索引是查找数据的依据,设置索引的目的是便于我们查找数据。举个例子,你逛超市买了很多食材,回到家以后要把它们放在冰箱里,放的过程其实就是一个建立索引的过程,比如蔬菜放在冷藏室,肉类放在冷冻室,这样在找的时候就能很快找到。

为无索引表添加索引

在Python中,如果表没有索引,会默认用从0开始的自然数做索引,比如下面这样:

# -*- coding:utf-8 -*-
import pandas as pd

df1 = pd.DataFrame([["aa","A"],["bb","B"],["cc","C"]])
print(df1)
"""
    0  1
0  aa  A
1  bb  B
2  cc  C
"""

通过给表df的columns参数传入列索引值index参数传入行索引值达到为无索引表添加索引的目的,具体实现如下:

# -*- coding:utf-8 -*-
import pandas as pd

df1 = pd.DataFrame([["aa","A"],["bb","B"],["cc","C"]])
print(df1)
"""
    0  1
0  aa  A
1  bb  B
2  cc  C
"""

# 添加列索引值
df1.columns = ["小写","大写"]
print(df1)
"""
   小写 大写
0  aa  A
1  bb  B
2  cc  C
"""

# 添加行索引值
df1.index = [1,2,3]
print(df1)
"""
   小写 大写
1  aa  A
2  bb  B
3  cc  C
"""

重新设置索引

重新设置索引,一般指行索引的设置。有的表虽然有索引,但不是我们想要的索引,比如现在有一个表是把序号作为行索引,而我们想要把订单编号作为行索引,该怎么实现呢?

在Excel中重新设置行索引比较简单,你想让哪一列做行索引,直接把这一列拖到第一列的位置即可。

在Python中可以利用set_index()方法重新设置索引列,在set_index()里指明要用作行索引的列的名称即可。

# -*- coding:utf-8 -*-
import pandas as pd

df1 = pd.DataFrame([["aa","A"],["bb","B"],["cc","C"]])
print(df1)
"""
    0  1
0  aa  A
1  bb  B
2  cc  C
"""

# 添加列索引值
df1.columns = ["小写","大写"]
print(df1)
"""
   小写 大写
0  aa  A
1  bb  B
2  cc  C
"""

# 添加行索引值
df1.index = [1,2,3]
print(df1)
"""
   小写 大写
1  aa  A
2  bb  B
3  cc  C
"""

# 重新设置索引 ———— 注意 获取的是返回值!!!
ret = df1.set_index(["大写"])
print(ret)
"""
    小写
大写    
A   aa
B   bb
C   cc
"""

在重新设置索引时,还可以给 set_index()方法传入两个或多个列名,我们把这种一个表中用多列来做索引的方式称为层次化索引,层次化索引一般用在某一列中含有多个重复值的情况下。层次化索引的例子,如下所示,其中 a、b、c、d 分别有多个重复值。

301fe8cfafa963e8609615f52fecd835.png

重命名索引

在Python中重命名索引,我们利用的是rename()方法,在rename后的括号里指明要修改的行索引及列索引名

# -*- coding:utf-8 -*-
import pandas as pd

df1 = pd.DataFrame([["aa","A"],["bb","B"],["cc","C"]])
print(df1)
"""
    0  1
0  aa  A
1  bb  B
2  cc  C
"""

# 添加列索引值
df1.columns = ["小写","大写"]
print(df1)
"""
   小写 大写
0  aa  A
1  bb  B
2  cc  C
"""

# 添加行索引值
df1.index = [1,2,3]
print(df1)
"""
   小写 大写
1  aa  A
2  bb  B
3  cc  C
"""

# 重命名列索引 注意获取的是返回值!!!
ret1 = df1.rename(columns={"小写":"lower","大写":"upper"})
print(ret1)
"""
  lower upper
1    aa     A
2    bb     B
3    cc     C
"""

# 重命名行索引 注意获取的是返回值!!!
ret2 = df1.rename(index={1:"一",2:"二",3:"三"})
print(ret2)
"""
   小写 大写
一  aa  A
二  bb  B
三  cc  C
"""

重置索引 ***

重置索引主要用在层次化索引表中,重置索引是将索引列当作一个columns进行返回。

在下图左侧的表中,Z1、Z2是一个层次化索引,经过重置索引以后,Z1、Z2这两个索引以columns的形式返回,变为常规的两列。

daa31b7e11b52575c3f8d41c057b14ed.png

在Excel中,我们要进行这种转换,直接通过复制、粘贴、删除等功能就可以实现,比较简单。我们主要讲一下在Python中怎么实现。

在Python利用的是reset_index()方法,reset_index()方法常用于数据分组数据透视表中。

reset_index()方法常用的参数如下:

reset_index(level=None, drop=False, inplace=False)

level参数用来指定要将层次化索引的第几级别转化为columns,第一个索引为0级,第二个索引为1级,默认为全部索引,即默认把索引全部转化为columns。

drop参数用来指定是否将原索引删掉,即不作为一个新的columns,默认为False,即不删除原索引。

inplace参数用来指定是否修改原数据表。

3d0cba94d0969ae6b1c501582b13e080.png

第6章 数据选择

之前是把所有的菜品都洗好并放在不同的容器里。现在要进行切配了,需要把这些菜品挑选出来,比如做一盘凉拌黄瓜,需要先把黄瓜找出来;要做一盘可乐鸡翅,需要先把鸡翅找出来。

数据分析也是同样的道理,你要分析什么,首先要把对应的数据筛选出来。

常规的数据选择主要有列选择行选择行列同时选择三种方式。

6.1 列选择 ***

选择某1列/某几列

位置索引 —— 通过传入具体位置来选择数据的方式。

方法1

在Python中我们要想获取某列只需要在表df后面的方括号中指明要选择的列名即可。如果是一列,则只需要传入一个列名;如果是同时选择多列,则传入多个列名即可,多个列名用一个list存起来。

# -*- coding:utf-8 -*-
import pandas as pd

df = pd.read_csv(r"~/Desktop/王宏伟测试.csv")
print(df)
"""
     姓名  年龄      性别
0   whw  12    male
1   www  19    male
2  wwwa  33  female
3   whh  23  female
"""

# 选择某一列
ret1 = df["姓名"]
print(ret1)
"""
0     whw
1     www
2    wwwa
3     whh
Name: 姓名, dtype: object
"""

# 选择某几列
ret2 = df[["姓名","性别"]]
print(ret2)
"""
     姓名      性别
0   whw    male
1   www    male
2  wwwa  female
3   whh  female
"""
方法2

除了传入具体的列名,我们还可以传入具体列的位置,即第几列,对数据进行选取,通过传入位置来获取数据时需要用到iloc方法。

# -*- coding:utf-8 -*-
import pandas as pd

df = pd.read_csv(r"~/Desktop/王宏伟测试.csv")
print(df)
"""
     姓名  年龄      性别
0   whw  12    male
1   www  19    male
2  wwwa  33  female
3   whh  23  female
"""

# 选取第1列与第3列的所有行的数据
ret = df.iloc[:,[0,2]]
print(ret)
"""     姓名      性别
0   whw    male
1   www    male
2  wwwa  female
3   whh  female
"""

在上面的代码中,iloc 后的方括号中逗号之前的部分表示要获取的行的位置,只输入一个冒号,不输入任何数值表示获取所有的行;逗号之后的方括号表示要获取的列的位置,列的位置同样是也是从0开始计数。

选择连续的某几列

在Python中可以通过前面介绍的普通索引和位置索引获取某一列或多列的数据。当你要获取的是连续的某几列,用普通索引和位置索引也是可以做到的,但是因为你要获取的列是连续的,所以只要传入这些连续列的位置区间即可,同样需要用到iloc方法。

# -*- coding:utf-8 -*-
import pandas as pd

df = pd.read_csv(r"~/Desktop/王宏伟测试.csv")
print(df)
"""
     姓名  年龄      性别
0   whw  12    male
1   www  19    male
2  wwwa  33  female
3   whh  23  female
"""

# 选取第1列与第3列的所有行的数据
ret = df.iloc[:,[0,2]]
print(ret)
"""     姓名      性别
0   whw    male
1   www    male
2  wwwa  female
3   whh  female
"""

在上面的代码中,iloc 后的方括号中逗号之前的表示选择的行,当只传入一个冒号时,表示选择所有行;逗号后面表示要选择列的位置区间,0:3表示选择第1列到第4列之间的值(包含第1列但不包含第4列),我们把这种通过传入一个位置区间来获取数据的方式称为切片索引。

6.2 行选择 ***

在Python中,获取行的方式主要有两种:
一种是普通索引,即传入具体行索引的名称,需要用到loc方法;
另一种是位置索引,即传入具体的行数,需要用到iloc方法。

loc方法

# -*- coding:utf-8 -*-
import pandas as pd

df = pd.read_csv(r"~/Desktop/王宏伟测试.csv")
print(df)
"""
     姓名  年龄      性别
0   whw  12    male
1   www  19    male
2  wwwa  33  female
3   whh  23  female
"""
# 选择一行
print(df.loc[0])
"""
姓名     whw
年龄      12
性别    male
Name: 0, dtype: object
"""


### 重命名行索引后再试试
ret = df.rename(index={0:"一",1:"二",2:"三",3:"四"})
print(ret)
"""
     姓名  年龄      性别
一   whw  12    male
二   www  19    male
三  wwwa  33  female
四   whh  23  female
"""
# 选择一行
print(ret.loc["一"])
"""
姓名     whw
年龄      12
性别    male
Name: 一, dtype: object
"""
# 选择第一行与第三行
print(ret.loc[["一","三"]])
"""
     姓名  年龄      性别
一   whw  12    male
三  wwwa  33  female
"""

iloc方法

# -*- coding:utf-8 -*-
import pandas as pd

df = pd.read_csv(r"~/Desktop/王宏伟测试.csv")
print(df)
"""
     姓名  年龄      性别
0   whw  12    male
1   www  19    male
2  wwwa  33  female
3   whh  23  female
"""
# 选择一行
print(df.iloc[0])
"""
姓名     whw
年龄      12
性别    male
Name: 0, dtype: object
"""

# 选择第一行与第二行
print(df.iloc[[0,1]])
"""
    姓名  年龄    性别
0  whw  12  male
1  www  19  male
"""

选择连续的几行

在Python中,选择连续的某几行时,你同样可以把要选择的每一个行索引名字或者行索引的位置输进去。很显然这是没有必要的,只要把连续行的位置用一个区间表示,然后传给iloc即可

# -*- coding:utf-8 -*-
import pandas as pd

df = pd.read_csv(r"~/Desktop/王宏伟测试.csv")
print(df)
"""
     姓名  年龄      性别
0   whw  12    male
1   www  19    male
2  wwwa  33  female
3   whh  23  female
"""

# 选择第一行与到第三行 —— 左闭右开区间
print(df.iloc[0:3])
"""
     姓名  年龄      性别
0   whw  12    male
1   www  19    male
2  wwwa  33  female
"""

选择满足条件的行

比如年龄这一列,需要把非异常值(大于200的属于异常值),即小于200岁的年龄筛选出来,该怎么实现呢?

在Excel中我们直接使用筛选功能,将满足条件的值筛选出来,筛选方法如下图所示。

5868f947e8f51e93bfbc6dba9a1ec9b3.png

Python实现

在Python中,我们直接在表名后面指明哪列要满足什么条件,就可以把满足条件的数据筛选出来。

# -*- coding:utf-8 -*-
import pandas as pd

df = pd.read_csv(r"~/Desktop/王宏伟测试.csv")
print(df)
"""
     姓名  年龄      性别
0   whw  12    male
1   www  19    male
2  wwwa  33  female
3   whh  23  female
"""

# 筛选出性别为male的
ret = df[df["性别"]=="male"]
print(ret)
"""
    姓名  年龄    性别
0  whw  12  male
1  www  19  male
"""

我们把上面这种通过传入一个判断条件来选择数据的方式称为布尔索引

传入的条件还可以是多个,如下为选择的年龄小于200且唯一识别码小于102的数据。

# -*- coding:utf-8 -*-
import pandas as pd

df = pd.read_csv(r"~/Desktop/王宏伟测试.csv")
print(df)
"""
     姓名  年龄      性别
0   whw  12    male
1   www  19    male
2  wwwa  33  female
3   whh  23  female
"""

### 筛选出性别为male 并且年龄大于15岁的
## 写法1
# 两个条件
condition1 = df["性别"]=="male"
condition2 = df["年龄"]>15
# 条件
condition = condition1 & condition2
# 结果
ret = df[condition]
print(ret)
"""
    姓名  年龄    性别
0  whw  12  male
1  www  19  male
"""

## 写法2 —— 结合一下即可
ret2 = df[(df["性别"]=="male") & (df["年龄"]>15)]
print(ret2)
"""
    姓名  年龄    性别
1  www  19  male
"""

6.3 行列同时选择 ***

上面的数据选择都是针对单一的行或列进行选择,实际业务中我们也会用到行、列同时选择,所谓的行、列同时选择就是选择出行和列的相交部分。

例如,我们要选择第二、三行和第二、三列相交部分的数据,下图中的阴影部分就是最终的选择结果。

b09899ccdd5207983f5fad07e36a0081.png

“普通索引+普通索引”选择指定的行和列

普通索引+普通索引就是通过同时传入行和列的索引名称进行数据选择,需要用到loc方法。

# -*- coding:utf-8 -*-
import pandas as pd

df = pd.read_csv(r"~/Desktop/王宏伟测试.csv")
print(df)
"""
     姓名  年龄      性别
0   whw  12    male
1   www  19    male
2  wwwa  33  female
3   whh  23  female
"""

# 利用loc方法传入行列名称
ret = df.loc[[0,1],["姓名","性别"]]
print(ret)
"""
    姓名    性别
0  whw  male
1  www  male
"""

loc方法中的第一对方括号表示行索引的选择,传入行索引名称;loc方法中的第二对方括号表示列索引的选择,传入列索引名称。

"位置索引+位置索引"选择指定的行与列

位置索引+位置索引是通过同时传入行、列索引的位置来获取数据,需要用到iloc方法。

# -*- coding:utf-8 -*-
import pandas as pd

df = pd.read_csv(r"~/Desktop/王宏伟测试.csv")
print(df)
"""
     姓名  年龄      性别
0   whw  12    male
1   www  19    male
2  wwwa  33  female
3   whh  23  female
"""

# 利用iloc方法传入行列位置
ret = df.iloc[[2,3],[0,2]]
print(ret)
"""
     姓名      性别
2  wwwa  female
3   whh  female
"""

在iloc方法中的第一对方括号表示行索引的选择,传入要选择行索引的位置;第二对方括号表示列索引的选择,传入要选择列索引的位置。行和列索引的位置都是从0开始计数

"布尔索引+普通索引"选择指定的行和列

布尔索引+普通索引是先对表进行布尔索引选择行然后通过普通索引选择列

# -*- coding:utf-8 -*-
import pandas as pd

df = pd.read_csv(r"~/Desktop/王宏伟测试.csv")
print(df)
"""
     姓名  年龄      性别
0   whw  12    male
1   www  19    male
2  wwwa  33  female
3   whh  23  female
"""

# 先进行布尔索引选择行 然后通过普通索引选择列
ret = df[df["年龄"]<20][["姓名","年龄","性别"]]
print(ret)
"""
    姓名  年龄    性别
0  whw  12  male
1  www  19  male
"""

"切片索引+切片索引"选择指定的行和列

切片索引+切片索引是通过同时传入行、列索引的位置区间进行数据选择。

# -*- coding:utf-8 -*-
import pandas as pd

df = pd.read_csv(r"~/Desktop/王宏伟测试.csv")
print(df)
"""
     姓名  年龄      性别
0   whw  12    male
1   www  19    male
2  wwwa  33  female
3   whh  23  female
"""

# 左闭右开区间
ret = df.iloc[0:2,0:2]
print(ret)
"""
    姓名  年龄
0  whw  12
1  www  19
"""

"切片索引+普通索引"选择指定的行和列(ix方法已移除!)

前面我们说过,如果是普通索引,就直接传入行或列名,用loc方法即可;如果是切片索引,也就是传入行或列的位置区间,要用 iloc 方法。如果是切片索引+普通索引,也就是行(列)用切片索引,列(行)用普通索引,这种交叉索引要用ix方法

# -*- coding:utf-8 -*-
import pandas as pd

df = pd.read_csv(r"~/Desktop/王宏伟测试.csv")
print(df)
"""
     姓名  年龄      性别
0   whw  12    male
1   www  19    male
2  wwwa  33  female
3   whh  23  female
"""

# 注意下面的代码会报错!!!
ret = df.ix[0:2,["姓名","性别"]]
print(ret)
"""
AttributeError: 'DataFrame' object has no attribute 'ix'
"""

注意:在pandas的1.0.0版本开始,移除了Series.ix and DataFrame.ix 方法!!!

7--15章 都是pandas/matplotlib/numpy的操作

7--15章内容与我之前做的笔记重复了,详情请看之前这篇笔记:

《Python数据科学实践指南》笔记

posted on 2020-08-16 10:30  江湖乄夜雨  阅读(1051)  评论(0编辑  收藏  举报