一、了解数据分析以及环境安装
1、流程
2、anaconda
【官网下载】
基本上一路next即可,需要修改的地方自己注意
如果没有配置环境变量的话:
经典操作:右键此电脑 -> 属性 -> 高级系统设置 -> 环境变量
先添加一个变量,内容是安装的目录
然后向path变量中添加
测试是否成功,执行结果出现版本号即为成功
3、jupyter
Jupyter是一个交互式的开发环境,是基于Web的代码笔记本
交互性、探索性的高效环境
每一步骤都能看到结果,很方便的查看之前的结果
安装:
打开:(可以在自己想要的工作目录下输入,只存放相关的为文件,jupyter的根目录就是当前工作路径)
二、介绍与安装模块
以下使用的是清华镜像源
介绍
NumPy 是一个 Python 包。 它代表 “Numeric Python”。 它是一个由多维数组 对象和用于处理数组的例程集合组成的库。
使用NumPy,开发人员可以执行以下操作:
数组的算数和逻辑运算。
傅立叶变换和用于图形操作的例程。
与线性代数有关的操作。 NumPy 拥有线性代数和随机数生成的内置函数。
为什么使用NumPy?
对于同样的数值计算任务,使用Numpy比直接Python代码实现,优点:
代码更简洁: Numpy直接以数组、矩阵为粒度计算并且支撑大量的数学函数,而python需要用for循环从底层实现;
性能更高效: Numpy的数组存储效率和输入输出计算性能,比Python使用List或者嵌套List好很多;
注: Numpy的数据存储和Python原生的List是不一样的
注: Numpy的大部分代码都是C语言实现的,这是Numpy比纯Python代码高效的原因
Numpy是Python各种数据科学类库的基础库
比如: Scipy,Scikit-Learn、TensorFlow,pandas等
安装
1 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple numpy
pandas
是对表格数据模型在python上的模拟,它有简单的像SQL
对数据的处理,能够方便的在python上实现。
安装
1 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pandas
介绍
Matplotlib 是一个用于在 Python 中绘制数组的 2D 图形库。虽然它起源于模仿 MATLAB 图形命令,但它独立于 MATLAB,可以以 Pythonic 和面向对象的方式使用。虽然 Matplotlib 主要是在纯 Python 中编写的,但它大量使用 NumPy 和其他扩展代码,即使对于大型数组也能提供良好的性能。
安装
1 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple matplotlib
三、numpy
1、Ndarray 对象
NumPy 中定义的最重要的对象 是称为 ndarray
的 N 维数组类型。 它描述相同类型的元素集合 。 可以使用基于零的索引访问集合中的项目。
ndarray
中的每个元素在内存中使用相同大小的块。 ndarray
中的每个元素是数据类型对象的对象(称为 dtype
)。
从ndarray
对象提取的任何元素(通过切片)由一个数组标量类型的 Python 对象表示。 下图显示了ndarray
,数据类型对象(dtype
)和数组标量类型之间的关系。
创建:
1 numpy.array(object , dtype = None , copy = True , order = None , subok = False , ndmin = 0 )
构造器参数:
参数
描述
object
任何暴露数组接口方法的对象都会返回一个数组或任何(嵌套)序列。
dtype
数组的所需数据类型,可选。(默认自动识别)
copy
可选,默认为true
,对象是否被复制。
order
C
(按行)、F
(按列)或 A
(任意,默认)。
subok
默认情况下,返回的数组被强制为基类数组。 如果为true
,则返回子类。
ndmin
指定返回数组的最小维数。
案例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import numpy as np array1 = np.array([[1 , 2 , 3 ], [2 , 3 , 4 ]])print ('array1:' )print (array1) array2 = np.array([1 , 2 , 3 , 4 , 5 ], ndmin=2 )print ('array2:' )print (array2) array3 = np.array([1 , 2 , 3 , 4 , 5 ], ndmin=3 )print ('array3:' )print (array3) array4 = np.array([1 , 2 , 3 ], dtype=complex )print ('array4:' )print (array4) array5 = np.array([1 , 2 , '3' ])print ('array5:' )print (array5) array6 = np.array(array1)print ('copy的结果:' )print (id (array1), id (array6)) mat = np.mat([1 , 2 , 3 ]) array7 = np.array(mat, subok=False ) array8 = np.array(mat, subok=True )print ('subok:' )print ('为False:' , type (array7))print ('为True:' , type (array8))
输出为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 array1: [[1 2 3] [2 3 4]] array2: [[1 2 3 4 5]] array3: [[[1 2 3 4 5]]] array4: [1.+0.j 2.+0.j 3.+0.j] array5: ['1' '2' '3'] copy的结果: 2963333225808 2963506355824 subok: 为True: <class 'numpy.ndarray'> 为False: <class 'numpy.matrix'>
2、NumPy - 数据类型
序号
数据类型
描述
1
bool
存储为一个字节的布尔值(真或假)
2
int
默认整数,相当于 C 的long
,通常为int32
或int64
3
intc
相当于 C 的int
,通常为int32
或int64
4
intp
用于索引的整数,相当于 C 的size_t
,通常为int32
或int64
5
int8
字节(-128 ~ 127)
6
int16
16 位整数(-32768 ~ 32767)
7
int32
32 位整数(-2147483648 ~ 2147483647)
8
int64
64 位整数(-9223372036854775808 ~ 9223372036854775807)
9
uint8
8 位无符号整数(0 ~ 255)
10
uint16
16 位无符号整数(0 ~ 65535)
11
uint32
32 位无符号整数(0 ~ 4294967295)
12
uint64
64 位无符号整数(0 ~ 18446744073709551615)
13
float
float64
的简写
14
float16
半精度浮点:符号位,5 位指数,10 位尾数
15
float32
单精度浮点:符号位,8 位指数,23 位尾数
16
float64
双精度浮点:符号位,11 位指数,52 位尾数
17
complex
complex128
的简写
18
complex64
复数,由两个 32 位浮点表示(实部和虚部)
19
complex128
复数,由两个 64 位浮点表示(实部和虚部)
20
str
字符串类型
21
string
字符串类型,也就是byte类型
NumPy 数字类型是dtype
(数据类型)对象的实例,每个对象具有唯一的特征。 这些类型可以是np.bool
,np.float32
等。
简写
字符
对应类型
字符
对应类型
字符
对应类型
字符
对应类型
b
布尔值
i
带符号整形
u
无符号整形
f
浮点型
c
复数浮点型
m
时间间隔(timedelta)
M
日期时间(datatime)
O
Python对象
S, a
字符串
U
Unicode
V
原始数据类型
还可以将两个字符作为参数传给数据类型的构造函数。此时,第一个字符表示数据类型,第二个字符表示该类型在内存中占用的字节数(f2、f4、f8分别表示16、32、64位浮点数)数据类型长度如何选择
数据类型对象 (dtype)
数据类型对象描述了对应于数组的固定内存块的解释,取决于以下方面:
数据类型(整数、浮点或者 Python 对象)
数据大小
字节序(小端或大端)
在结构化类型的情况下,字段的名称,每个字段的数据类型,和每个字段占用的内存块部分。
如果数据类型是子序列,它的形状和数据类型。
字节顺序取决于数据类型的前缀<
或>
。 <
意味着编码是小端(最小有效字节存储在最小地址中)。 >
意味着编码是大端(最大有效字节存储在最小地址中)。
dtype
可由一下语法构造 :
1 numpy.dtype(object , align, copy)
参数为:
Object
:被转换为数据类型的对象。
Align
:如果为true
,则向字段添加间隔,使其类似 C 的结构体。
Copy
: 生成dtype
对象的新副本,如果为flase
,结果是内建数据类型对象的引用。
案例1
1 2 3 4 5 6 7 8 9 10 import numpy as np dt1 = np.dtype(np.int32)print (dt1, type (dt1)) dt2 = np.dtype('i4' )print (dt2, type (dt2)) dt3 = np.dtype('>i4' )print (dt3, type (dt3))
输出如下:
1 2 3 int32 <class 'numpy.dtype[int32]'> int32 <class 'numpy.dtype[int32]'> >i4 <class 'numpy.dtype[int32]'>
案例2
以下示例定义名为 student 的结构化 数据类型,其中包含字符串字段name
,整数字段 age
和浮点字段 marks
。 此dtype
应用于ndarray
对象。
1 2 3 4 5 6 7 import numpy as np student = np.dtype([('name' , 'S20' ), ('age' , 'i1' ), ('marks' , 'f4' )])print (student) array = np.array([tuple (['abc' , 21 , 50 ]),('xyz' , 18 , 75 )], dtype=student)print (array)
输出为:
1 2 [('name', 'S20'), ('age', 'i1'), ('marks', '<f4')] [(b'abc', 21, 50.) (b'xyz', 18, 75.)]
案例
1 2 3 4 5 6 import numpy as np array1 = np.array(range (10 ), dtype='i' )print (array1) array2 = np.array(range (10 ), dtype='f' )print (array2)
3、NumPy - 数组属性
这一数组属性返回一个包含数组维度的元组,它也可以用于调整数组大小。
案例
1 2 3 4 5 6 7 8 9 10 import numpy as np array = np.array([[1 ,2 ,3 ],[4 ,5 ,6 ]])print (array.shape, id (array))print (array) array.shape = (3 , 2 )print (array.shape, id (array))print (array)
输出为:
1 2 3 4 5 6 7 (2, 3) 2083924122672 [[1 2 3] [4 5 6]] (3, 2) 2083924122672 [[1 2] [3 4] [5 6]]
NumPy 也提供了reshape()
函数来调整数组大小。
案例1
1 2 3 4 5 import numpy as np a = np.array([[1 ,2 ,3 ],[4 ,5 ,6 ]]) b = a.reshape(3 ,2 ) print (b)
输出如下:
1 2 3 [[1, 2] [3, 4] [5, 6]]
案例2
1 2 3 4 5 6 7 import numpy as np a = np.arange(24 ) b = a.reshape(2 ,4 ,3 ) print (b)
输出如下:
1 2 3 4 5 6 7 8 9 [[[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] [[12 13 14] [15 16 17] [18 19 20] [21 22 23]]]
ndarray.ndim
这一数组属性返回数组的维数。
numpy.itemsize
这一数组属性返回数组中每个元素的字节单位长度。
1 2 3 4 import numpy as np array = np.array([[1 ,2 ,3 ], [4 ,5 ,6 ]], dtype='i4' )print (array.ndim, array.itemsize)
1 2 3 4 import numpy as np array = np.array([[1 , 2 , 3 ], [2 , 3 , 4 ]])print (array.size)
1 2 3 4 5 6 import numpy as np arrayA = np.array([[1 , 2 , 3 ], [2 , 3 , 4 ]])print (arrayA.dtype) arrayB = arrayA.astype('float' )print (arrayA.dtype, arrayB.dtype)
4、NumPy - 创建数组
新的ndarray
对象可以通过任何下列数组创建例程或使用低级ndarray
构造函数构造。
它创建指定形状和dtype
的未初始化数组。 它使用以下构造函数:
1 numpy.empty(shape, dtype = float , order = 'C' )
构造器接受下列参数:
序号
参数及描述
1
shape
空数组的形状,整数或整数元组
2
dtype
所需的输出数组类型,可选
3
order
'C'
为按行的 C 风格数组,'F'
为按列的 Fortran 风格数组
案例
下面的代码展示空数组的例子:
1 2 3 4 5 import numpy as np array1 = np.empty((3 ,2 ), dtype=int )print (array1)
输出为
1 2 3 [[22649312 1701344351] [1818321759 1885959276] [16779776 156368896]]
注意 :数组元素为随机值,因为它们未初始化 。
numpy.zeros()
/ numpy.ones()
返回特定大小,以 0 / 1 填充的新数组。
1 numpy.zeros(shape, dtype = float , order = 'C' )
构造器接受下列参数:
序号
参数及描述
1
Shape
空数组的形状,整数或整数元组
2
Dtype
所需的输出数组类型,可选
3
Order
'C'
为按行的 C 风格数组,'F'
为按列的 Fortran 风格数组
案例
1 2 3 4 5 6 7 8 9 import numpy as np array1 = np.zeros(5 ) print (array1) array2 = np.zeros((2 , 2 ))print (array2) dt = np.dtype([('name' , 'S20' ), ('age' , 'i4' )]) array3 = np.zeros((2 ,2 ), dtype=dt)print (array3)
输出为
1 2 3 4 5 [0. 0. 0. 0. 0.] [[0. 0.] [0. 0.]] [[(b'', 0) (b'', 0)] [(b'', 0) (b'', 0)]]
5、NumPy - 来自现有数据的数组
这一章中,我们会讨论如何从现有数据创建数组。
此函数类似于numpy.array
,除了它有较少的参数。 这个例程对于将 Python 序列转换为ndarray
非常有用。
1 numpy.asarray(a, dtype=None , order=None )
构造器接受下列参数:
序号
参数及描述
1
a
任意形式的输入参数,比如列表、列表的元组、元组、元组的元组、元组的列表
2
dtype
通常,输入数据的类型会应用到返回的ndarray
3
order
'C'
为按行的 C 风格数组,'F'
为按列的 Fortran 风格数组
下面的例子展示了如何使用asarray
函数:
案例
1 2 3 4 5 6 7 8 9 import numpy as np lst1 = [1 , 2 , 3 ] array1 = np.asarray(lst1)print (array1) lst2 = [(1 , 2 , 3 ), (4 , 5 , 6 )] array2 = np.asarray(lst2)print (array2)
输出为
1 2 3 [1 2 3] [[1 2 3] [4 5 6]]
此函数将缓冲区解释为一维数组。 暴露缓冲区接口的任何对象都用作参数来返回ndarray
。
1 numpy.frombuffer(buffer, dtype = float , count = -1 , offset = 0 )
构造器接受下列参数:
序号
参数及描述
1
buffer
任何暴露缓冲区借口的对象
2
dtype
返回数组的数据类型,默认为float
3
count
需要读取的数据数量,默认为-1
,读取所有数据
4
offset
需要读取的起始位置,默认为0
案例
下面的例子展示了frombuffer
函数的用法。
1 2 3 4 5 import numpy as np lst = b'helloworld' array = np.frombuffer(lst, dtype='S1' )print (array)
输出如下:
1 [b'h' b'e' b'l' b'l' b'o' b'w' b'o' b'r' b'l' b'd']
此函数从任何可迭代对象构建一个ndarray
对象,返回一个新的一维数组。
1 numpy.fromiter(iterable, dtype, count = -1 )
构造器接受下列参数:
序号
参数及描述
1.
iterable
任何可迭代对象
2.
dtype
返回数组的数据类型
3.
count
需要读取的数据数量,默认为-1
,读取所有数据
以下示例展示了如何使用内置的range()
函数返回列表对象。 此列表的迭代器用于形成ndarray
对象。
案例
1 2 3 4 5 6 7 8 9 import numpy as np lst = range (5 ) it = iter (lst) x = np.fromiter(it, dtype=float )print (x)
6、NumPy - 来自数值范围的数组
这一章中,我们会学到如何从数值范围创建数组。
这个函数返回ndarray
对象,包含给定范围内的等间隔值。
1 numpy.arange(start, stop, step, dtype)
构造器接受下列参数:
序号
参数及描述
1
start
范围的起始值,默认为0
2
stop
范围的终止值(不包含)
3
step
两个值的间隔,默认为1
4
dtype
返回ndarray
的数据类型,如果没有提供,则会使用输入数据的类型。
下面的例子展示了如何使用该函数:
案例
1 2 3 4 5 6 7 import numpy as np array1 = np.arange(5 )print (array1) array2 = np.arange(5 , dtype=float )print (array2)
此函数类似于arange()
函数。 在此函数中,指定了范围之间的均匀间隔数量,而不是步长。 此函数的用法如下。
1 numpy.linspace(start, stop, num, endpoint, retstep, dtype)
构造器接受下列参数:
序号
参数及描述
1
start
序列的起始值
2
stop
序列的终止值,如果endpoint
为true
,该值包含于序列中
3
num
要生成的等间隔样例数量,默认为50
4
endpoint
序列中是否包含stop
值,默认为ture
5
retstep
如果为true
,返回样例,以及连续数字之间的步长
6
dtype
输出ndarray
的数据类型
下面的例子展示了linspace()
函数的用法。
案例
1 2 3 4 5 6 7 8 9 import numpy as np array1 = np.linspace(10 , 20 , 5 )print (array1) array2 = np.linspace(10 , 20 , 5 , endpoint=False )print (array2) array3 = np.linspace(10 , 20 , 5 , endpoint=False , retstep=True )print (array3)
此函数返回一个ndarray
对象,其中包含在对数刻度上均匀分布的数字。 刻度的开始和结束端点是某个底数的幂,通常为 10。
1 numpy.logscale(start, stop, num, endpoint, base, dtype)
logspace
函数的输出由以下参数决定:
序号
参数及描述
1
start
起始值是base ** start
(base:底数)
2
stop
终止值是base ** stop
3
num
范围内的数值数量,默认为50
4
endpoint
如果为true
,终止值包含在输出数组当中
5
base
对数空间的底数,默认为10
6
dtype
输出数组的数据类型,如果没有提供,则取决于其它参数
下面的例子展示了logspace
函数的用法。
案例
1 2 3 4 5 6 7 8 import numpy as np array1 = np.logspace(1.0 , 2.0 , num=10 )print (array1) array2 = np.logspace(1 , 10 , num=10 , base=2 )print (array2)
输出为:
1 2 3 [ 10. 12.91549665 16.68100537 21.5443469 27.82559402 35.93813664 46.41588834 59.94842503 77.42636827 100. ] [ 2. 4. 8. 16. 32. 64. 128. 256. 512. 1024.]
7、NumPy - 切片和索引
ndarray
对象的内容可以通过索引或切片来访问和修改,就像 Python 的内置容器对象一样。
如前所述,ndarray
对象中的元素遵循基于零的索引。 有三种可用的索引方法类型: 字段访问,基本切片 和高级索引 。
基本切片是 Python 中基本切片概念到 n 维的扩展。 通过将start
,stop
和step
参数提供给内置的slice()
函数来构造一个 Python slice()
对象。 此slice
对象被传递给数组来提取数组的一部分。
案例
1 2 3 4 5 import numpy as np array = np.arange(10 ) s = slice (2 ,7 ,2 )print (array[s])
在上面的例子中,ndarray
对象由arange()
函数创建。 然后,分别用起始,终止和步长值2
,7
和2
定义切片对象。 当这个切片对象传递给ndarray
时,会对它的一部分进行切片,从索引2
到7
,步长为2
。
通过将由冒号分隔的切片参数(start:stop:step
)直接提供给ndarray
对象,也可以获得相同的结果。
案例
1 2 3 4 5 import numpy as np array = np.arange(10 ) b = array[2 :7 :2 ] print (b)
如果只输入一个参数,则将返回与索引对应的单个项目。 如果使用a:
,则从该索引向后的所有项目将被提取。 如果使用两个参数(以:
分隔),则对两个索引(不包括停止索引)之间的元素以默认步骤进行切片。
案例1
1 2 3 4 5 6 7 8 import numpy as np array = np.arange(10 )print (array[5 ]) print (array[2 :]) print (array[2 :5 ])
上面的描述也可用于多维ndarray
。
案例2
1 2 3 4 5 6 7 8 9 10 import numpy as np array = np.array([[1 ,2 ,3 ],[3 ,4 ,5 ],[4 ,5 ,6 ]])print (array)print ('现在我们从索引 a[1:] 开始对数组切片' )print (array[1 :])print ('二次索引取得' )print (array[1 ])print (array[1 ][2 ])
输出如下:
1 2 3 4 5 6 7 8 9 [[1 2 3] [3 4 5] [4 5 6]] 现在我们从索引 a[1:] 开始对数组切片 [[3 4 5] [4 5 6]] 二次索引取得 [3 4 5] 5
切片还可以包括省略号(...
),来使选择元组的长度与数组的维度相同。 如果在行位置使用省略号,它将返回包含行中元素的ndarray
。
案例3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import numpy as np array = np.array([[1 ,2 ,3 ],[3 ,4 ,5 ],[4 ,5 ,6 ]])print ('我们的数组是:' )print (array)print ('第二列的元素是:' )print (array[...,1 ])print ('第二行的元素是:' )print (array[1 ,...])print ('第二列及其剩余元素是:' )print (array[...,1 :])
输出如下:
1 2 3 4 5 6 7 8 9 10 11 12 我们的数组是: [[1 2 3] [3 4 5] [4 5 6]] 第二列的元素是: [2 4 5] 第二行的元素是: [3 4 5] 第二列及其剩余元素是: [[2 3] [4 5] [5 6]]
获取值的索引
1 2 3 import numpy as np array = np.array([1 ,0 ,1 ,3 ,1 ,0 ])print (np.where(array == 0 ))
8、NumPy - 高级索引
如果一个ndarray
是非元组序列,数据类型为整数或布尔值的ndarray
,或者至少一个元素为序列对象的元组,我们就能够用它来索引ndarray
。高级索引始终返回数据的副本。 与此相反,切片只提供了一个视图。
有两种类型的高级索引:整数和布尔值。
8.1、整数索引
这种机制有助于基于 N 维索引来获取数组中任意元素。 每个整数数组表示该维度的下标值。 当索引的元素个数就是目标ndarray
的维度时,会变得相当直接。
以下示例获取了ndarray
对象中每一行指定列的一个元素。 因此,行索引包含所有行号,列索引指定要选择的元素。
案例1
1 2 3 4 5 6 7 import numpy as np array = np.array([[1 , 2 ], [3 , 4 ], [5 , 6 ]])print ('原数组' )print (array) res = array[[0 , 1 , 2 ], [0 , 1 , 0 ]] print (res)
输出为
1 2 3 4 5 原数组 [[1 2] [3 4] [5 6]] [1 4 5]
下面的示例获取了 4X3 数组中的每个角处的元素。 行索引是[0,0]
和[3,3]
,而列索引是[0,2]
和[0,2]
。
案例2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import numpy as np array = np.array([[0 , 1 , 2 ], [3 , 4 , 5 ], [6 , 7 , 8 ], [9 , 10 , 11 ]])print ('我们的数组是:' )print (array) rows1 = np.array([[0 ,0 ],[3 ,3 ]]) cols1 = np.array([[0 ,2 ],[0 ,2 ]]) res1 = array[rows1, cols1] print ('这个数组的每个角处的元素是:' )print (res1) cols2 = np.array([0 ,2 ,0 ,2 ]) rows2 = np.array([0 ,0 ,3 ,3 ]) res2 = array[rows2, cols2] print ('这个数组的每个角处的元素是:' )print (res2)
输出如下:
1 2 3 4 5 6 7 8 9 10 我们的数组是: [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] 这个数组的每个角处的元素是: [[ 0 2] [ 9 11]] 这个数组的每个角处的元素是: [ 0 2 9 11]
返回的结果是包含每个角元素的ndarray
对象。
高级和基本索引可以通过使用切片:
或省略号...
与索引数组组合。 以下示例使用slice
作为列索引和高级索引。 当切片用于两者时,结果是相同的。 但高级索引会导致复制,并且可能有不同的内存布局。
案例3
1 2 3 4 5 6 7 8 9 10 11 12 13 import numpy as np array = np.array([[0 , 1 , 2 ], [3 , 4 , 5 ], [6 , 7 , 8 ], [9 , 10 , 11 ]])print ('我们的数组是:' )print (array) res1 = array[1 :4 , 1 :3 ] print ('切片之后,我们的数组变为:' )print (res1) res2 = array[1 :4 , [1 , 2 ]] print ('对列使用高级索引来切片:' )print (res2)
输出如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 我们的数组是: [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] 切片之后,我们的数组变为: [[ 4 5] [ 7 8] [10 11]] 对列使用高级索引来切片: [[ 4 5] [ 7 8] [10 11]]
8.2、布尔索引
当结果对象是布尔运算(例如比较运算符)的结果时,将使用此类型的高级索引。
提取出为True的元素
案例1
这个例子中,大于 5 的元素会作为布尔索引的结果返回。
1 2 3 4 5 6 7 8 import numpy as np array = np.array([[0 , 1 , 2 ], [3 , 4 , 5 ], [6 , 7 , 8 ], [9 , 10 , 11 ]]) print ('我们的数组是:' ) print (array) print ('大于 5 的元素是:' ) print (array[array > 5 ])
输出如下:
1 2 3 4 5 6 7 我们的数组是: [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] 大于 5 的元素是: [ 6 7 8 9 10 11]
案例2
这个例子使用了 ~
(取补运算符)来过滤NaN
。
1 2 3 4 import numpy as np array = np.array([np.nan, 1 , 2 , np.nan, 3 , 4 , 5 ])print (array[~np.isnan(array)])
案例3
以下示例显示如何从数组中过滤掉非复数元素。
1 2 3 4 import numpy as np array = np.array([1 , 2 + 6j , 5 , 3.5 + 5j ])print (array[np.iscomplex(array)])
案例4
9、NumPy - 广播
术语广播 是指 NumPy 在算术运算期间处理不同形状的数组的能力。 对数组的算术运算通常在相应的元素上进行。 如果两个阵列具有完全相同的形状,则这些操作被无缝执行。
案例1
1 2 3 4 5 6 import numpy as np arrayA = np.array([1 , 2 , 3 , 4 ]) arrayB = np.array([10 , 20 , 30 , 40 ]) arrayC = arrayA * arrayBprint (arrayC)
如果两个数组的维数不相同,则元素到元素的操作是不可能的。 然而,在 NumPy 中仍然可以对形状不相似的数组进行操作 ,因为它拥有广播功能。 较小的数组会广播 到较大数组的大小,以便使它们的形状可兼容。
如果满足以下规则,可以进行广播 :
ndim
较小的数组会在前面追加一个长度为 1 的维度。
输出数组的每个维度的大小是输入数组该维度大小的最大值。
如果输入在每个维度中的大小与输出大小匹配,或其值正好为 1,则在计算中可它。
如果输入的某个维度大小为 1,则该维度中的第一个数据元素将用于该维度的所有计算。
如果上述规则产生有效结果,并且满足以下条件之一,那么数组被称为可广播的 。
数组拥有相同形状。
数组拥有相同的维数,每个维度拥有相同长度,或者长度为 1。
数组拥有极少的维度,可以在其前面追加长度为 1 的维度,使上述条件成立。
对于广播规则另一种简单理解
将两个数组的维度大小右对齐,然后比较对应维度上的数值
如果数值相等或其中有一个为1或者为空,则能进行广播运算
输出的维度大小为取数值大的数值。否则不能进行数组运算
案例2
1 2 3 4 5 6 7 8 9 10 import numpy as np arrayA = np.array([[0.0 , 0.0 , 0.0 ], [10.0 , 10.0 , 10.0 ], [20.0 , 20.0 , 20.0 ], [30.0 , 30.0 , 30.0 ]]) arrayB = np.array([1.0 , 2.0 , 3.0 ])print ('第一个数组:' )print (arrayA)print ('第二个数组:' )print (arrayB)print ('第一个数组加第二个数组:' )print (arrayA + arrayB)
输出为
1 2 3 4 5 6 7 8 9 10 11 12 第一个数组: [[ 0. 0. 0.] [10. 10. 10.] [20. 20. 20.] [30. 30. 30.]] 第二个数组: [1. 2. 3.] 第一个数组加第二个数组: [[ 1. 2. 3.] [11. 12. 13.] [21. 22. 23.] [31. 32. 33.]]
案例2如何通过广播来兼容
10、NumPy - 数组上的迭代
NumPy 包包含一个迭代器对象numpy.nditer
。 它是一个有效的多维迭代器对象,可以用于在数组上进行迭代。 数组的每个元素可使用 Python 的标准Iterator
接口来访问。
案例1
让我们使用arange()
函数创建一个 3X4 数组,并使用nditer
对它进行迭代。
1 2 3 4 5 6 7 8 9 import numpy as np a = np.arange(0 ,60 ,5 ) a.shape = (3 ,4 )print ('原始数组是:' )print (a)print ('迭代结果为' )for x in np.nditer(a): print (x, end=' ' )
输出为
1 2 3 4 5 6 原始数组是: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] 迭代结果为 0 5 10 15 20 25 30 35 40 45 50 55
案例2
迭代的顺序匹配数组的内容布局,而不考虑特定的排序。 这可以通过迭代上述数组的转置来看到。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import numpy as np array = np.arange(0 , 60 , 5 ) array.shape = (3 , 4 )print ('原始数组是:' )print (array)print ('原数组迭代:' )for x in np.nditer(array): print (x, end=' ' ) t = array.Tprint ('\n转置后:' )print (t)print ('转置后的数组是:' )for x in np.nditer(t): print (x, end=' ' )
输出为
1 2 3 4 5 6 7 8 9 10 11 12 13 原始数组是: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] 原数组迭代: 0 5 10 15 20 25 30 35 40 45 50 55 转置后: [[ 0 20 40] [ 5 25 45] [10 30 50] [15 35 55]] 转置后的数组是: 0 5 10 15 20 25 30 35 40 45 50 55
10.1、迭代顺序
如果相同元素使用 F 风格顺序存储,则迭代器选择以更有效的方式对数组进行迭代。
案例1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import numpy as np array = np.arange(0 , 60 , 5 ) array.shape = (3 , 4 )print ('原始数组是:' )print (array)print ('以 C 风格顺序排序:' ) c = array.copy(order='C' )print (c)print ('迭代(C):' )for x in np.nditer(c): print (x, end=' ' ),print ('\n以 F 风格顺序排序:' ) f = array.copy(order='F' )print (f)print ('迭代(F):' )for x in np.nditer(f): print (x, end=' ' )
输出为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 原始数组是: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] 以 C 风格顺序排序: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] 迭代(C): 0 5 10 15 20 25 30 35 40 45 50 55 以 F 风格顺序排序: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] 迭代(F): 0 20 40 5 25 45 10 30 50 15 35 55
案例2
可以通过显式提醒,来强制nditer
对象使用某种顺序:
1 2 3 4 5 6 7 8 9 10 11 12 import numpy as np array = np.arange(0 , 60 , 5 ) array.shape = (3 , 4 )print ('原始数组是:' )print (array)print ('以 C 风格顺序排序:' )for x in np.nditer(array, order='C' ): print (x, end=' ' )print ('\n以 F 风格顺序排序:' )for x in np.nditer(array, order='F' ): print (x, end=' ' )
输出为
1 2 3 4 5 6 7 8 原始数组是: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] 以 C 风格顺序排序: 0 5 10 15 20 25 30 35 40 45 50 55 以 F 风格顺序排序: 0 20 40 5 25 45 10 30 50 15 35 55
10.2、修改数组的值
nditer
对象有另一个可选参数op_flags
。 其默认值为只读,但可以设置为读写或只写模式。 这将允许使用此迭代器修改数组元素。
案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import numpy as np array = np.arange(0 , 60 , 5 ) array.shape = (3 , 4 )print ('原始数组是:' )print (array) array[0 , 0 ] = 2 print ('修改左上角为2:' )print (array[0 , 0 ])print ('迭代器修改:' )for i in np.nditer(array, op_flags=['readwrite' ]): i[...] = 2 * iprint (array)
输出为
1 2 3 4 5 6 7 8 9 10 原始数组是: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] 修改左上角为2: 2 迭代器修改: [[ 4 10 20 30] [ 40 50 60 70] [ 80 90 100 110]]
测试 上面的案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import numpy as np array = np.arange(2 ) array.shape = (2 , 1 )print ('原数组为:' )print (array)print ('数组地址元素地址为:' )print ('第1个元素:' )print (id (array[0 , 0 ]))print (id (array[0 , 0 ][...]))print ('第2个元素:' )print (id (array[1 , 0 ]))print (id (array[1 , 0 ][...]))print ('迭代器结果:' )for i in np.nditer(array, op_flags=['readwrite' ]): print (f'第{i} 个元素:' ) print (id (i)) print (id (i[...]))
结果为:
10.3、外部循环
nditer
类的构造器拥有flags
参数,它可以接受下列值:
序号
参数及描述
1
c_index
可以跟踪 C 顺序的索引
2
f_index
可以跟踪 Fortran 顺序的索引
3
multi-index
每次迭代可以跟踪一种索引类型
4
external_loop
给出的值是具有多个值的一维数组,而不是零维数组
案例
在下面的示例中,迭代器遍历对应于每列的一维数组。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import numpy as np array = np.arange(0 , 60 , 5 ) array.shape = (3 , 4 )print ('原始数组是:' )print (array)print ('c_index:' )for x in np.nditer(array, flags=['c_index' ], order='F' ): print (x, end=' ' )print ('\nf_index:' )for x in np.nditer(array, flags=['f_index' ], order='F' ): print (x, end=' ' )print ('\nmulti_index:' )for x in np.nditer(array, flags=['multi_index' ], order='F' ): print (x, end=' ' )print ('\nexternal_loop \'F\':' )for x in np.nditer(array, flags=['external_loop' ], order='F' ): print (x, end=' ' )print ('\nexternal_loop \'C\':' )for x in np.nditer(array, flags=['external_loop' ], order='C' ): print (x, end=' ' )
输出为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 原始数组是: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] c_index: 0 20 40 5 25 45 10 30 50 15 35 55 f_index: 0 20 40 5 25 45 10 30 50 15 35 55 multi_index: 0 20 40 5 25 45 10 30 50 15 35 55 external_loop 'F': [ 0 20 40] [ 5 25 45] [10 30 50] [15 35 55] external_loop 'C': [ 0 5 10 15 20 25 30 35 40 45 50 55]
10.4、广播迭代
如果两个数组是可广播的 ,nditer
组合对象能够同时迭代它们。 假设数组a
具有维度 3X4,并且存在维度为 1X4 的另一个数组b
,则使用以下类型的迭代器(数组b
被广播到a
的大小)。
案例
1 2 3 4 5 6 7 8 9 10 11 12 import numpy as np array1 = np.arange(0 , 60 , 5 ) array1 = array1.reshape(3 , 4 )print ('第一个数组:' )print (array1)print ('第二个数组:' ) array2 = np.array([1 , 2 , 3 , 4 ], dtype=int )print (array2)print ('迭代结果:' )for x, y in np.nditer([array1, array2]): print (f'{x} :{y} ' , end=' ' )
输出为
1 2 3 4 5 6 7 8 第一个数组: [[ 0 5 10 15] [20 25 30 35] [40 45 50 55]] 第二个数组: [1 2 3 4] 迭代结果: 0:1 5:2 10:3 15:4 20:1 25:2 30:3 35:4 40:1 45:2 50:3 55:4
11、NumPy - 数组操作
NumPy包中有几个例程用于处理ndarray
对象中的元素。 它们可以分为以下类型:
11.0、NumPy的轴
11.1、修改形状
序号
形状及描述
1
reshape
不改变数据的条件下修改形状
2
flat
数组上的一维迭代器
3
flatten
返回折叠为一维的数组副本
4
ravel
返回连续的展开数组
这个函数在不改变数据的条件下修改形状,它接受如下参数:
1 numpy.reshape(arr, newshape, order)
其中:
arr
:要修改形状的数组
newshape
:整数或者整数数组,新的形状应当兼容原有形状;(-1, 2),-1表示行自动变化,2表示两列
order
:'C'
为 C 风格顺序,'F'
为 F 风格顺序,'A'
为保留原顺序。
案例
1 2 3 4 5 6 7 8 9 import numpy as np arrayA = np.arange(8 )print ('原始数组:' )print (arrayA) arrayB = np.reshape(arrayA, (2 , 4 ))print ('修改后的数组:' )print (arrayB)
输出为
1 2 3 4 5 原始数组: [0 1 2 3 4 5 6 7] 修改后的数组: [[0 1 2 3] [4 5 6 7]]
该函数返回数组上的一维迭代器,行为类似 Python 内建的迭代器。
案例
1 2 3 4 5 6 7 8 9 10 11 12 import numpy as np array = np.arange(8 ).reshape(2 , 4 )print ('原始数组:' )print (array)print ('调用 flat 函数之后:' )print (array.flat)print (array.flat[5 ])print ('for-in 迭代:' )for i in array.flat: print (i, end=' ' )
输出为
1 2 3 4 5 6 7 8 原始数组: [[0 1 2 3] [4 5 6 7]] 调用 flat 函数之后: <numpy.flatiter object at 0x000002E0449B2390> 5 for-in 迭代: 0 1 2 3 4 5 6 7
该函数返回折叠为一维的数组副本,函数接受下列参数:
其中:
order
:'C'
– 按行,'F'
– 按列,'A'
– 原顺序,'k'
– 元素在内存中的出现顺序。
案例
1 2 3 4 5 6 7 8 9 10 import numpy as np array = np.arange(8 ).reshape(2 , 4 )print ('原数组:' )print (array)print ('展开的数组:' )print (array.flatten())print ('以 F 风格顺序展开的数组:' )print (array.flatten(order='F' ))
输出为
1 2 3 4 5 6 7 原数组: [[0 1 2 3] [4 5 6 7]] 展开的数组: [0 1 2 3 4 5 6 7] 以 F 风格顺序展开的数组: [0 4 1 5 2 6 3 7]
这个函数返回展开的一维数组,并且按需生成副本。返回的数组和输入数组拥有相同数据类型。这个函数接受两个参数。
构造器接受下列参数:
order
:'C'
– 按行,'F'
– 按列,'A'
– 原顺序,'k'
– 元素在内存中的出现顺序。
案例
1 2 3 4 5 6 7 8 9 10 11 import numpy as np array = np.arange(8 ).reshape(2 , 4 )print ('原数组:' )print (array)print ('调用 ravel 函数之后:' )print (np.ravel(array))print ('以 F 风格顺序调用 ravel 函数之后:' )print (np.ravel(array, order='F' ))
输出为
1 2 3 4 5 6 7 原数组: [[0 1 2 3] [4 5 6 7]] 调用 ravel 函数之后: [0 1 2 3 4 5 6 7] 以 F 风格顺序调用 ravel 函数之后: [0 4 1 5 2 6 3 7]
11.2、翻转操作
序号
操作及描述
1
transpose
翻转数组的维度
2
ndarray.T
和self.transpose()
相同
3
rollaxis
向后滚动指定的轴
4
swapaxes
互换数组的两个轴
这个函数翻转给定数组的维度。如果可能的话它会返回一个视图。函数接受下列参数:
1 numpy.transpose(arr, axes)
其中:
arr
:要转置的数组
axes
:整数的列表,对应维度,通常所有维度都会翻转。
案例
1 2 3 4 5 6 7 8 9 import numpy as np array = np.arange(6 ).reshape(2 , 3 )print ('原数组:' )print (array)print ('转置数组:' )print (np.transpose(array))
输出为
1 2 3 4 5 6 7 原数组: [[0 1 2] [3 4 5]] 转置数组: [[0 3] [1 4] [2 5]]
该函数属于ndarray
类,行为类似于numpy.transpose
。
案例
该函数向后滚动特定的轴,直到一个特定位置。这个函数接受三个参数:
1 numpy.rollaxis(arr, axis, start)
其中:
arr
:输入数组
axis
:要向后滚动的轴,其它轴的相对位置不会改变
start
:默认为零,表示完整的滚动。会滚动到特定位置。
案例
1 2 3 4 5 6 7 8 9 10 11 12 import numpy as np array = np.arange(8 ).reshape(2 , 2 , 2 )print ('原数组:' )print (array)print ('调用 rollaxis 函数:' )print (np.rollaxis(array, 2 ))print ('调用 rollaxis 函数:' )print (np.rollaxis(array, 2 , 1 ))
输出为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 原数组: [[[0 1] [2 3]] [[4 5] [6 7]]] 调用 rollaxis 函数: [[[0 2] [4 6]] [[1 3] [5 7]]] 调用 rollaxis 函数: [[[0 2] [1 3]] [[4 6] [5 7]]]
该函数交换数组的两个轴。对于 1.10 之前的 NumPy 版本,会返回交换后数组的试图。这个函数接受下列参数:
1 numpy.swapaxes(arr, axis1, axis2)
arr
:要交换其轴的输入数组
axis1
:对应第一个轴的整数
axis2
:对应第二个轴的整数
案例
1 2 3 4 5 6 7 8 import numpy as np array = np.arange(8 ).reshape(2 , 2 , 2 )print ('原数组:' )print (array)print ('调用 swapaxes 函数后的数组:' )print (np.swapaxes(array, 2 , 0 ))
输出为
1 2 3 4 5 6 7 8 9 10 11 12 原数组: [[[0 1] [2 3]] [[4 5] [6 7]]] 调用 swapaxes 函数后的数组: [[[0 4] [2 6]] [[1 5] [3 7]]]
11.3、修改维度
序号
维度和描述
1
broadcast()
产生模仿广播的对象
2
broadcast_to()
将数组广播到新形状
3
expand_dims()
扩展数组的形状
4
squeeze()
从数组的形状中删除单维条目
如前所述,NumPy 已经内置了对广播的支持。 此功能模仿广播机制。 它返回一个对象,该对象封装了将一个数组广播到另一个数组的结果。
该函数使用两个数组作为输入参数。 下面的例子说明了它的用法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import numpy as np x = np.array([[1 ], [2 ], [3 ]]) y = np.array([4 , 5 , 6 ]) arrayA = np.broadcast(x, y)print ('对 y 广播 x:' ) r, arrayB = arrayA.itersprint (next (r), next (arrayB))print (next (r), next (arrayB))print ('广播对象的形状:' )print (arrayA.shape) arrayA = np.broadcast(x, y) arrayB = np.empty(arrayA.shape)print ('手动使用 broadcast 将 x 与 y 相加:' )print (arrayB.shape) arrayB.flat = [u + v for (u, v) in arrayA]print ('调用 flat 函数:' )print (arrayB)print ('x 与 y 的和:' )print (x + y)
输出为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 对 y 广播 x: 1 4 1 5 广播对象的形状: (3, 3) 手动使用 broadcast 将 x 与 y 相加: (3, 3) 调用 flat 函数: [[5. 6. 7.] [6. 7. 8.] [7. 8. 9.]] x 与 y 的和: [[5 6 7] [6 7 8] [7 8 9]]
此函数将数组广播到新形状。 它在原始数组上返回只读视图。 它通常不连续。 如果新形状不符合 NumPy 的广播规则,该函数可能会抛出ValueError
。
注意 - 此功能可用于 1.10.0 及以后的版本。
该函数接受以下参数。
1 numpy.broadcast_to(array, shape, subok)
案例
1 2 3 4 5 6 7 import numpy as np array = np.arange(4 ).reshape(1 , 4 )print ('原数组:' )print (array)print ('调用 broadcast_to 函数之后:' )print (np.broadcast_to(array, (4 , 4 )))
输出为
1 2 3 4 5 6 7 原数组: [[0 1 2 3]] 调用 broadcast_to 函数之后: [[0 1 2 3] [0 1 2 3] [0 1 2 3] [0 1 2 3]]
函数通过在指定位置插入新的轴来扩展数组形状。该函数需要两个参数:
1 numpy.expand_dims(arr, axis)
其中:
arr
:输入数组
axis
:新轴插入的位置
案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import numpy as np arrayX = np.array(([1 , 2 ], [3 , 4 ]))print ('数组X:' )print (arrayX) arrayY = np.expand_dims(arrayX, axis=0 )print ('数组Y:' )print (arrayY)print ('数组 x 和 y 的形状:' , arrayX.shape, arrayY.shape) arrayY = np.expand_dims(arrayX, axis=1 )print ('在位置 1 插入轴之后的数组 y:' )print (arrayY)print ('x.ndim 和 y.ndim:' , arrayX.ndim, arrayY.ndim)print ('x.shape 和 y.shape:' , arrayX.shape, arrayY.shape)
输出为
1 2 3 4 5 6 7 8 9 10 11 12 13 数组X: [[1 2] [3 4]] 数组Y: [[[1 2] [3 4]]] 数组 x 和 y 的形状: (2, 2) (1, 2, 2) 在位置 1 插入轴之后的数组 y: [[[1 2]] [[3 4]]] x.ndim 和 y.ndim: 2 3 x.shape 和 y.shape: (2, 2) (2, 1, 2)
函数从给定数组的形状中删除一维条目。 此函数需要两个参数。
1 numpy.squeeze(arr, axis)
其中:
arr
:输入数组
axis
:整数或整数元组,用于选择形状中单一维度条目的子集
案例
1 2 3 4 5 6 7 8 9 import numpy as np arrayX = np.arange(9 ).reshape(1 , 3 , 3 )print ('数组 X:' )print (arrayX) arrayY = np.squeeze(arrayX)print ('数组 Y:' )print (arrayY)print ('数组 x 和 y 的形状:' , arrayX.shape, arrayY.shape)
输出为
1 2 3 4 5 6 7 8 9 数组 X: [[[0 1 2] [3 4 5] [6 7 8]]] 数组 Y: [[0 1 2] [3 4 5] [6 7 8]] 数组 x 和 y 的形状: (1, 3, 3) (3, 3)
11.4、数组的连接
序号
数组及描述
1
concatenate()
沿着现存的轴连接数据序列
2
stack()
沿着新轴连接数组序列
3
hstack()
水平堆叠序列中的数组(列方向)
4
vstack()
竖直堆叠序列中的数组(行方向)
数组的连接是指连接。 此函数用于沿指定轴连接相同形状的两个或多个数组。 该函数接受以下参数。
1 numpy.concatenate((a1, a2, ...), axis)
其中:
a1, a2, ...
:相同类型 的数组序列
axis
:沿着它连接数组的轴,默认为 0
案例
1 2 3 4 5 6 7 8 9 10 11 12 13 import numpy as np array1 = np.array([[1 , 2 ], [3 , 4 ]])print ('第一个数组:' )print (array1) array2 = np.array([[5 , 6 ], [7 , 8 ]])print ('第二个数组:' )print (array2)print ('沿轴 0 连接两个数组:' )print (np.concatenate((array1, array2)))print ('沿轴 1 连接两个数组:' )print (np.concatenate((array1, array2), axis=1 ))
输出为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 第一个数组: [[1 2] [3 4]] 第二个数组: [[5 6] [7 8]] 沿轴 0 连接两个数组: [[1 2] [3 4] [5 6] [7 8]] 沿轴 1 连接两个数组: [[1 2 5 6] [3 4 7 8]]
此函数沿新轴连接数组序列。 此功能添加自 NumPy 版本 1.10.0。 需要提供以下参数。
1 numpy.stack(arrays, axis)
其中:
arrays
:相同形状 的数组序列
axis
:返回数组中的轴,输入数组沿着它来堆叠
案例
1 2 3 4 5 6 7 8 9 10 11 12 import numpy as np array1 = np.array([[1 , 2 ], [3 , 4 ], [5 , 6 ]])print ('第一个数组:' )print (array1) array2 = np.array([[5 , 6 ], [7 , 8 ], [0 , 0 ]])print ('第二个数组:' )print (array2)print ('沿轴 0 堆叠两个数组:' )print (np.stack((array1, array2), 0 ))print ('沿轴 1 堆叠两个数组:' )print (np.stack((array1, array2), 1 ))
输出为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 第一个数组: [[1 2] [3 4] [5 6]] 第二个数组: [[5 6] [7 8] [0 0]] 沿轴 0 堆叠两个数组: [[[1 2] [3 4] [5 6]] [[5 6] [7 8] [0 0]]] 沿轴 1 堆叠两个数组: [[[1 2] [5 6]] [[3 4] [7 8]] [[5 6] [0 0]]]
numpy.stack()
函数的变体,通过堆叠来生成水平的单个数组。
案例
1 2 3 4 5 6 7 8 9 10 11 import numpy as np array1 = np.array([[1 , 2 ], [3 , 4 ], [5 , 6 ]])print ('第一个数组:' )print (array1) array2 = np.array([[5 , 6 ], [7 , 8 ], [0 , 0 ]])print ('第二个数组:' )print (array2)print ('水平堆叠:' ) array3 = np.hstack((array1, array2))print (array3)
输出为
1 2 3 4 5 6 7 8 9 10 11 12 第一个数组: [[1 2] [3 4] [5 6]] 第二个数组: [[5 6] [7 8] [0 0]] 水平堆叠: [[1 2 5 6] [3 4 7 8] [5 6 0 0]]
numpy.stack
函数的变体,通过堆叠来生成竖直的单个数组。
案例
1 2 3 4 5 6 7 8 9 10 11 import numpy as np array1 = np.array([[1 , 2 ], [3 , 4 ], [5 , 6 ]])print ('第一个数组:' )print (array1) array2 = np.array([[5 , 6 ], [7 , 8 ], [0 , 0 ]])print ('第二个数组:' )print (array2)print ('竖直堆叠:' ) array3 = np.vstack((array1, array2))print (array3)
输出为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 第一个数组: [[1 2] [3 4] [5 6]] 第二个数组: [[5 6] [7 8] [0 0]] 竖直堆叠: [[1 2] [3 4] [5 6] [5 6] [7 8] [0 0]]
11.5、数组分割
序号
数组及操作
1
split()
将一个数组分割为多个子数组
2
hsplit()
将一个数组水平分割为多个子数组(按列)
3
vsplit()
将一个数组竖直分割为多个子数组(按行)
该函数沿特定的轴将数组分割为子数组。函数接受三个参数:
1 numpy.split(ary, indices_or_sections, axis)
其中:
ary
:被分割的输入数组
indices_or_sections
:可以是整数,表明要从输入数组创建的,等大小的子数组的数量。 如果此参数是一维数组,则其元素表明要创建新子数组的点。
axis
:默认为 0
案例
1 2 3 4 5 6 7 8 9 10 11 import numpy as np array1 = np.arange(9 )print ('第一个数组:' )print (array1)print ('将数组分为三个大小相等的子数组:' ) array2 = np.split(array1, 3 )print (array2)print ('将数组在一维数组中表明的位置分割:' ) array3 = np.split(array1, [5 , 7 ])print (array3)
输出为
1 2 3 4 5 6 第一个数组: [0 1 2 3 4 5 6 7 8] 将数组分为三个大小相等的子数组: [array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])] 将数组在一维数组中表明的位置分割: [array([0, 1, 2, 3, 4]), array([5, 6]), array([7, 8])]
numpy.hsplit
是split()
函数的特例,其中轴为 1 表示水平分割,无论输入数组的维度是什么。
案例
1 2 3 4 5 6 7 8 import numpy as np array1 = np.arange(16 ).reshape(4 , 4 )print ('第一个数组:' )print (array1)print ('水平分割:' ) array2 = np.hsplit(array1, 2 )print (array2)
输出为
1 2 3 4 5 6 7 8 9 10 11 12 13 第一个数组: [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11] [12 13 14 15]] 水平分割: [array([[ 0, 1], [ 4, 5], [ 8, 9], [12, 13]]), array([[ 2, 3], [ 6, 7], [10, 11], [14, 15]])]
numpy.vsplit
是split()
函数的特例,其中轴为 0 表示竖直分割,无论输入数组的维度是什么。下面的例子使之更清楚。
案例
1 2 3 4 5 6 7 8 import numpy as np array1 = np.arange(16 ).reshape(4 , 4 )print ('第一个数组:' )print (array1)print ('竖直分割:' ) array2 = np.vsplit(array1, 2 )print (array2)
输出为
1 2 3 4 5 6 7 8 9 第一个数组: [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11] [12 13 14 15]] 竖直分割: [array([[0, 1, 2, 3], [4, 5, 6, 7]]), array([[ 8, 9, 10, 11], [12, 13, 14, 15]])]
11.6、添加/删除元素
序号
元素及描述
1
resize()
返回指定形状的新数组
2
append()
将值添加到数组末尾
3
insert()
沿指定轴将值插入到指定下标之前
4
delete()
返回删掉某个轴的子数组的新数组
5
unique()
寻找数组内的唯一元素
此函数返回指定大小的新数组。 如果新大小大于原始大小,则包含原始数组中的元素的重复副本 。 该函数接受以下参数。
1 numpy.resize(arr, shape)
其中:
arr
:要修改大小的输入数组
shape
:返回数组的新形状
例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import numpy as np array1 = np.array([[1 , 2 , 3 ], [4 , 5 , 6 ]])print ('第一个数组:' )print (array1)print ('第一个数组的形状:' )print (array1.shape) array2 = np.resize(array1, (3 , 2 ))print ('第二个数组:' )print (array2)print ('第二个数组的形状:' )print (array2.shape)print ('修改第二个数组的大小:' ) array2 = np.resize(array1, (3 , 3 ))print (array2)
输出为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 第一个数组: [[1 2 3] [4 5 6]] 第一个数组的形状: (2, 3) 第二个数组: [[1 2] [3 4] [5 6]] 第二个数组的形状: (3, 2) 修改第二个数组的大小: [[1 2 3] [4 5 6] [1 2 3]]
此函数在输入数组的末尾添加值。 附加操作不是原地的,而是分配新的数组。 此外,输入数组的维度必须匹配否则将生成ValueError
。
函数接受下列函数:
1 numpy.append(arr, values, axis)
其中:
arr
:输入数组
values
:要向arr
添加的值,比如和arr
形状相同(除了要添加的轴)
axis
:沿着它完成操作的轴。如果没有提供,两个参数都会被展开。
案例
1 2 3 4 5 6 7 8 9 10 11 import numpy as np array = np.array([[1 , 2 , 3 ], [4 , 5 , 6 ]])print ('第一个数组:' )print (array)print ('向数组添加元素:' )print (np.append(array, [7 , 8 , 9 ]))print ('沿轴 0 添加元素:' )print (np.append(array, [[7 , 8 , 9 ]], axis=0 ))print ('沿轴 1 添加元素:' )print (np.append(array, [[5 , 5 , 5 ], [7 , 8 , 9 ]], axis=1 ))
输出为
1 2 3 4 5 6 7 8 9 10 11 12 第一个数组: [[1 2 3] [4 5 6]] 向数组添加元素: [1 2 3 4 5 6 7 8 9] 沿轴 0 添加元素: [[1 2 3] [4 5 6] [7 8 9]] 沿轴 1 添加元素: [[1 2 3 5 5 5] [4 5 6 7 8 9]]
此函数在给定索引之前,沿给定轴在输入数组中插入值。 如果值的类型转换为要插入,则它与输入数组不同。 插入没有原地的,函数会返回一个新数组。 此外,如果未提供轴,则输入数组会被展开。
insert()
函数接受以下参数:
1 numpy.insert(arr, obj, values, axis)
其中:
arr
:输入数组
obj
:在其之前插入值的索引
values
:要插入的值
axis
:沿着它插入的轴,如果未提供,则输入数组会被展开
案例
1 2 3 4 5 6 7 8 9 10 11 12 import numpy as np array = np.array([[1 , 2 ], [3 , 4 ], [5 , 6 ]])print ('第一个数组:' )print (array)print ('未传递 Axis 参数。 在插入之前输入数组会被展开。' )print (np.insert(array, 3 , [11 , 12 ]))print ('传递了 Axis 参数。 会广播值数组来配输入数组。' )print ('沿轴 0 广播:' )print (np.insert(array, 1 , [11 ], axis=0 ))print ('沿轴 1 广播:' )print (np.insert(array, 1 , 11 , axis=1 ))
输出为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 第一个数组: [[1 2] [3 4] [5 6]] 未传递 Axis 参数。 在插入之前输入数组会被展开。 [ 1 2 3 11 12 4 5 6] 传递了 Axis 参数。 会广播值数组来配输入数组。 沿轴 0 广播: [[ 1 2] [11 11] [ 3 4] [ 5 6]] 沿轴 1 广播: [[ 1 11 2] [ 3 11 4] [ 5 11 6]]
此函数返回从输入数组中删除指定子数组的新数组。 与insert()
函数的情况一样,如果未提供轴参数,则输入数组将展开。 该函数接受以下参数:
1 Numpy.delete(arr, obj, axis)
其中:
arr
:输入数组
obj
:可以被切片,整数或者整数数组,表明要从输入数组删除的子数组
axis
:沿着它删除给定子数组的轴,如果未提供,则输入数组会被展开
案例
1 2 3 4 5 6 7 8 9 10 11 12 import numpy as np array = np.arange(12 ).reshape(3 , 4 )print ('第一个数组:' )print (array)print ('未传递 Axis 参数。 在插入之前输入数组会被展开。' )print (np.delete(array, 5 ))print ('删除第二列:' )print (np.delete(array, 1 , axis=1 ))print ('包含从数组中删除的替代值的切片:' ) array = np.array([1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ])print (np.delete(array, np.s_[::2 ]))
输出为
1 2 3 4 5 6 7 8 9 10 11 12 第一个数组: [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] 未传递 Axis 参数。 在插入之前输入数组会被展开。 [ 0 1 2 3 4 6 7 8 9 10 11] 删除第二列: [[ 0 2 3] [ 4 6 7] [ 8 10 11]] 包含从数组中删除的替代值的切片: [ 2 4 6 8 10]
此函数返回输入数组中的去重元素数组。 该函数能够返回一个元组 ,包含去重数组和相关索引的数组。 索引的性质取决于函数调用中返回参数的类型。
1 numpy.unique(arr, return_index, return_inverse, return_counts)
其中:
arr
:输入数组,如果不是一维数组则会展开
return_index
:如果为true
,返回输入数组中的元素下标
return_inverse
:如果为true
,返回去重数组的下标,它可以用于重构输入数组
return_counts
:如果为true
,返回去重数组中的元素在原数组中的出现次数
案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import numpy as np array = np.array([5 , 2 , 6 , 2 , 7 , 5 , 6 , 8 , 2 , 9 ])print ('第一个数组:' )print (array)print ('第一个数组的去重值:' ) u = np.unique(array)print (u)print ('去重数组的索引数组:' ) u, indices = np.unique(array, return_index=True )print (indices)print ('我们可以看到每个和原数组下标对应的数值:' )print (array)print ('去重数组的下标:' ) u, indices = np.unique(array, return_inverse=True )print (u)print ('下标为:' )print (indices)print ('使用下标重构原数组:' )print (u[indices])print ('返回去重元素的重复数量:' ) u, indices = np.unique(array, return_counts=True )print (u)print (indices)
输出为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 第一个数组: [5 2 6 2 7 5 6 8 2 9] 第一个数组的去重值: [2 5 6 7 8 9] 去重数组的索引数组: [1 0 2 4 7 9] 我们可以看到每个和原数组下标对应的数值: [5 2 6 2 7 5 6 8 2 9] 去重数组的下标: [2 5 6 7 8 9] 下标为: [1 0 2 0 3 1 2 4 0 5] 使用下标重构原数组: [5 2 6 2 7 5 6 8 2 9] 返回去重元素的重复数量: [2 5 6 7 8 9] [3 2 2 1 1 1]
11.7、排序
numpy.sort()
对输入数组执行排序,并返回一个数组副本。
参数
说明
a
要排序的数组
axis
沿着指定轴进行排序,如果没有指定 axis,默认在最后一个轴上排序,若 axis=0 表示按列排序,axis=1 表示按行排序
kind
默认为 quicksort (快速排序)
order
若数组设置了字段,则 order 表示要排序的字段
1 numpy.sort(a, axis, kind, order)
案例
1 2 3 4 5 6 7 import numpy as np dt = np.dtype([('name' , 'S10' ), ('age' , 'i4' )]) array = np.array([('ggw' , 999 ), ('xpl' , 998 )], dtype=dt)print (array) print (np.sort(array, order='age' ))
1 2 3 4 5 6 7 8 9 import numpy as np array = np.array([90 , 29 , 89 , 12 ])print (array) sortIndex = np.argsort(array)print (sortIndex) print (array[sortIndex])
11.8、矩阵乘、点乘
案例 :点乘、矩阵乘
1 2 3 4 5 6 7 8 9 array1 = np.arange(1 , 5 ).reshape(2 , 2 ) array2 = np.arange(1 , 5 ).reshape(2 , 2 )print ('原数组' )print (array1)print (array2)print ('*' )print (array1 * array2)print ('numpy.dot()' )print (array1.dot(array2))
输出为
1 2 3 4 5 6 7 8 9 10 11 原数组 [[1 2] [3 4]] [[1 2] [3 4]] * [[ 1 4] [ 9 16]] numpy.dot() [[ 7 10] [15 22]]
12、NumPy - 统计
12.1、平均值和中位数
案例
1 2 3 4 5 import numpy as np array = np.arange(20 ).reshape(4 , 5 )print (array.mean()) print (np.median(array))
12.2、标准差和方差
ndarray.std()
标准差
ndarray.var()
方差
案例
1 2 3 4 5 6 7 8 9 10 import numpy as npimport math array = np.arange(20 ).reshape(4 , 5 )print (array.std()) print (math.sqrt(np.sum ((array - array.mean()) ** 2 ) / array.size))print (array.var())
12.3、最大值、最小值、和
ndarray.max()
最大值
参数: axis
,值0、1,分别是轴0、轴1的方向
ndarray.min()
最小值
参数: axis
,值0、1,分别是轴0、轴1的方向
ndarray.sum()
和
参数: axis
,值0、1,分别是轴0、轴1的方向
案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import numpy as np array = np.arange(20 ).reshape(4 , 5 )print ('原数组:' )print (array)print ('----------------------' )print (array.max ())print (array.max (axis=0 ))print (array.max (axis=1 ))print ('----------------------' )print (array.min ())print (array.min (axis=0 ))print (array.min (axis=1 ))print ('----------------------' )print (array.sum ())print (array.sum (axis=0 ))print (array.sum (axis=1 ))
输出为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 原数组: [[ 0 1 2 3 4] [ 5 6 7 8 9] [10 11 12 13 14] [15 16 17 18 19]] ---------------------- 19 [15 16 17 18 19] [ 4 9 14 19] ---------------------- 0 [0 1 2 3 4] [ 0 5 10 15] ---------------------- 190 [30 34 38 42 46] [10 35 60 85]
12.4、加权平均值
1 numpy.average(a, axis=None , weights=None , returned=False )
案例
对比两位学生的考试成绩
姓名
平时测验
期中考试
期末考试
ggw
95
90
80
xpl
80
90
95
学校规定的学科综合成绩的计算方法:
平时测验
期中考试
期末考试
20%
30%
50%
1 2 3 4 5 6 import numpy as np array = np.array([[95 , 90 , 80 ], [80 , 90 , 95 ]]) w = [0.2 , 0.3 , 0.5 ]print (np.average(array, axis=1 , weights=w)) print (95 *0.2 + 90 *0.3 + 80 *0.5 )
12、NumPy - 文件操作
1 2 3 loadtxt(fname, dtype=<type 'float' >, comments='#' , delimiter=None , \ converters=None , skiprows=0 , usercols=None , unpack=False , \ ndmin=0 , encoding='bytes' )
参数
说明
fname
指定文件或者字符串。支持压缩文件,包括gz,bz格式。
dtype
数据类型,默认为float。
comments
字符串或字符串组成的列表。表示注释字符集开始的标志,默认为#。
delimiter
字符串。分隔符。
converters
字典。将特定列的数据转换为字典中对应的函数的浮点型数据。例如将空值转换为0,默认为空。
skiprows
跳过特定行数据。例如跳过前1行(可能是标题或注释)。默认为0。
usercols
元组。用来指定要读取数据的列,第一列为0。例如(1, 3, 5),默认为空。
unpack
布尔型。指定是否转置数组,如果为真则转置,默认为False。
ndmin
整数型。指定返回的数组至少包含特定维度的数组。值域为0、1、2,默认为0。
enconding
编码。确认文件是gbk还是utf-8格式。
返回值:从文件读出的数组
【具体使用说明】
1 np.savez(r'./data.npz' , data=data, x=x, y=y)
将numpy数组data、x、y存储到文件data.npz中,没有设置关键字参数而是直接传参,则变为’arr_0、arr_1、arr_2’
1 2 3 data = np.load(r'./data.npz') data, x, y = data['data'], data['x'], data['y'] # print(data.files) # 查看文件
将文件中的数组加载出来
13、随机函数
NumPy中也有自己的随机函数,包含在random模块中。它能产生特定分布的随机数,如正态分布等。接下来介绍一些常用的随
机数。
rand()
rand()函数根据给定维度生成[0,1)之间的数据,包含0,不包含1
dn表示每个维度
返回值为指定维度的array
1 numpy.random.rand(d0,d1,...,dn)
案例
1 2 3 4 import numpy as np array = np.random.rand(1 , 2 )print (array)
randn()
randn()函数返回一个或一组样本,具有标准正态分布
dn表示每个维度
返回值为指定维度的array
标准正态分布又称为u分布,是以0为均值、以1为标难差的正态分布,记为N (0,1)
1 numpy.random.randn(d0,d1,...,dn)
randint()
返回随机整数,范围区间[low, high)
,包括low,不包括high
参数:low
为最小值,high
为最大值,size
为数组维数大小,dtype
为数据类型,默认是int
high没有填写时,默认生成的是[0, low)
范围
1 numpy.random.randint(low, high=None , size=None , dtype='i' )
案例
1 2 3 4 import numpy as np array = np.random.randint(-5 , 6 , size=(1 ,3 ))print (array)
sample()
返回半开区间的随机浮点数[0.0, 1.0]
1 numpy.random.sample(size=None )
案例
1 2 3 4 import numpy as np array = np.random.sample((1 , 2 ))print (array)
seed()
使用相同的seed()值,则每次生成的随机数都相同,使得随机数可以预测
但是,只在调用的时候seed()一下并不能使生成的随机数相同,需要每次调用都seed()一下,表示种子相同,从而生成的随机数
相同
案例
1 2 3 4 5 6 7 8 import numpy as np np.random.seed(1 ) array1 = np.random.sample((1 , 2 ))print (array1) np.random.seed(1 ) array2 = np.random.sample((1 , 2 ))print (array2)
1 numpy.random.normal(loc=0.0 , scale=1.0 , size=None )
案例
1 2 3 4 import numpy as np array = np.random.normal(0.0 , 1.0 , size=(1 , 2 ))print (array)
四、matplotlib
Matplotlib 是Python中类似 MATLAB 的绘图工具,熟悉 MATLAB 也可以很快的上手 Matplotlib。
优点:
Matplotlib 提供了一个套面向绘图对象编程的API 接口
依托于Python,借助Python的强大的可拓展性Matplotlib可以在许多不同的环境中被使用
基于Matlab的和基于面向对象的,但是它完全免费(Matlab是商业数学软件)
Matplotlib 实现了几乎是完全自主控制的图形定义功能
1、第一个绘图程序
1 2 3 4 5 6 7 import numpy as npimport matplotlib.pyplot as plt x = np.arange(-50 , 51 ) y = x ** 2 plt.plot(x, y) plt.show()
2、基本方法
2.1、title()
设置图标名称
1 2 3 4 5 6 7 8 9 10 import numpy as npimport matplotlib.pyplot as plt x = np.arange(-50 , 51 ) y = x ** 2 plt.plot(x, y) plt.title('y=x^2' ) plt.show()
修改字体配置(2个问题)
(1)默认不支持中文(字体丢失),报错为:missing from current font.
1 2 3 4 5 6 7 8 9 10 import numpy as npimport matplotlib.pyplot as plt x = np.arange(-50 , 51 ) y = x ** 2 plt.plot(x, y) plt.title('y等于x的平方' ) plt.show()
解决办法:
1 2 plt.rcParams['font.sans-serif' ] = ['SimHei' ]
字体说明
中文字体
说明
SimHei
中文黑体
Kaiti
中文楷体
LiSu
中文隶书
FangSong
中文仿宋
YouYuan
中文幼圆
STSong
华文宋体
(2)当字体设置支持中文后,必须设置负号,否则数值中出现负值时,符号无法显示
解决办法:
1 plt.rcParams['axes.unicode_minus' ] = False
正常执行的代码
1 2 3 4 5 6 7 8 9 10 11 12 import numpy as npimport matplotlib.pyplot as plt x = np.arange(-50 , 51 ) y = x ** 2 plt.plot(x, y) plt.title('y等于x的平方' ) plt.rcParams['font.sans-serif' ] = ['SimHei' ] plt.rcParams['axes.unicode_minus' ] = False plt.show()
2.2、xlabel()、ylabel()
设置x轴、y轴的名称
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import numpy as npimport matplotlib.pyplot as plt x = np.arange(-50 , 51 ) y = x ** 2 plt.plot(x, y) plt.title('y等于x的平方' ) plt.rcParams['font.sans-serif' ] = ['SimHei' ] plt.rcParams['axes.unicode_minus' ] = False plt.xlabel('x 轴' ) plt.ylabel('y 轴' ) plt.show()
2.3、补充
(1)样式
参数
说明
fontsize
字体大小
linewidth
线条宽度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import numpy as npimport matplotlib.pyplot as plt x = np.arange(-50 , 51 ) y = x ** 2 plt.plot(x, y, linewidth=5 ) plt.title('y等于x的平方' , fontsize=16 ) plt.rcParams['font.sans-serif' ] = ['SimHei' ] plt.rcParams['axes.unicode_minus' ] = False plt.xlabel('x 轴' , fontsize=16 ) plt.ylabel('y 轴' , fontsize=16 ) plt.show()
(2)一张图多个曲线
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import numpy as npimport matplotlib.pyplot as plt x = np.arange(-50 , 51 ) y1 = x ** 2 y2 = 10 * x plt.title('y等于x的平方' , fontsize=16 ) plt.rcParams['font.sans-serif' ] = ['SimHei' ] plt.rcParams['axes.unicode_minus' ] = False plt.xlabel('x 轴' , fontsize=16 ) plt.ylabel('y 轴' , fontsize=16 ) plt.plot(x, y1, linewidth=5 ) plt.plot(x, y2, linewidth=5 ) plt.show()
2.4、xticks()、yticks()
设置x轴、y轴的刻度(把坐标轴变成自己想要的样子)
1 plt.xticks(ticks=None , label=None , **kwargs)
参数
说明
ticks
此参数是xtick位置 的列表。是一个可选参数。如果将一个空列表作为参数传递,则它将删除所有xticks
label
此参数包含放置在给定刻度线位置的标签。它是一个可选参数
**kwargs
此参数是文本属性,用于控制标签的外观 rotation :旋转角度;如: rotation=45 color: 颜色;如: color=“red”
如果ticks参数的值是数值型,那么代表的是他本身,而不是索引(位置)
案例
1 2 3 4 5 6 7 8 9 import numpy as npimport matplotlib.pyplot as plt date = [f'1月{i} 日' for i in range (1 , 21 )] salary = np.random.randint(500 , 900 , size=len (date)) plt.rcParams['font.sans-serif' ] = ['SimHei' ] plt.rcParams['axes.unicode_minus' ] = False plt.plot(date, salary) plt.show()
设置x轴刻度后
1 2 3 4 5 6 7 8 9 10 11 12 13 import numpy as npimport matplotlib.pyplot as plt date = [f'1月{i} 日' for i in range (1 , 21 )] salary = np.random.randint(500 , 900 , size=len (date)) plt.rcParams['font.sans-serif' ] = ['SimHei' ] plt.rcParams['axes.unicode_minus' ] = False plt.xticks(range (1 , len (date), 2 ), rotation=45 ) plt.plot(date, salary) plt.show()
2.5、show()
显示所有打开的图形
注意:jupyter notebooks会自动显示图形(即使没调用)
如果在jupyter中也想要出现图形操作菜单,可以使用matplotlib中的魔术方法
如果在jupyter中变回原来的模式
2.6、legend()
(1)使用图例前需要在,plot()函数中指定参数label的值
(2)需要先指定,在执行legend()函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import numpy as npimport matplotlib.pyplot as plt date = [f'1月{i} 日' for i in range (1 , 21 )] salary = np.random.randint(500 , 900 , size=len (date)) expenses = np.random.randint(100 , 500 , size=len (date)) plt.rcParams['font.sans-serif' ] = ['SimHei' ] plt.rcParams['axes.unicode_minus' ] = False plt.xticks(range (1 , len (date), 2 ), rotation=45 ) plt.plot(date, salary, label='收入' ) plt.plot(date, expenses, label='支出' ) plt.legend() plt.show()
设置图例
(1)默认会选择不遮挡图形的位置来显示图例(loc=best)(位置不定)
(2)指定图例位置
位置
字符串位置值
位置值
默认值,自定寻找合适位置
best
0
右上角
upper right
1
左上角
upper left
2
左下角
lower left
3
右下角
lower right
4
右边中间
right
5
左边中间
center left
6
右边中间
center right
7
中间最下面
lower center
8
中间最上面
upper center
9
正中心
center
10
2.7、text()
显示每条数据的值
1 plt.text(x, y, string, fontsize=15 , verticalalignment='top' , horizontalalignment='right' )
参数
说明
x, y
坐标轴上的值
string
说明文字
fontsize
字体大小
verticalalignment
垂直对齐方式(va),[‘center’ | ‘top’ | ‘bottom’ | ‘baseline’]
horizontalalignment
水平对齐方式(ha),[‘center’ | ‘right’ | ‘left’]
案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import numpy as npimport matplotlib.pyplot as plt date = [f'1月{i} 日' for i in range (1 , 21 )] salary = np.random.randint(500 , 900 , size=len (date)) expenses = np.random.randint(100 , 500 , size=len (date)) plt.rcParams['font.sans-serif' ] = ['SimHei' ] plt.rcParams['axes.unicode_minus' ] = False plt.xticks(range (1 , len (date), 2 ), rotation=45 ) plt.plot(date, salary, label='收入' ) plt.plot(date, expenses, label='支出' ) plt.legend(loc='upper right' )for x, y1, y2 in zip (date, salary, expenses): plt.text(x, y1, f'{y1} 元' , fontsize=8 , horizontalalignment='center' ) plt.text(x, y2, f'{y2} 元' , fontsize=8 , horizontalalignment='center' ) plt.show()
2.8、plot()线条样式
1 2 plt.plot(x, y, color='red' , alpha=0.3 , linestyle='-' , linewidth=5 ,\ marker='o' , markeredgecolor='r' , markersize='20' , markeredgewidth=10 )
参数说明
(1)x, y:plot(y),x可省略,默认[0,…,N-1]递增,N为y轴元素的个数
(2)color:可以使用颜色的十六进制,也可以使用线条的颜色英文,还可以使用之前的缩写
字符
颜色
英文全称
b
蓝色
blue
g
绿色
green
r
红色
red
c
青色
cyan
m
品红
magenta
y
黄色
yellow
k
黑色
black
w
白色
white
(3)alpha:0.0-1.0,透明度
(4)linestyle:线条样式
字符
描述
-
实线
–
虚线
-.
点划线
:
虚线
(5)linewidth:折线的宽度
(7)marker:标记点
标记符号
描述
.
点标记
o
圆圈标记
x
'X’标记
D
钻石标记
H
六角标记
s
正方形标记
+
加号标记
(7)markeredgecolor:标记点的颜色
(8)markersize:标记点的大小
(9)markeredgewidth:标记点的边宽
3、其他元素的可视性
3.1、grid()
操作网格
1 plt.grid(True , linestyle='——' , color='gray' , linewidth='0,5' , axis='x' )
参数
说明
True
显示网格
linestyle
线性
color
颜色
linewidth
宽度
axis
x, y, both:显示x、显示y、显示x和y的网格
案例
1 2 3 4 5 6 7 8 9 10 11 import numpy as npimport matplotlib.pyplot as plt x = np.linspace(-np.pi, np.pi, endpoint=True ) c, s = np.cos(x), np.sin(x) plt.plot(x, c) plt.plot(x, s) plt.grid() plt.show()
3.2、gca(),spines
首先观察画布上面的坐标轴
上图中,框选出的四条黑色边界框线在Matplotlib中被称为spines ,中文翻译为脊柱,可以理解为这些框线是坐标轴的”支柱“
所有的操作在plt.gca()
中完成(gca: get current axes(获取当前区域))
用法在下面的例子中得到说明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import numpy as npimport matplotlib.pyplot as plt x = np.arange(-50 , 51 ) y = x ** 2 plt.ylim(0 , 2500 ) ax = plt.gca() ax.spines['right' ].set_color('none' ) ax.spines['top' ].set_color('none' ) ax.spines['left' ].set_position(('data' , 0 )) plt.plot(x, y) plt.show()
4、创建图形对象
在 Matplotlib 中,面向对象编程的核心思想是创建图形对象(figure obiect)。通过图形对象来调用其它的方法和属性,这样有助于我们更好地处理多个画布。在这个过程中,pyplot 负责生成图形对象,并通过该对象来添加一个或多个axes 对象(即绘图区)
Matplotib 提供了 matplotlib,figure 图形类模块,它包含了创建图形对象的方法。通过调用 pyplot 模块中 figure() 函数来实例化figure对象。
创建图形对象
1 plt.figure(num=None , figsize=None , dpi=None , facecolor=None , edgecolor=None , frameon=True , **kwargs)
参数
描述
num
图像编号或名称,数字为编号 ,字符串为名称
figsize
指定figure的宽和高,单位为英寸;
dpi
指定绘图对象的分辨率,即每英寸多少个像素,缺省值为72
facecolor
背景颜色
edgecolor
边框颜色
frameon
是否显示边框
案例
1 2 3 4 5 6 import matplotlib.pyplot as plt fig = plt.figure('f1' , figsize=(4 , 2 ), dpi=100 , facecolor='pink' ) plt.show()
5、绘制多子图
fiqure是绘制对象(可理解为一个空白的画布),一个figure对象可以包含多个Axes子图,一个Axes是一个绘图区域,不加设置时,Axes为1,且每次绘图其实都是在figure上的Axes上绘图。
我们是在图形对象上面的Axes区域作画
1、add_axes()
添加区域
Matplotlib 定义了一个 axes 类(轴域类),该类的对象被称为 axes 对象(即轴域对象),它指定了一个有数值范围限制的绘图区域。在一个给定的画布 (figure) 中可以包含多个 axes 对象,但是同一个axes 对象只能在一个画布中使用。
2D绘图区域(axes)包含两个轴(axis)对象
语法:
该方法用来生成一个axes 轴域对象,对象的位置由参数rect决定
rect 是位置参数,接受一个由 4 个元素组成的浮点数列表,形如[left, botom, width, height],它表示添加到画布中的矩形区
域的左下角坐标(x,y),以及宽度和高度。
案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import matplotlib.pyplot as plt fig = plt.figure(facecolor='pink' ) ax1 = fig.add_axes([0.1 , 0.1 , 0.8 , 0.8 ]) plt.plot([1 , 2 , 3 , 4 , 6 ], [9 , 7 , 5 , 8 , 2 ]) ax2 = fig.add_axes([0.2 , 0.2 , 0.5 , 0.5 ]) plt.plot([1 , 2 , 3 , 4 , 6 ], [9 , 7 , 5 , 8 , 2 ]) ax1.plot([1 , 2 , 3 , 4 , 6 ], [2 , 3 , 5 , 8 , 9 ]) ax2.plot([1 , 2 , 3 , 4 , 6 ], [2 , 3 , 5 , 8 , 9 ]) plt.show()
ps:plt.plot()是在当前区域作画
2、subplot()
均等地划分画布
1 fig, ax = plt.subplot(nrows, ncols, index, *args, **kwargs)
返回值:区域画布,区域对象
参数
描述
nrows
行
ncols
列
indes
索引
**kwargs
title、xlabel、ylabel等
说明:
nrows 与 ncols 表示要划分几行几列的子区域 (nrows*nclos表示子图数量),index 的初始值为1,用来选定具体的某个子区域。
例如:subplot(233)表示在当前画布的右上角创建一个两行三列的绘图区域,同时,选择在第 3 个位置绘制子图。
案例1
1 2 3 4 5 6 7 8 9 10 11 12 13 import matplotlib.pyplot as plt fig = plt.figure(facecolor='pink' ) ax1 = plt.subplot(221 ) ax2 = plt.subplot(224 ) ax1.plot([1 , 2 , 3 , 4 , 6 ], [2 , 3 , 5 , 8 , 9 ]) ax2.plot([1 , 2 , 3 , 4 , 6 ], [2 , 3 , 5 , 8 , 9 ]) plt.show()
案例2
1 2 3 4 5 6 7 8 9 10 import matplotlib.pyplot as plt fig = plt.figure(facecolor='pink') # ----------------------------------------------------------------------------- ax1 = plt.subplot(121) ax2 = plt.subplot(224) # ----------------------------------------------------------------------------- ax1.plot([1, 2, 3, 4, 6], [2, 3, 5, 8, 9]) ax2.plot([1, 2, 3, 4, 6], [2, 3, 5, 8, 9]) plt.show()
6、柱状图
1、bar()
绘制柱状图
1 plt.bar(x, height, width:float =0.8 , bottom=None , *, align:str ='center' , data=None , **kwargs)
参数
描述
x
表示x坐标,数据类型为float类型,一般为np.arange()生成的固定步长列表
height
表示柱状图的高度,也就是y坐标值,数据类型为float类型,一般为一个列表,包含生成柱状图的所有y值
width
表示柱状图的宽度,取值在0-1之间,默认值为0.8
bottom
柱状图的起始位置,也就是y轴的起始坐标,默认值为None
align
柱状图的中心位置,“center”,"lege"边缘,默认值为’center’
color
柱状图颜色,默认为蓝色
alpha
透明度,取值在0~1之间,默认值为1
label
标签,设置后需要调用plt.legend()生成
edgecolor
边框颜色(ec)
linewidth
边框宽度,浮点数或类数组,默认为None (lw)
tick_label
柱子的刻度标签,字符串或字符串列表,默认值为None。
linestyle
线条样式(Is)
案例1
基本柱状图
1 2 3 4 5 6 7 import numpy as npimport matplotlib.pyplot as plt x = range (5 ) y = np.random.randint(2 , 8 , size=5 ) plt.bar(x, y, color='pink' ) plt.show()
案例2
测试参数
1 2 3 4 5 6 7 8 import numpy as npimport matplotlib.pyplot as plt x = range (5 ) y = np.random.randint(2 , 8 , size=5 ) plt.bar(x, y, color=['c' , 'pink' , 'y' ], bottom=[1 , 2 , 1 , 4 , 3 ], \ edgecolor='k' , linestyle='--' , linewidth=2 ) plt.show()
2、同位置多柱状图
案例
各个国家的奖牌数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 import numpy as npimport matplotlib.pyplot as plt countries = ['挪威' , '德国' , '中国' , '美国' , '瑞典' ] goldMedal = [16 , 12 , 9 , 8 , 8 ] silverMedal = [8 , 10 , 4 , 10 , 5 ] bronzeMedal = [13 , 5 , 2 , 7 , 5 ] x = np.arange(len (countries)) width = 0.2 goldX = x silverX = x + width bronzeX = x + 2 * width plt.xticks(x + width, labels=countries) plt.rcParams['font.sans-serif' ] = ['SimHei' ] plt.rcParams['axes.unicode_minus' ] = False for i in range (len (countries)): plt.text(goldX[i], goldMedal[i], goldMedal[i], va='bottom' , ha='center' ) plt.text(silverX[i], silverMedal[i], silverMedal[i], va='bottom' , ha='center' ) plt.text(bronzeX[i], bronzeMedal[i], bronzeMedal[i], va='bottom' , ha='center' ) plt.bar(goldX, goldMedal, width=width, color='gold' ) plt.bar(silverX, silverMedal, width=width, color='silver' ) plt.bar(bronzeX, bronzeMedal, width=width, color='saddlebrown' ) plt.show()
3、堆叠状图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import numpy as npimport matplotlib.pyplot as plt countries = ['挪威' , '德国' , '中国' , '美国' , '瑞典' ] goldMedal = [16 , 12 , 9 , 8 , 8 ] silverMedal = [8 , 10 , 4 , 10 , 5 ] bronzeMedal = [13 , 5 , 2 , 7 , 5 ] bronzeBottom = np.zeros(5 ) silverBottom = bronzeBottom + bronzeMedal goldBottom = silverBottom + silverMedal plt.rcParams['font.sans-serif' ] = ['SimHei' ] plt.rcParams['axes.unicode_minus' ] = False plt.bar(countries, goldMedal, bottom=goldBottom, color='gold' ) plt.bar(countries, silverMedal, bottom=silverBottom, color='silver' ) plt.bar(countries, bronzeMedal, bottom=bronzeBottom, color='saddlebrown' ) plt.show()
4、barh()
绘制水平柱状图,和bar()用法基本一致
区别 :width 和 height参数意义互换, bottom变成left
案例
将上面堆叠状图的案例简单修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import numpy as npimport matplotlib.pyplot as plt countries = ['挪威' , '德国' , '中国' , '美国' , '瑞典' ] goldMedal = [16 , 12 , 9 , 8 , 8 ] silverMedal = [8 , 10 , 4 , 10 , 5 ] bronzeMedal = [13 , 5 , 2 , 7 , 5 ] bronzeBottom = np.zeros(5 ) silverBottom = bronzeBottom + bronzeMedal goldBottom = silverBottom + silverMedal plt.rcParams['font.sans-serif' ] = ['SimHei' ] plt.rcParams['axes.unicode_minus' ] = False plt.barh(countries, goldMedal, height=0.5 , left=goldBottom, color='gold' ) plt.barh(countries, silverMedal, height=0.5 , left=silverBottom, color='silver' ) plt.barh(countries, bronzeMedal, height=0.5 , left=bronzeBottom, color='saddlebrown' ) plt.show()
7、直方图
柱状图
直方图
柱状图一般用于描述离散 型分类数据的对比
直方图一般用于描述连续 型数据的分布关系
每根柱子宽度固定,柱子之间会有间距
每根柱子宽度可以不一样,且一般没有间距
横轴变量可以任意排序
横轴变量有一定顺序规则
hist()
1 2 3 4 plt.hist(x, bins=None , range =None , density=None , weights=None , \ cumulative=False , bottom=None , histtype='bar' , align='mid' , \ orientation='vertical' , rwidth=None , log=False , color=None , \ label=None , stacked=False , normed=None , *, data=None , **kwargs)
参数
说明
x
【必选参数】作直方图所要用的数据,必须是一维数组;多维数组可以先进行扁平化再作图。
bins
直方图的柱数,即要分的组数,默认为10。
weights
与x形状相同的权重数组;将x中的每个元素乘以对应权重值再计数;如果normed或density取值为True,则会对权重进行归一化处理。这个参数可用于绘制已合并的数据的直方图。
density
布尔值,可选参数。如果”True”,返回元组的第一个元素将会将计数标准化以形成一个概率密度,也就是说,直方图下的正积(或积分)总和为1。这是通过将计数除以数的数量来实现的观察乘以箱子的宽度而不是除以总数数量的观察。如果叠加也是“真实”的,那么柱状图被规范化为1。(替代normed)
bottom
数组,标量值或None;每个柱子底部相对于y=0的位置。如果是标量值,则每个柱子相对于y=0向上/向下的偏移量相同。如果是数组,则根据数组元素取值移动对应的柱子;即直方图上下便宜距离。
histtype
{‘bar’, ‘barstacked’, ‘step’, ‘stepfilled’};'bar’是传统的条形直方图;'barstacked’是堆叠的条形直方图;'step’是未填充的条形直方图,只有外边框;‘stepfilled’是有填充的直方图;当histtvpe取值为’step’或’stepfilled’,rwidth设置失效,即不能指定柱子之间的间隔,默认连接在一起。
align
{‘left’, ‘mid’, ‘right’};‘left’:柱子的中心位于bins的左边缘;‘mid’:柱子位于bins左右边缘之间;‘right’:柱子的中心位于bins的右边缘。
color
具体颜色,数组(元素为颜色)或None。
label
字符串 (序列)或None;有多个数据集时,用label参数做标注区分。
normed
是否将得到的直方图向量归一化,即显示占比,默认为0,不归一化;不推荐使用,建议改用density参数。
edgecolor
直方图边框颜色。
alpha
透明度
返回值 :
n:数组或数组列表(直方图的值)
bins:数组(返回各个bin区间范围)
patches:列表或列表的列表(返回每个bins里面包含的数据,是一个list)
案例
1 2 3 4 5 6 import numpy as npimport matplotlib.pyplot as plt x = np.random.randint(140 , 180 , size=200 ) plt.hist(x, bins=10 , edgecolor='w' , color='pink' ) plt.show()
8、饼状图
饼状图用来显示一个数据系列,具体来说,饼状图显示一个数据系列中各项目的占项目总和的百分比。
Matplotlib 提供了一个 pie()函数,该函数可以生成数组中数据的饼状图。您可使用 x/sum(x) 来计算各个扇形区域占饼图总和的
百分比。
pie()
1 plt.pie(x, explode=None , labels=None , colors=None , autopct=None )
参数
描述
x
数组序列,数组元素对应扇形区域的数量大小。
labels
列表字符串序列,为每个扇形区域备注一个标签名字。
colors
为每个扇形区域设置颜色,默认按照颜色周期自动设置。
autopct
格式化字符串"fmt%pct”,使用百分比的格式设置每个扇形区的标签,并将其放置在扇形区内。
pctdistance
设置百分比标签与圆心的距离。
labeldistance
设置各扇形标签 (图例)与圆心的距离。
explode
指定饼图某些部分的突出显示,即呈现爆炸式。
shadow
是否添加饼图的阴影效果。
案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import matplotlib.pyplot as plt label = ['娱乐' , '育儿' , '饮食' , '房贷' , '交通' , '其他' ] x = [200 , 500 , 1200 , 7000 , 200 , 900 ] plt.rcParams['font.sans-serif' ] = ['SimHei' ] plt.rcParams['axes.unicode_minus' ] = False plt.title('饼图示例:8月份家庭支出' ) plt.pie(x, labels=label, autopct='%.2f%%' , colors=['pink' , 'y' , 'c' ]) plt.show()
9、散点图
散点图也叫XY 图,它将所有的数据以点的形式展现在直角坐标系上,以显示变量之间的相互影响程度,点的位置由变量的数值决定
通过观察散点图上数据点的分布情况,我们可以推断出变量间的相关性。如果变量之间不存在相互关系,那么在散点图上就会表现为随机分布的离散的点,如果存在某种相关性,那么大部分的数据点就会相对密集并以某种趋势星现。
scatter()
1 2 3 plt.scatter(x, y, s=None , c=None , marker=None , cmap=None , norm=None , \ vmin=None , vmax=None , alpha=None , linewidths=None , edgecolors=None , \ plotnonfinite=None , data=None , **kwargs)
参数
描述
x, y
散点的坐标
s
散点的面积
c
散点的颜色(默认值为蓝色,‘b’,其余颜色同plt.plot( ))
marker
散点样式(默认值为实心圆,"o,其余样式同plt.plot( ))
alpha
散点透明度 ([0,1]之间的数,0表示完全透明,1则表示完全不透明)
linewidths
散点的边缘线宽
edgecolors
散点的边缘颜色
cmap
Colormap,默认 None,标量或者是一个 colormap 的名字,只有c是一个浮点数数组的时候才使用
案例
1 2 3 4 5 6 7 8 9 10 11 import numpy as npimport matplotlib.pyplot as plt x = np.random.rand(50 ) y = np.random.rand(50 ) s = (100 * np.random.randn(50 )) colors = np.random.rand(50 ) plt.scatter(x, y, s, c=colors) plt.show()
10、词云图
WordCloud 是一款python环境下的词云图工具包,同时支持python2和python3把关键词数据转换成直观且有趣的图文模式
pip安装
conda安装
1 conda install -c conda-forge wordcloud
【b站视频】
11、保存图片
savefig()
1 2 plt.savefig(fname, dpi=None , facecolor='w' , edgecolor='w' , orientation='portrait' , papertype=None , \ format =None , transparent=False , bbox_inches=None , pad_inches=0.1 , frameon=None , metadata=None )
参数
描述
fname
(字符串或者仿路径或仿文件)如果格式已经设置,这将决定输出的格式并将文件按fname来保存。如果格式没有设置,在fname有扩展名的情况下推断按此保存,没有扩展名将按照默认格式存储为“png”格式,并将适当的扩展名添加在fname后面。
dpi
分辨率,每英寸的点数
facecolor
(颜色或“auto”,默认值:“auto”) : 图形表面颜色。如果是“auto”,使用当前图形的表面颜色
edgecolor
(颜色或“auto”,默认值:“auto”) : 图形边缘颜色。如果是“auto”,使用当前图形的边缘颜色
format
字符串,文件格式,比如“png”,“pdf”,“svg”等,未设置的行为将被记录在fname中
transparent
用于将图片背景设置为透明。图形也会是透明,除非通过关键字参数指定了表面颜色或边缘
案例
1 2 3 4 5 6 7 8 import numpy as npimport matplotlib.pyplot as plt x = np.arange(-50 , 51 ) y = x ** 2 plt.plot(x, y) plt.savefig('第一个绘图程序.jpg' ) plt.show()
五、pandas
千锋教育
Pandas 是基于NumPy的一种工具,该工具是为解决数据分析任务而创建的, Pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
Pandas与出色的 Jupyter工具包和其他库相结合,Python中用于进行数据分析的环境在性能、生产率和协作能力方面都是卓越的。
Pandas的主要数据结构是 **Series(**一维数据)与 **DataFrame **(二维数据),这两种数据结构足以处理金融、统计、社会科学、工程等领域里的大多数案例
处理数据一般分为几个阶段:数据整理与清洗、数据分析与建模、数据可视化,Pandas 是处理数据的理想工具。
1. pandas安装
Anaconda环境: 无需安装
普通Python环境: pip install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple
2. Pandas数据结构
Series
Series是一种类似于一维数组的对象,由下面两个部分组成:
values:一组数据(ndarray类型)
index:相关的数据索引标签
1)Series的创建
两种创建方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import numpy as npimport pandas as pd list1 = [11 , 22 , 33 , 44 ] s = pd.Series(list1)print ("由列表创建:" )print (s) n = np.array(list1) s = pd.Series(n)print ("\n由numpy创建:" )print (s)print ("\n查看series的类型对象:" ) print (type (s))print ("\nSeries属性: index和values" )print ("index:" , s.index)print ("values:" , s.values)print ("\n修改索引:" ) s.index = list ("abcd" )print (s.index)print ("通过索引获取值:" , s.b, s.c, s['d' ]) s.index = ["鲁班" , "李白" , "诸葛亮" , "张飞" ]print (s.index)print ("通过索引获取值:" , s["鲁班" ])
查看输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 由列表创建: 0 11 1 22 2 33 3 44 dtype: int64 由numpy创建: 0 11 1 22 2 33 3 44 dtype: int32 查看series的类型对象: <class 'pandas.core.series.Series'> Series属性: index和values index: RangeIndex(start=0, stop=4, step=1) values: [11 22 33 44] 修改索引: Index(['a', 'b', 'c', 'd'], dtype='object') 通过索引获取值: 22 33 44 Index(['鲁班', '李白', '诸葛亮', '张飞'], dtype='object') 通过索引获取值: 11
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 import numpy as npimport pandas as pd d = { 'a' : 11 , 'b' : 22 , 'c' : 33 , 'd' : 44 } s = pd.Series(d)print ("由 字典 创建:" )print (s)print ("\n修改索引:" ) s.index = list ("ABCD" )print (s) d = { 'a' : np.random.randint(0 , 10 , size=(2 ,3 )), 'b' : np.random.randint(0 , 10 , size=(2 ,3 )), 'c' : np.random.randint(0 , 10 , size=(2 ,3 )), 'd' : np.random.randint(0 , 10 , size=(2 ,3 )) } s = pd.Series(d)print ("\n一个实例:" )print (s)print ("\nmore:" ) s = pd.Series([1 ,2 ,3 ], index=["张三" , '李四' , '王五' ], name="人物" )print (s)
查看输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 由 字典 创建: a 11 b 22 c 33 d 44 dtype: int64 修改索引: A 11 B 22 C 33 D 44 dtype: int64 一个实例: a [[2, 1, 1], [9, 2, 3]] b [[7, 3, 5], [4, 5, 5]] c [[4, 7, 8], [9, 9, 7]] d [[2, 0, 6], [8, 3, 5]] dtype: object more: 张三 1 李四 2 王五 3 Name: 人物, dtype: int64
2)Series的索引
可以使用中括号取单个索引(此时返回的是元素类型),或者中括号里一个列表取多个索引(此时返回的仍然是一个Series类型)。分为显示索引和隐式索引:
使用index中的元素作为索引值
使用.loc[] —— (推荐使用 ,为了和后面作区别)
注意,此时是闭区间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import numpy as npimport pandas as pd s = pd.Series({'语文' : 150 , "数学" : 100 , "英语" : 120 , "Python" : 99 })print ("法一:" )print (s['语文' ], '\n' ) print (s[['语文' , "Python" , "数学" ]], '\n' ) print (s[['语文' ]], '\n' ) print ("法二:" )print (s.loc['语文' ], '\n' )print (s.loc[['语文' , "Python" , "数学" ]], '\n' )print (s.loc[['语文' ]], '\n' )
查看输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 法一: 150 语文 150 Python 99 数学 100 dtype: int64 语文 150 dtype: int64 法二: 150 语文 150 Python 99 数学 100 dtype: int64 语文 150 dtype: int64
使用整数作为索引值
使用.iloc[] ——(推荐 )
注意,此时是半开区间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import numpy as npimport pandas as pd s = pd.Series({'语文' : 150 , "数学" : 100 , "英语" : 120 , "Python" : 99 })print ("法一:" )print (s[0 ], '\n' ) print (s[[0 , 2 , 1 ]], '\n' ) print (s[[0 ]], '\n' ) print ("法二:" )print (s.iloc[0 ], '\n' ) print (s.iloc[[0 , 2 , 1 ]], '\n' ) print (s.iloc[[0 ]], '\n' )
查看输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 法一: 150 语文 150 英语 120 数学 100 dtype: int64 语文 150 dtype: int64 法二: 150 语文 150 英语 120 数学 100 dtype: int64 语文 150 dtype: int64
3)Series的切片
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import numpy as npimport pandas as pd s = pd.Series({'语文' : 150 , "数学" : 100 , "英语" : 120 , "Python" : 99 , "Numpy" : 66 , "Pandas" : 199 })print ("隐式切片:" )print (s[1 : 4 ], '\n' )print (s.iloc[1 : 4 ], '\n' )print ("显式切片:" )print (s["数学" : "Python" ], '\n' )print (s.loc["数学" : "Python" ], '\n' )
查看输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 隐式切片: 数学 100 英语 120 Python 99 dtype: int64 数学 100 英语 120 Python 99 dtype: int64 显式切片: 数学 100 英语 120 Python 99 dtype: int64 数学 100 英语 120 Python 99 dtype: int64
4)Series的属性和方法
shape —— 形状
size —— 大小
index —— 索引
values —— 值
dtype —— 元素类型
name —— Series名字
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import numpy as npimport pandas as pd s = pd.Series({'语文' : 150 , "数学" : 100 , "英语" : 120 , "Python" : 99 , "Numpy" : 66 , "Pandas" : 199 })print ("shape —— 形状:" )print (s.shape, '\n' )print ("size —— 大小:" )print (s.size, '\n' )print ("index —— 索引:" )print (s.index, '\n' )print ("values —— 值:" )print (s.values, '\n' )print ("dtype —— 元素类型:" )print (s.dtype, '\n' )print ("name —— Series名字:" )print (s.name, '\n' )
查看输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 shape —— 形状: (6,) size —— 大小: 6 index —— 索引: Index(['语文', '数学', '英语', 'Python', 'Numpy', 'Pandas'], dtype='object') values —— 值: [150 100 120 99 66 199] dtype —— 元素类型: int64 name —— Series名字: None
head()
查看前几条数据,默认5条
tail()
查看后几条数据,默认5条
1 2 3 4 5 6 7 8 9 10 11 12 import numpy as npimport pandas as pd s = pd.Series({'语文' : 150 , "数学" : 100 , "英语" : 120 , "Python" : 99 , "Numpy" : 66 , "Pandas" : 199 })print (s.head(), '\n' ) print (s.head(2 ), '\n' )print (s.tail(), '\n' )print (s.tail(2 ), '\n' )
查看输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 语文 150 数学 100 英语 120 Python 99 Numpy 66 dtype: int64 语文 150 数学 100 dtype: int64 数学 100 英语 120 Python 99 Numpy 66 Pandas 199 dtype: int64 Numpy 66 Pandas 199 dtype: int64
pd.isnull()
pd.notnull()
isnull()
notnull()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import numpy as npimport pandas as pd s = pd.Series(["张三" , "李四" , "王五" , np.nan])print ("isnul():" )print (pd.isnull(s), '\n' ) print ("notnul():" )print (pd.notnull(s), '\n' ) print (s[ pd.notnull(s) ])print ("等价于:" )print (s[[True ,True ,True ,False ]],'\n' )print (s[~pd.isnull(s)],'\n' )
查看输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 isnul(): 0 False 1 False 2 False 3 True dtype: bool notnul(): 0 True 1 True 2 True 3 False dtype: bool 0 张三 1 李四 2 王五 dtype: object 等价于: 0 张三 1 李四 2 王五 dtype: object 0 张三 1 李四 2 王五 dtype: object
5)Series的运算
(1) 适用于NumPy的数组运算也适用于Series
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import numpy as npimport pandas as pd s = pd.Series(np.random.randint(10 , 100 , size=3 ))print ("原数据:" )print (s, '\n' )print ("+" )print (s + 100 , '\n' )print ("-" )print (s - 100 , '\n' )print ("*" )print (s * 100 , '\n' )print ("/" )print (s / 100 , '\n' )print ("//" )print (s // 10 , '\n' )print ("**" )print (s ** 2 , '\n' )
查看输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 原数据: 0 55 1 98 2 65 dtype: int32 + 0 155 1 198 2 165 dtype: int32 - 0 -45 1 -2 2 -35 dtype: int32 * 0 5500 1 9800 2 6500 dtype: int32 / 0 0.55 1 0.98 2 0.65 dtype: float64 // 0 5 1 9 2 6 dtype: int32 ** 0 3025 1 9604 2 4225 dtype: int32
在运算中自动对齐索引的数据
如果索引不对应,则补NaN
Series没有广播机制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import numpy as npimport pandas as pd s1 = pd.Series([10 , 20 , 30 ]) s2 = pd.Series([10 , 20 , 30 ])print (s1 + s2, '\n' ) s1 = pd.Series([10 , 20 , 30 ], [1 , 2 , 3 ]) s2 = pd.Series([10 , 20 , 30 ], [3 , 2 , 1 ])print (s1 + s2, '\n' ) s1 = pd.Series([10 , 20 , 30 ]) s2 = pd.Series([10 , 20 , 30 , 40 ])print (s1 + s2, '\n' )print (s1.add(s2, fill_value=1 ))
查看输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 0 20 1 40 2 60 dtype: int64 1 40 2 40 3 40 dtype: int64 0 20.0 1 40.0 2 60.0 3 NaN dtype: float64 0 20.0 1 40.0 2 60.0 3 41.0 dtype: float64
DataFrame
前期提要:Series可以看做是一个有序的字典结构
DataFrame是一个【表格型】的数据结构,可以看做是【由Series组成的字典】(共用同一个索引)。DataFrame由按一定顺序排列的多列数据组成。设计初衷是将Series的使用场景从一维拓展到多维。DataFrame既有行索引,也有列索引。
行索引:index
列索引:columns
值:values(numpy的二维数组)
1)DataFrame的创建
最常用的方法是传递一个字典来创建。DataFrame以字典的键作为每一【列】的名称,以字典的值(一个数组)作为每一列。
此外,DataFrame会自动加上每一行的索引(和Series一样)。
同Series一样,若传入的列与字典的键不匹配,则相应的值为NaN
1 2 3 4 5 6 7 8 9 10 import numpy as npimport pandas as pd d = { 'name' : ["鲁班" , '陈咬金' , "猪八戒" ], 'age' : [7 , 9 , 8 ], 'sex' : ['男' , '女' , '男' ] } df = pd.DataFrame(d)print (df)
查看输出 1 2 3 4 name age sex 0 鲁班 7 男 1 陈咬金 9 女 2 猪八戒 8 男
values —— 值
columns —— 列索引
index —— 行索引(可以直接赋值修改)
shape —— 形状
head() —— 查看前几行数据 (默认5条)
tail() —— 查看后几行数据 (默认5条)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import numpy as npimport pandas as pd d = { 'name' : ["鲁班" , '陈咬金' , "猪八戒" ], 'age' : [7 , 9 , 8 ], 'sex' : ['男' , '女' , '男' ] } df = pd.DataFrame(d)print ("values —— 值" )print (df.values, '\n' )print ("columns —— 列索引" )print (df.columns, '\n' )print ("index —— 行索引" )print (df.index, '\n' )print ("shape —— 形状" )print (df.shape, '\n' )print ("head() —— 查看前几行数据" )print (df.head(), '\n' ) print ("tail() —— 查看后几行数据" )print (df.tail(), '\n' )
查看输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 values —— 值 [['鲁班' 7 '男'] ['陈咬金' 9 '女'] ['猪八戒' 8 '男']] columns —— 列索引 Index(['name', 'age', 'sex'], dtype='object') index —— 行索引 RangeIndex(start=0, stop=3, step=1) shape —— 形状 (3, 3) head() —— 查看前几行数据 name age sex 0 鲁班 7 男 1 陈咬金 9 女 2 猪八戒 8 男 tail() —— 查看后几行数据 name age sex 0 鲁班 7 男 1 陈咬金 9 女 2 猪八戒 8 男
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import numpy as npimport pandas as pd d = { 'name' : ["鲁班" , '陈咬金' , "猪八戒" ], 'age' : [7 , 9 , 8 ], 'sex' : ['男' , '女' , '男' ] } df = pd.DataFrame(d, list ('abc' ))print (df, '\n' ) df = pd.DataFrame( data=np.random.randint(10 , 100 , size=(4 ,6 )), index=["小明" , "小红" , "小欢" , "小白" ], columns=["语文" , "数学" , "英语" , "物理" , "化学" , "生物" ] )print (df)
查看输出 1 2 3 4 5 6 7 8 9 10 name age sex a 鲁班 7 男 b 陈咬金 9 女 c 猪八戒 8 男 语文 数学 英语 物理 化学 生物 小明 75 64 83 10 45 43 小红 47 26 49 28 92 93 小欢 68 86 30 87 50 88 小白 69 40 47 96 18 67
2)DataFrame的索引
通过类似字典的方式
通过属性的方式
可以将DataFrame的列获取为一个Series。返回的Series拥有原DataFrame相同的索引,且name属性也已经设置好了,就是相应的列名。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import numpy as npimport pandas as pd df = pd.DataFrame( data=np.random.randint(10 , 100 , size=(4 ,6 )), index=["小明" , "小红" , "小欢" , "小白" ], columns=["语文" , "数学" , "英语" , "物理" , "化学" , "生物" ] )print (df['语文' ], '\n' ) print (df[['语文' , '化学' ]], '\n' ) print (df[['语文' ]], '\n' )
查看输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 小明 73 小红 14 小欢 44 小白 78 Name: 语文, dtype: int32 语文 化学 小明 73 84 小红 14 58 小欢 44 56 小白 78 86 语文 小明 73 小红 14 小欢 44 小白 78
使用.loc[ ]加index来进行行索引
使用.iloc[ ]加整数来进行行索引
同样返回一个Series,index为原来的columns。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import numpy as npimport pandas as pd df = pd.DataFrame( data=np.random.randint(10 , 100 , size=(4 ,6 )), index=["小明" , "小红" , "小欢" , "小白" ], columns=["语文" , "数学" , "英语" , "物理" , "化学" , "生物" ] )print (df.loc['小明' ], '\n' ) print (df.iloc[0 ], '\n' )print (df.loc[['小明' , '小欢' ]], '\n' ) print (df.loc[['小明' ]], '\n' )print (df.iloc[[0 , 2 ]], '\n' ) print (df.iloc[[0 ]], '\n' )
查看输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 语文 29 数学 90 英语 56 物理 90 化学 33 生物 36 Name: 小明, dtype: int32 语文 29 数学 90 英语 56 物理 90 化学 33 生物 36 Name: 小明, dtype: int32 语文 数学 英语 物理 化学 生物 小明 29 90 56 90 33 36 小欢 74 56 97 73 93 94 语文 数学 英语 物理 化学 生物 小明 29 90 56 90 33 36 语文 数学 英语 物理 化学 生物 小明 29 90 56 90 33 36 小欢 74 56 97 73 93 94 语文 数学 英语 物理 化学 生物 小明 29 90 56 90 33 36
使用列索引
使用行索引(iloc[3,1]相当于两个参数;iloc[[3,3]] 里面的[3,3]看做一个参数)
使用values属性(二维numpy数组)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import numpy as npimport pandas as pd df = pd.DataFrame( data=np.random.randint(0 , 100 , size=(4 , 6 )), index=['小明' , "小红" , '小绿' , '小黄' ], columns=['语文' , '数学' , '英语' , 'Python' , 'Numpy' , 'Pandas' ] )print ("原表:" )print (df)print (df['语文' ][1 ])print (df['语文' ]['小明' ])print (df.iloc[1 ]['语文' ])print (df.loc['小明' , '语文' ])
查看输出 1 2 3 4 5 6 7 8 9 10 原表: 语文 数学 英语 Python Numpy Pandas 小明 7 88 51 10 81 50 小红 82 51 94 76 6 98 小绿 92 22 88 1 35 94 小黄 86 87 63 65 18 20 82 7 82 7
3)DataFrame 的切片
【注意】 直接用中括号时:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 import numpy as npimport pandas as pd df = pd.DataFrame( data=np.random.randint(0 , 100 , size=(4 , 6 )), index=['小明' , "小红" , '小绿' , '小黄' ], columns=['语文' , '数学' , '英语' , 'Python' , 'Numpy' , 'Pandas' ] )print ("原表:" )print (df, '\n' )print ("行切片:" )print (df[1 : 3 ], '\n' ) print (df['小明' : "小绿" ], '\n' ) print (df.iloc[1 : 3 ], '\n' ) print (df.loc['小明' : "小绿" ], '\n' ) print ("列切片:" )print (df.iloc[:, 1 :3 ], '\n' )print (df.loc[:, "数学" : "Python" ], '\n' )print ("练习:" )print (df.loc["小明" :"小绿" , "数学" :"Python" ], '\n' )print (df.iloc[:3 , 1 :4 ], '\n' )print (df.loc[["小明" , "小黄" ], ["语文" , "Pandas" ]])
查看输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 原表: 语文 数学 英语 Python Numpy Pandas 小明 43 24 93 60 28 80 小红 60 22 53 85 74 8 小绿 39 23 75 63 84 14 小黄 1 82 0 86 60 47 行切片: 语文 数学 英语 Python Numpy Pandas 小红 60 22 53 85 74 8 小绿 39 23 75 63 84 14 语文 数学 英语 Python Numpy Pandas 小明 43 24 93 60 28 80 小红 60 22 53 85 74 8 小绿 39 23 75 63 84 14 语文 数学 英语 Python Numpy Pandas 小红 60 22 53 85 74 8 小绿 39 23 75 63 84 14 语文 数学 英语 Python Numpy Pandas 小明 43 24 93 60 28 80 小红 60 22 53 85 74 8 小绿 39 23 75 63 84 14 列切片: 数学 英语 小明 24 93 小红 22 53 小绿 23 75 小黄 82 0 数学 英语 Python 小明 24 93 60 小红 22 53 85 小绿 23 75 63 小黄 82 0 86 练习: 数学 英语 Python 小明 24 93 60 小红 22 53 85 小绿 23 75 63 数学 英语 Python 小明 24 93 60 小红 22 53 85 小绿 23 75 63 语文 Pandas 小明 43 80 小黄 1 47
4)DataFrame的运算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import numpy as npimport pandas as pd df = pd.DataFrame( data=np.random.randint(0 , 100 , size=(4 , 6 )), index=['小明' , "小红" , '小绿' , '小黄' ], columns=['语文' , '数学' , '英语' , 'Python' , 'Numpy' , 'Pandas' ] )print ("原表:" )print (df, '\n' )print (df + 100 , '\n' )print (df - 100 , '\n' )print (df / 10 , '\n' )print (df % 10 , '\n' )print (df ** 2 , '\n' )
查看输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 原表: 语文 数学 英语 Python Numpy Pandas 小明 81 3 84 78 28 0 小红 94 82 63 15 7 4 小绿 32 88 8 74 37 62 小黄 57 21 34 38 7 98 语文 数学 英语 Python Numpy Pandas 小明 181 103 184 178 128 100 小红 194 182 163 115 107 104 小绿 132 188 108 174 137 162 小黄 157 121 134 138 107 198 语文 数学 英语 Python Numpy Pandas 小明 -19 -97 -16 -22 -72 -100 小红 -6 -18 -37 -85 -93 -96 小绿 -68 -12 -92 -26 -63 -38 小黄 -43 -79 -66 -62 -93 -2 语文 数学 英语 Python Numpy Pandas 小明 8.1 0.3 8.4 7.8 2.8 0.0 小红 9.4 8.2 6.3 1.5 0.7 0.4 小绿 3.2 8.8 0.8 7.4 3.7 6.2 小黄 5.7 2.1 3.4 3.8 0.7 9.8 语文 数学 英语 Python Numpy Pandas 小明 1 3 4 8 8 0 小红 4 2 3 5 7 4 小绿 2 8 8 4 7 2 小黄 7 1 4 8 7 8 语文 数学 英语 Python Numpy Pandas 小明 6561 9 7056 6084 784 0 小红 8836 6724 3969 225 49 16 小绿 1024 7744 64 5476 1369 3844 小黄 3249 441 1156 1444 49 9604
在运算中自动对齐索引的数据
如果索引不对应,则补NaN
DataFrame没有广播机制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import numpy as npimport pandas as pd df1 = pd.DataFrame( data={ 'Python' : [100 , 90 , 80 ], 'Java' : [80 , 70 , 60 ], 'PHP' : [60 , 50 , 40 ] }, index=['张飞' , "吕布" , '关羽' ] ) df2 = pd.DataFrame( data={ 'Python' : [100 , 90 , 80 , 70 ], 'Java' : [80 , 70 , 60 , 50 ], 'PHP' : [60 , 50 , 40 , 30 ], 'Go' : [40 , 30 , 20 , 10 ] }, index=['张飞' , "吕布" , '关羽' , "刘备" ] )print (df1 + df2, '\n' )print (df1.add(df2, fill_value=1000 ), '\n' )
查看输出 1 2 3 4 5 6 7 8 9 10 11 12 Go Java PHP Python 关羽 NaN 120.0 80.0 160.0 刘备 NaN NaN NaN NaN 吕布 NaN 140.0 100.0 180.0 张飞 NaN 160.0 120.0 200.0 Go Java PHP Python 关羽 1020.0 120.0 80.0 160.0 刘备 1010.0 1050.0 1030.0 1070.0 吕布 1030.0 140.0 100.0 180.0 张飞 1040.0 160.0 120.0 200.0
使用Python操作符:以行为单位操作(参数必须是行),对所有行都有效。(类似于numpy中二维数组与一维数组的运算,但可能出现NaN)
使用pandas操作函数:
axis=0:以列为单位操作(参数必须是列),对所有列都有效。
axis=1:以行为单位操作(参数必须是行),对所有行都有效。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import numpy as npimport pandas as pd df1 = pd.DataFrame( data={ 'Python' : [100 , 90 , 80 ], 'Java' : [80 , 70 , 60 ], 'PHP' : [60 , 50 , 40 ] }, index=['张飞' , "吕布" , '关羽' ] ) s = pd.Series([100 , 10 , 1 ], index=df1.columns)print (df1 + s, '\n' )print (df1.add(s), '\n' ) print (df1.add(s, axis='columns' ), '\n' ) print (df1.add(s, axis=1 ), '\n' ) s = pd.Series([100 , 10 , 1 ], index=df1.index)print (df1.add(s, axis='index' ), '\n' ) print (df1.add(s, axis=0 ), '\n' )
查看输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 Python Java PHP 张飞 200 90 61 吕布 190 80 51 关羽 180 70 41 Python Java PHP 张飞 200 90 61 吕布 190 80 51 关羽 180 70 41 Python Java PHP 张飞 200 90 61 吕布 190 80 51 关羽 180 70 41 Python Java PHP 张飞 200 90 61 吕布 190 80 51 关羽 180 70 41 Python Java PHP 张飞 200 180 160 吕布 100 80 60 关羽 81 61 41 Python Java PHP 张飞 200 180 160 吕布 100 80 60 关羽 81 61 41
3. Pandas层次化索引
3.1. 创建多层行索引
最常见的方法是给DataFrame构造函数的index参数传递两个或更多的数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import numpy as npimport pandas as pd data = np.random.randint(0 , 100 , size=(6 , 6 )) index = [ ['1班' , '1班' , '1班' , '2班' , '2班' , '2班' ], ['张三' , '李四' , '王五' , '赵六' , '田七' , '孙八' ] ] columns = [ ['期中' , '期中' , '期中' , '期末' , '期末' , '期末' ], ['语文' , '数学' , '英语' , '语文' , '数学' , '英语' ] ] df = pd.DataFrame(data=data, index=index, columns=columns)print (df)
查看输出 1 2 3 4 5 6 7 8 期中 期末 语文 数学 英语 语文 数学 英语 1班 张三 5 48 31 55 77 80 李四 49 31 69 47 53 87 王五 9 36 93 97 17 34 2班 赵六 12 76 5 36 45 90 田七 50 10 1 89 45 16 孙八 30 1 25 5 30 22
Series也可以创建多层索引
1 2 3 4 5 6 7 8 9 10 11 12 import numpy as npimport pandas as pd data = np.random.randint(0 , 100 , size=6 ) index = [ ['1班' , '1班' , '1班' , '2班' , '2班' , '2班' ], ['张三' , '李四' , '王五' , '赵六' , '田七' , '孙八' ] ] s = pd.Series(data=data, index=index)print (s)
查看输出 1 2 3 4 5 6 7 1班 张三 33 李四 75 王五 3 2班 赵六 46 田七 28 孙八 99 dtype: int32
使用数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import numpy as npimport pandas as pd data = np.random.randint(0 , 100 , size=(6 , 6 )) index = pd.MultiIndex.from_arrays( [ ['1班' , '1班' , '1班' , '2班' , '2班' , '2班' ], ['张三' , '李四' , '王五' , '赵六' , '田七' , '孙八' ] ] ) columns = [ ['期中' , '期中' , '期中' , '期末' , '期末' , '期末' ], ['语文' , '数学' , '英语' , '语文' , '数学' , '英语' ] ] df = pd.DataFrame(data=data, index=index, columns=columns)print (df)
查看输出 1 2 3 4 5 6 7 8 期中 期末 语文 数学 英语 语文 数学 英语 1班 张三 15 18 8 89 60 66 李四 82 16 91 80 18 73 王五 37 60 32 87 12 74 2班 赵六 38 31 34 84 74 53 田七 17 11 99 74 82 47 孙八 5 57 54 58 30 17
使用tuple
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import numpy as npimport pandas as pd data = np.random.randint(0 , 100 , size=(6 , 6 )) index = pd.MultiIndex.from_tuples( ( ('1班' , '张三' ), ('1班' , '李四' ), ('1班' , '王五' ), ('2班' , '赵六' ), ('2班' , '田七' ), ('2班' , '孙八' ), ) ) columns = [ ['期中' , '期中' , '期中' , '期末' , '期末' , '期末' ], ['语文' , '数学' , '英语' , '语文' , '数学' , '英语' ] ] df = pd.DataFrame(data=data, index=index, columns=columns)print (df)
查看输出 1 2 3 4 5 6 7 8 期中 期末 语文 数学 英语 语文 数学 英语 1班 张三 16 45 36 67 48 13 李四 72 29 72 8 81 33 王五 56 98 69 93 93 55 2班 赵六 24 64 30 1 76 88 田七 75 28 16 62 20 14 孙八 33 53 96 32 32 75
使用product
笛卡尔积:{a, b} {c, d} => {a, c} {a, d} {b, c} {b, d}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import numpy as npimport pandas as pd data = np.random.randint(0 , 100 , size=(6 , 6 )) index = pd.MultiIndex.from_product( [ ['1班' , '2班' ], ['张三' , '李四' , '王五' ] ] ) columns = [ ['期中' , '期中' , '期中' , '期末' , '期末' , '期末' ], ['语文' , '数学' , '英语' , '语文' , '数学' , '英语' ] ] df = pd.DataFrame(data=data, index=index, columns=columns)print (df)
查看输出 1 2 3 4 5 6 7 8 期中 期末 语文 数学 英语 语文 数学 英语 1班 张三 80 82 69 56 95 71 李四 87 9 69 15 48 19 王五 72 80 56 18 37 60 2班 张三 89 24 86 42 88 24 李四 39 77 83 35 97 96 王五 67 43 48 52 48 79
3.2. 创建多层列索引(同行索引)
除了行索引index
,列索引columns
也能用同样的方法创建多层索引
3.3. 多层索引对象的索引与切片操作
【重要】对于Series来说,直接中括号[]与使用.loc()完全一样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 import numpy as npimport pandas as pd data = np.random.randint(0 , 100 , size=6 ) index = [ ['1班' , '1班' , '1班' , '2班' , '2班' , '2班' ], ['张三' , '李四' , '王五' , '赵六' , '田七' , '孙八' ] ] s = pd.Series(data=data, index=index)print ("原表:" )print (s, '\n' )print ("s['1班']:" )print (s['1班' ], '\n' )print ("s.loc['1班']:" )print (s.loc['1班' ], '\n' )print ("s.loc[['1班']]:" )print (s.loc[['1班' ]], '\n' )print ("s.loc[['1班', '2班']]:" )print (s.loc[['1班' , '2班' ]], '\n' )print ("s['1班']['张三']:" )print (s['1班' ]['张三' ], '\n' )print ("s.loc['1班']['张三']:" )print (s.loc['1班' ]['张三' ], '\n' )print ("s.loc['1班','张三']:" )print (s.loc['1班' ,'张三' ], '\n' )print ("s['1班', '张三']:" )print (s['1班' , '张三' ], '\n' )print ("s[1]:" )print (s[1 ], '\n' )print ("s.iloc[1]:" )print (s.iloc[1 ], '\n' )print ("s.iloc[[3, 2]]:" )print (s.iloc[[3 , 2 ]], '\n' )print ("s['1班': '1班']:" )print (s['1班' : '1班' ], '\n' )print ("s.loc['1班': '2班']:" )print (s.loc['1班' : '2班' ], '\n' )print ("s[1: 4]:" )print (s[1 : 4 ], '\n' )print ("s.iloc[1: 5]:" )print (s.iloc[1 : 5 ], '\n' )
查看输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 原表: 1班 张三 85 李四 50 王五 44 2班 赵六 81 田七 3 孙八 28 dtype: int32 s['1班']: 张三 85 李四 50 王五 44 dtype: int32 s.loc['1班']: 张三 85 李四 50 王五 44 dtype: int32 s.loc[['1班']]: 1班 张三 85 李四 50 王五 44 dtype: int32 s.loc[['1班', '2班']]: 1班 张三 85 李四 50 王五 44 2班 赵六 81 田七 3 孙八 28 dtype: int32 s['1班']['张三']: 85 s.loc['1班']['张三']: 85 s.loc['1班','张三']: 85 s['1班', '张三']: 85 s[1]: 50 s.iloc[1]: 50 s.iloc[[3, 2]]: 2班 赵六 81 1班 王五 44 dtype: int32 s['1班': '1班']: 1班 张三 85 李四 50 王五 44 dtype: int32 s.loc['1班': '2班']: 1班 张三 85 李四 50 王五 44 2班 赵六 81 田七 3 孙八 28 dtype: int32 s[1: 4]: 1班 李四 50 王五 44 2班 赵六 81 dtype: int32 s.iloc[1: 5]: 1班 李四 50 王五 44 2班 赵六 81 田七 3 dtype: int32
2)DataFrame的操作
可以直接使用列名称来进行列索引
使用行索引需要用iloc(),loc()等函数
无法直接对二级索引进行索引
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 data = np.random.randint(0 , 100 , size=(6 , 6 )) index = pd.MultiIndex.from_product( [ ['1班' , '2班' ], ['张三' , '李四' , '王五' ] ] ) columns = [ ['期中' , '期中' , '期中' , '期末' , '期末' , '期末' ], ['语文' , '数学' , '英语' , '语文' , '数学' , '英语' ] ] df = pd.DataFrame(data=data, index=index, columns=columns) df['期中' ]['数学' ][1 ] df.iloc[1 , 3 ] df.loc[('1班' , '李四' ), ('期末' , '语文' )] df['期中' ] df['期中' ]['数学' ] df['期中' , '数学' ] df.iloc[:, 2 ] df.iloc[:, [1 ,2 ,3 ]] df.loc['1班' ] df.loc['1班' ].loc['张三' ] df.loc['1班' , '张三' ] df.loc[('1班' , '张三' )] df.iloc[1 ] df.iloc[[1 ]] df.iloc[[1 ,2 ,3 ]] df.iloc[1 :5 ] df.loc['1班' : '2班' ] df.loc[('1班' , '李四' ) : ('2班' , '李四' )] df.iloc[:, 1 : 5 ] df.loc[:, '期中' : '期末' ]
3.4. 索引的堆叠(stack)
【小技巧】使用stack()的时候,level等于哪一个,哪一个就消失,出现在行里。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 data = np.random.randint(0 , 100 , size=(6 , 6 )) index = pd.MultiIndex.from_product( [ ['1班' , '2班' ], ['张三' , '李四' , '王五' ] ] ) columns = [ ['期中' , '期中' , '期中' , '期末' , '期末' , '期末' ], ['语文' , '数学' , '英语' , '语文' , '数学' , '英语' ] ] df = pd.DataFrame(data=data, index=index, columns=columns) df.stack() df.stack(level=1 ) df.stack(level=0 )
【小技巧】使用unstack()的时候,level等于哪一个,哪一个就消失,出现在列里。
1 2 3 4 5 df.unstack() df.unstack(level=1 ) df.unstack(level=0 )
使用fill_value填充
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 data = np.random.randint(0 , 100 , size=(6 , 6 )) index = pd.MultiIndex.from_tuples( ( ('1班' , '张三' ), ('1班' , '李四' ), ('1班' , '王五' ), ('2班' , '赵六' ), ('2班' , '田七' ), ('2班' , '孙八' ), ) ) columns = [ ['期中' , '期中' , '期中' , '期末' , '期末' , '期末' ], ['语文' , '数学' , '英语' , '语文' , '数学' , '英语' ] ] df2 = pd.DataFrame(data=data, index=index, columns=columns) df2.unstack() df2.unstack(fill_value=0 )
3.5. 聚合操作
【注意】
需要指定axis
【小技巧】和unstack()相反,聚合的时候,axis等于哪一个,哪一个就保留。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 data = np.random.randint(0 , 100 , size=(6 , 6 )) index = pd.MultiIndex.from_tuples( ( ('1班' , '张三' ), ('1班' , '李四' ), ('1班' , '王五' ), ('2班' , '赵六' ), ('2班' , '田七' ), ('2班' , '孙八' ), ) ) columns = [ ['期中' , '期中' , '期中' , '期末' , '期末' , '期末' ], ['语文' , '数学' , '英语' , '语文' , '数学' , '英语' ] ] df2 = pd.DataFrame(data=data, index=index, columns=columns) df3 = df.loc['1班' , '期中' ] df3.sum () df3.sum (axis=0 ) df3.sum (axis=1 ) df.sum () df.sum (axis=1 ) df.sum (axis=0 , level=0 ) df.sum (axis=1 , level=0 ) df.sum (axis=0 , level=1 ) df.sum (axis=1 , level=1 )
4. Pandas数据合并
pd.concat
pd.append
pd.merge
为了方便,我们首先定义一个生成DataFrame的函数:
1 2 3 4 5 6 7 def make_df (indexs, columns ): data = [[str (j)+str (i) for j in columns] for i in indexs] df = pd.DataFrame(data=data, index=indexs, columns=columns) return df
1. 使用pd.concat()级联
Pandas使用pd.concat函数,与NumPy中的concatenate函数类似,只是多了一些参数:
1) 简单级联
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 df1 = make_df([1 , 2 ], ['A' , 'B' ]) df2 = make_df([3 , 4 ], ['A' , 'B' ]) display(df1, df2) pd.concat([df1, df2]) pd.concat([df1, df2], axis=1 ) pd.concat([df1, df2], ignore_index=True ) pd.concat([df1, df2], keys=['x' , 'y' ])
2) 不匹配级联
不匹配指的是级联的维度的索引不一致。例如纵向级联时列索引不一致,横向级联时行索引不一致
1 2 3 4 5 6 7 8 9 10 11 12 13 df3 = make_df([1 , 2 , 3 , 4 ], ['A' , 'B' , 'C' , 'D' ]) df4 = make_df([2 , 3 , 4 , 5 ], ['B' , 'C' , 'D' , 'E' ]) display(df3, df4) pd.concat([df3, df4]) pd.concat([df3, df4]) pd.concat([df3, df4], join='outer' ) pd.concat([df3, df4], join='inner' )
2. 使用append()函数添加
由于在后面级联的使用非常普遍,因此有一个函数append专门用于在后面添加
1 2 3 4 5 df3 = make_df([1 , 2 , 3 , 4 ], ['A' , 'B' , 'C' , 'D' ]) df4 = make_df([2 , 3 , 4 , 5 ], ['B' , 'C' , 'D' , 'E' ]) display(df3, df4) df3.append(df4, sort=True )
3.使用merge()合并
类似MySQL中表和表之间的合并
merge与concat的区别在于,merge需要依据某一共同的行或列来进行合并
使用pd.merge()合并时,会自动根据两者相同column名称的那一列,作为key来进行合并。
每一列元素的顺序不要求一致
1) 一对一合并
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 df1 = pd.DataFrame({ 'name' : ['张三' , '李四' , '王五' ], 'id' : [1 , 2 , 3 ], 'age' : [22 , 33 , 44 ] }) df2 = pd.DataFrame({ 'id' : [2 , 3 , 4 ], 'sex' : ['男' , '女' , '女' ], 'job' : ['saler' , 'CTO' , 'Programer' ] }) display(df1, df2) df1.merge(df2)
2) 多对一合并
1 2 3 4 5 6 7 8 9 10 11 12 13 14 df1 = pd.DataFrame({ 'name' : ['张三' , '李四' , '王五' ], 'id' : [1 , 2 , 2 ], 'age' : [22 , 33 , 44 ] }) df2 = pd.DataFrame({ 'id' : [2 , 3 , 4 ], 'sex' : ['男' , '女' , '女' ], 'job' : ['saler' , 'CTO' , 'Programer' ] }) display(df1, df2) df1.merge(df2)
3) 多对多合并
1 2 3 4 5 6 7 8 9 10 11 12 13 14 df1 = pd.DataFrame({ 'name' : ['张三' , '李四' , '王五' ], 'id' : [1 , 2 , 2 ], 'age' : [22 , 33 , 44 ] }) df2 = pd.DataFrame({ 'id' : [2 , 2 , 4 ], 'sex' : ['男' , '女' , '女' ], 'job' : ['saler' , 'CTO' , 'Programer' ] }) display(df1, df2) df1.merge(df2)
4) key的规范化
使用on=显式指定哪一列为key,当有多个key相同时使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 df1 = pd.DataFrame({ 'name' : ['张三' , '李四' , '王五' ], 'id' : [1 , 2 , 3 ], 'age' : [22 , 33 , 44 ] }) df2 = pd.DataFrame({ 'id' : [2 , 3 , 4 ], 'name' : ['李四' , '王五' , '赵六' ], 'job' : ['saler' , 'CTO' , 'Programer' ] }) display(df1, df2) df1.merge(df2, on='id' ) df1.merge(df2, on='name' )
使用left_on和right_on指定左右两边的列作为key,当左右两边的key都不想等时使用
1 2 df1.merge(df2, left_on='id' , right_on='id2' )
当左边的列和右边的index相同的时候,使用right_index=True
1 df1.merge(df2, left_index=True , right_on='id2' )
5) 内合并与外合并
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 df1 = pd.DataFrame({ 'name' : ['张三' , '李四' , '王五' ], 'id' : [1 , 2 , 3 ], 'age' : [22 , 33 , 44 ] }) df2 = pd.DataFrame({ 'id' : [2 , 3 , 4 ], 'sex' : ['男' , '女' , '女' ], 'job' : ['saler' , 'CTO' , 'Programer' ] }) display(df1, df2) df1.merge(df2) df1.merge(df2, how='inner' )
1 2 df1.merge(df2, how='outer' )
左合并、右合并:how=‘left’,how=‘right’
1 2 3 4 5 df1.merge(df2, how='left' ) df1.merge(df2, how='right' )
6) 添加后缀
当列冲突时,即有多个列名称相同时,需要使用on=来指定哪一个列作为key,配合suffixes指定冲突列名
可以使用suffixes=自己指定后缀
1 2 3 4 5 6 7 8 9 10 11 12 13 df1 = pd.DataFrame({ 'name' : ['张三' , '李四' , '王五' ], 'id' : [1 , 2 , 3 ], 'age' : [22 , 33 , 44 ] }) df2 = pd.DataFrame({ 'id' : [2 , 3 , 4 ], 'name' : ['李四' , '王五' , '赵六' ], 'job' : ['saler' , 'CTO' , 'Programer' ] }) display(df1, df2) df1.merge(df2, on='id' , suffixes=['_表1' , '_表2' ])
merge合并总结:
合并有三种现象: 一对一, 多对一, 多对多.
合并默认会找相同的列名进行合并, 如果有多个列名相同,用on来指定.
如果没有列名相同,但是数据又相同,可以通过left_on, right_on来分别指定要合并的列.
如果想和index合并, 使用left_index, right_index来指定.
如果多个列相同,合并之后可以通过suffixes来区分.
还可以通过how来控制合并的结果, 默认是内合并, 还有外合并outer, 左合并left, 右合并right.
六、Pandas缺失值处理
有两种缺失值(空值):
1. None
1 2 3 4 5 6 %timeit np.arange(1e5 , dtype=object ).sum () %timeit np.arange(1e5 , dtype=np.int32).sum ()
2. np.nan(NaN)
np.nan是浮点类型,能参与到计算中。但计算的结果总是NaN。
但可以使用np.nan*()函数来计算nan,此时会过滤掉nan。
1 2 3 4 5 6 n = np.array([1 , 2 , 3 , np.nan, 5 , 6 ]) np.nansum(n) np.nan + 10
3. pandas中的None与NaN
1) pandas中None与np.nan都视作np.nan
1 2 3 4 5 6 7 8 9 10 11 data = np.random.randint(0 ,100 , size=(5 , 5 )) df = pd.DataFrame(data=data, columns=list ('ABCDE' )) df.loc[2 , 'B' ] = np.nan df.loc[3 , 'C' ] = None display(df) df.loc[2 , 'B' ] df.loc[3 , 'C' ]
2) pandas中None与np.nan的操作
isnull()
notnull()
all()
any()
dropna(): 过滤丢失数据
fillna(): 填充丢失数据
(1)判断函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 df.isnull() df.notnull() df.isnull().any () df.notnull().all () df.isnull().any (axis=1 ) df.notnull().all (axis=1 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 cond = df.isnull().any (axis=1 ) df[~cond] cond = df.notnull().all (axis=1 ) df[cond] cond = df.notnull().all () df.loc[:, cond] cond = df.isnull().any () df.loc[:, ~cond]
(2) 过滤函数
可以选择过滤的是行还是列(默认为行)
1 2 df.dropna() df.dropna(axis=1 )
也可以选择过滤的方式 how = ‘all’
1 2 df.dropna(how='any' ) df.dropna(how='all' , axis=1 )
inplace=True 修改原数据
1 2 3 4 5 df2 = df.copy() df2.dropna(inplace=True ) df2
(3) 填充函数 Series/DataFrame
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 df.fillna(value=100 ) df2 = df.copy() df2.loc[1 , 'B' ] = np.nan df2.loc[4 , 'C' ] = None display(df2) df2.fillna(value=100 , limit=1 , inplace=True ) df.fillna(method='ffill' ) df.fillna(method='bfill' ) df.fillna(method='ffill' , axis=1 ) df.fillna(method='bfill' , axis=1 )
七、Pandas处理重复值和异常值
1 2 3 4 5 6 def make_df (indexs, columns ): data = [[str (j)+str (i) for j in columns] for i in indexs] df = pd.DataFrame(data=data, index=indexs, columns=columns) return df
1. 删除重复行
使用duplicated()函数检测重复的行,返回元素为布尔类型的Series对象
每个元素对应一行,如果该行不是第一次出现,则元素为True
1 2 3 4 5 6 7 8 9 10 11 12 13 df.loc[1 ] = df.loc[2 ] df.duplicated() df.loc[1 , 'D' ] = 'DDD' df.duplicated(subset=['A' , 'B' , 'C' ])
使用drop_duplicates()函数删除重复的行
1 2 df.drop_duplicates(subset=['A' , 'B' , 'C' ]) df.drop_duplicates(subset=['A' , 'B' , 'C' ], keep='last' )
2. 映射
映射的含义:创建一个映射关系列表,把values元素和一个特定的标签或者字符串绑定
包含三种操作:
replace()函数:替换元素
map()函数:处理某一单独的列, 最重要
rename()函数:替换索引
1) replace()函数:替换元素
使用replace()函数,对values进行替换操作
1 2 3 4 5 6 7 8 index = ['鲁班' , '张三丰' , '张无忌' , '杜甫' , '李白' ] columns = ['Python' , 'Java' , 'H5' , 'Pandas' ] data = np.random.randint(0 , 100 , size=(5 , 4 )) df = pd.DataFrame(data=data, index=index, columns=columns) df.replace({1 : 100 })
2) map()函数: 适合处理某一单独的列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 df2 = df.copy() df2 df2['Python' ].map ({12 : 100 , 11 : 90 }) df2['NumPy' ] = df2['Python' ].map (lambda x: x+100 ) df2 df2['是否及格' ] = df2['Java' ].map (lambda n: "及格" if n>=60 else "不及格" ) df2def fn (n ): if n >= 80 : return '优秀' elif n >= 60 : return '及格' return '不及格' df2['等级' ] = df2['Java' ].map (fn) df2
3) rename()函数:替换索引
1 2 3 4 5 6 7 8 9 df3 = df.copy() df3 df3.rename({'鲁班' : "Mr Lu" }) df3.rename({'Python' : 'PYTHON' }, axis=1 ) df3.rename(index={'鲁班' : "Mr Lu" }) df3.rename(columns={'Python' : 'PYTHON' })
4) apply()函数:既支持 Series,也支持 DataFrame
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 df = pd.DataFrame(data=np.random.randint(0 , 10 , size=(5 ,3 )), index=list ('ABCDE' ), columns=['Python' , 'NumPy' , 'Pandas' ]) df['Python' ].apply(lambda x:True if x >5 else False ) df.apply(lambda x : x.median(), axis=0 ) df.apply(lambda x : x.median(), axis=1 ) def convert (x ): return (np.round (x.mean(), 1 ), x.count()) df.apply(convert, axis=1 ) df.applymap(lambda x : x + 100 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 df = pd.DataFrame(data=np.random.randint(0 , 10 , size=(10 ,3 )), index=list ('ABCDEFHIJK' ), columns=['Python' , 'NumPy' , 'Pandas' ]) df['Python' ].transform([np.sqrt, np.exp]) def convert (x ): if x.mean() > 5 : x *= 10 else : x *= -10 return x df.transform({'Python' :convert,'NumPy' :np.max ,'Pandas' :np.min })
3. 异常值检测和过滤
1 2 3 4 df.describe() df.describe([0.3 , 0.4 , 0.5 , 0.9 , 0.99 ]) df.describe([0.3 , 0.4 , 0.5 , 0.9 , 0.99 ]).T
df.std() : 可以求得DataFrame对象每一列的标准差
1 2 3 4 5 6 7 8 9 10 df4 = df.copy() df4 df4.drop('鲁班' ) df4.drop('Java' , axis=1 ) df4.drop(index='鲁班' ) df4.drop(columns='H5' ) df4.drop(columns=['Java' , 'Pandas' ])
1 2 3 4 5 6 7 8 9 index = ['鲁班' , '张三丰' , '张无忌' , '杜甫' , '李白' ] columns = ['Python' , 'Java' , 'H5' , 'Pandas' ] data = np.random.randint(0 , 10 , size=(5 , 4 )) df = pd.DataFrame(data=data, index=index, columns=columns) df df['Python' ].unique()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 df.query('Python == 5' ) df.query('Python > 5' ) df.query('Python==5 and Java==5' ) df.query('Python==5 & Java==5' ) df.query('Python==5 or Java==6' ) df.query('Python==5 | Java==6' ) n = 5 df.query('Python > @n' ) df.query('Python in [3, 4, 5, 6]' ) m = [3 , 4 , 5 , 6 ] df.query('Python in @m' )
df.sort_values(): 根据值排序
df.sort_index(): 根据索引排序
1 2 3 4 5 6 7 8 9 10 11 12 13 index = ['鲁班' , '张三丰' , '张无忌' , '杜甫' , '李白' ] columns = ['Python' , 'Java' , 'H5' , 'Pandas' ] data = np.random.randint(0 , 100 , size=(5 , 4 )) df = pd.DataFrame(data=data, index=index, columns=columns) df df.sort_values('Python' ) df.sort_values('Python' , ascending=False ) df.sort_values('鲁班' , axis=1 ) df.sort_index(ascending=True , axis=1 )
练习:
新建一个形状为10000*3的标准正态分布的DataFrame,去除掉所有满足以下情况的行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 df = pd.DataFrame(np.random.randn(10000 , 3 )) df.head() df.std() df.abs () cond = df.abs () > df.std() * 3 cond cond2 = cond.any (axis=1 ) cond2 df.loc[~cond2]
4. 抽样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 df2.take([4 , 1 , 2 , 3 , 0 ]) df2.take([1 , 0 , 2 , 3 , 4 , 5 , 6 ], axis=1 ) np.random.permutation([0 , 1 , 2 , 3 , 4 , 5 ]) df2.take(np.random.permutation([0 , 1 , 2 , 3 , 4 ])) np.random.randint(0 , 10 , size=10 ) df2.take(np.random.randint(0 , 5 , size=5 ))
八、Pandas数学函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 df = pd.DataFrame(data=np.random.randint(0 ,100 ,size = (20 ,3 ))) df.count() df.max () df.min () df.median() df.sum () df.mean(axis=1 ) df[0 ].value_counts() df.cumsum() df.cumprod() df.var() df.std()
其他数学函数
协方差
- 两组数值中每对变量的偏差乘积的平均值
- 协方差>0 : 表式两组变量正相关
- 如果两个变量的变化趋势一致,也就是说如果其中一个大于自身的期望值时另外一个也大于自身的期望值,那么两个变量之间的协方差就是正值;
- 协方差<0 : 表式两组变量负相关
- 如果两个变量的变化趋势相反,即其中一个变量大于自身的期望值时另外一个却小于自身的期望值,那么两个变量之间的协方差就是负值。
- 协方差=0 : 表式两组变量不相关
相关系数
相关系数r = X与Y的协方差 / (X的标准差 * Y的标准差)
相关系数值的范围在-1和+1之间
r>0为正相关,r<0为负相关。r=0表示不相关
r 的绝对值越大,相关程度越高
两个变量之间的相关程度,一般划分为四级:
如两者呈正相关,r呈正值,r=1时为完全正相关;
如两者呈负相关则r呈负值,而r=-1时为完全负相关,完全正相关或负相关时,所有图点都在直线回归线上;点分布在直线回归线上下越离散,r的绝对值越小。
相关系数的绝对值越接近1,相关越密切;越接近于0,相关越不密切。
当r=0时,说明X和Y两个变量之间无直线关系。
通常|r|大于0.8时,认为两个变量有很强的线性相关性。
1 2 3 4 5 6 7 8 9 df.cov() df[0 ].cov(df[1 ]) df.corr() df.corrwith(df[2 ])
协方差: C o v ( X , Y ) = ∑ 1 n ( X i − X ‾ ) ( Y i − Y ‾ ) n − 1 Cov(X,Y) = \frac{\sum\limits_1^n(X_i - \overline{X})(Y_i - \overline{Y})}{n-1} C o v ( X , Y ) = n − 1 1 ∑ n ( X i − X ) ( Y i − Y )
相关性系数:r ( X , Y ) = C o v ( X , Y ) V a r [ X ] ∗ V a r [ Y ] r(X,Y) = \frac{Cov(X,Y)}{\sqrt{Var[X]*Var[Y]}} r ( X , Y ) = Va r [ X ] ∗ Va r [ Y ] C o v ( X , Y )
九、 数据分组聚合
数据聚合是数据处理的最后一步,通常是要使每一个数组生成一个单一的数值。
分组
数据聚合处理:
分组:先把数据分为几组
用函数处理:为不同组的数据应用不同的函数以转换数据
合并:把不同组得到的结果合并起来
数据分类处理的核心: groupby()函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 df = pd.DataFrame( { 'color' : ['green' , 'green' , 'yellow' , 'blue' , 'blue' , 'yellow' , 'yellow' ], 'price' : [4 , 5 , 3 , 2 , 7 , 8 , 9 ] } ) df df.groupby(by='color' ) df.groupby(by='color' ).groups df.groupby(by='color' ).sum ()
分组聚合练习:
假设菜市场张大妈在卖菜,有以下属性:
菜品(item):萝卜,白菜,辣椒,冬瓜
颜色(color):白,青,红
重量(weight)
价格(price)
要求以属性作为列索引,新建一个ddd
对ddd进行聚合操作,求出颜色为白色的价格总和
对ddd进行聚合操作,求出萝卜的所有重量以及平均价格
使用merge合并总重量及平均价格
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ddd = pd.DataFrame( data={ "item" : ["萝卜" ,"白菜" ,"辣椒" ,"冬瓜" ,"萝卜" ,"白菜" ,"辣椒" ,"冬瓜" ], 'color' :["白" ,"青" ,"红" ,"白" ,"青" ,"红" ,"白" ,"青" ], 'weight' : [10 ,20 ,10 ,10 ,30 ,40 ,50 ,60 ], 'price' : [0.99 , 1.99 , 2.99 , 3.99 , 4 , 5 , 6 ,7 ] } ) ddd ddd.groupby('color' )['price' ].sum () ddd.groupby('color' )[['price' ]].sum () ddd.groupby('color' )[['price' ]].sum () .loc[['白' ]] df1 = ddd.groupby('item' )[['weight' ]].sum () df2= ddd.groupby('item' )[['price' ]].mean() df1.merge(df2, left_index=True , right_index=True )
十、Pandas加载数据
csv数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 data = np.random.randint(0 ,50 ,size=(10 ,5 )) df = pd.DataFrame(data=data, columns=['Python' ,'Java' ,'Go' ,'C' ,'JS' ]) df.to_csv('data.csv' , sep=',' , header=True , index=True ) pd.read_csv('data.csv' , sep=',' , header=[0 ], index_col=0 ) pd.read_table('data.csv' , sep=',' , header=[0 ], index_col=0 )
excel数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 data = np.random.randint(0 , 50 , size=(10 ,5 )) df = pd.pDataFrame(data=data, columns=['Python' ,'Java' ,'Go' ,'C' ,'JS' ]) df.to_excel('data.xls' , sheet_name='sheet1' , header=True , index=False ) pd.read_excel('data.xls' , sheet_name=0 , header=0 , names=list ('ABCDE' ), index_col=1 )
MySQL数据
需要安装pymysql
需要安装sqlalchemy:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 from sqlalchemy import create_engine data = np.random.randint(0 ,150 ,size=(150 ,3 )) df = pd.DataFrame(data=data, columns=['Python' ,'Pandas' ,'PyTorch' ]) conn = create_engine('mysql+pymysql://root:123456@localhost/db' ) df.to_sql('score' , conn, index=False , if_exists='append' ) pd.read_sql('select * from score' , conn, index_col='Python' )
十一、Pandas分箱操作
分箱操作就是将连续型数据离散化。
分箱操作分为等距分箱和等频分箱。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 data = np.random.randint(0 ,150 ,size=(150 ,3 )) df = pd.DataFrame(data=data, columns=['Python' ,'Pandas' ,'PyTorch' ]) df.Python.values pd.cut(df.Python, bins=4 ) pd.cut(df.Python, bins=[0 , 30 , 60 , 80 , 100 ], right=False , labels=['D' ,'C' ,'B' ,'A' ]) pd.qcut(df.Python, q=4 , labels=['差' , '中' , '良' , '优' ])
十二、Pandas绘图
Series和DataFrame都有一个用于生成各类图表的plot方法
Pandas的绘图是基于Matplotlib, 可以快速实现基本图形的绘制,复杂的图形还是需要用Matplotlib
常见可视化图形:
折线图
条形图/柱形图
饼图
散点图
箱型图
面积图
直方图
1、折线图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 s = pd.Series([100 , 200 , 300 , 200 , 150 , 400 , 250 ]) s.plot() x = np.arange(0 , 2 *np.pi, 0.1 ) y = np.sin(x) s = pd.Series(data=y, index=x) s.plot() data = np.random.randint(50 , 100 , size=(5 , 6 )) index = ['1st' , '2nd' , '3th' , '4th' , '5th' ] columns = ['Jeff' , 'Jack' , 'Rose' , 'Lucy' , 'Lily' , 'Bob' ] df = pd.DataFrame(data=data, index=index, columns=columns) df.plot()
2、条形图/柱形图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 df = pd.DataFrame(data=np.random.rand(10 ,4 )) df.plot.bar(stacked=True ) s = pd.Series(data=[100 , 110 , 130 , 200 ]) s.index = ['Jeff' , "千锋" , 'Python' , 'Rose' ] s.plot(kind='bar' ) s.plot(kind='barh' ) data = np.random.randint(0 , 100 , size=(4 , 3 )) index = list ('ABCD' ) columns = ['Python' , 'C' , 'Java' ] df = pd.DataFrame(data=data, index=index, columns=columns) df.plot(kind='bar' ) df.plot(kind='barh' )
3、饼图
1 2 3 4 5 6 7 8 df = pd.DataFrame(data=np.random.rand(4 ,2 ), index=list ('ABCD' ), columns=['Python' ,'Java' ]) df.plot.pie(subplots=True , figsize=(8 ,8 ), autopct='%.1f%%' )
4、散点图
散点图是观察两个一维数据数列之间的关系的有效方法,DataFrame对象可用
1 2 3 4 5 6 7 8 9 10 11 data = np.random.normal(size=(1000 , 2 )) df = pd.DataFrame(data=data, columns=list ('AB' )) df.head() df.plot(kind='scatter' , x='A' , y='B' ) df.plot.scatter(x='A' , y='B' )
5、面积图
1 2 3 df = pd.DataFrame(data=np.random.rand(10 , 4 ), columns=list ('ABCD' )) df.plot.area(stacked=True )
6、箱型图
1 2 3 4 5 df = pd.DataFrame(data=np.random.rand(10 , 5 ), columns=list ('ABCDE' )) df.plot.box() df.plot(kind='box' )
7、直方图
1 2 3 4 5 6 7 8 9 df = pd.DataFrame({'A' : np.random.randn(1000 ) + 1 , 'B' : np.random.randn(1000 ), 'C' : np.random.randn(1000 ) - 1 }) df.plot.hist(alpha=0.5 ) df.plot.hist(stacked=True ) df['A' ].plot(kind='hist' ) df.plot(kind='hist' )