Python数据分析

NumPy


NumPy简介

NumPy是一个开源的Python科学计算基础库

  • 一个强大的N维数据数组对象 ndarray
  • 广播功能函数
  • 线性代数,傅里叶变换,随机数生成等功能


NumPySciPyPandas等数据处理或科学计算库的基础


数据的维度

维度:是一组数据的组织形式

一维数据

  • 定义:由对等关系的有序或无序数据构成,采用线性方式组织
  • 有序一维结构:列表(list[ ]),元组( tuple( ) ),数组
  • 无序一维结构:字典(dict{ : }),集合(set{ })


二维数据

  • 定义:二维数据由多个一维数据构成,是一维数据的组合
  • python中,列表的元素也可以是另外一个列表,这样的嵌套就形成了一个二维数据


高维数据

  • 定义:python中,字典就表示的是高维数据,由键值对存储信息

数组对象 ndarray

定义

数组:是一种一维有序数据结构,要求数据结构里的所有数据类型必须相同

ndarray:就是NumPy库所提供的一个多维数组对象,要求所有元素类型相同,数据的下标从0开始

ndarray.array()函数:生成一个ndarray数组,是[ ]形式,元素由空格分割

1
2
3
4
5
6
ndarray.array([[1,2,3],[4,5,6]])  
"""
创建了一个二维数组:
[[1 2 3]
[5 4 3]]
"""


Python中虽然有数据结构list存储有序数据,但是其不支持矢量化计算,运算效率很低

Numpy库提供了很多用于矢量化运算的函数和方法。

矢量化运算是指对数组中的每个元素进行相同的操作,而不需要使用循环。这样可以提高代码的效率和简洁性。


以下举例说明NumPy相比list的优势:

假设A和B是元素个数相同的数组,求$A^2+B^3$ :

在使用NumPy前,需要声明要引入Numpy这个包,并可以重命名为np这个简写

image-20231028200932805


可以看到,用list计算,需要经过循环,而引入NumPy计算,可以直接计算得出结果


对象的属性

轴(axis):保存数据的维度 秩(rank):轴的数量

假设我们通过np.array()函数生成了一个ndarray对象,命名为a

属性 说明
a.ndim 秩,即维度的数量,或者说,数组的行数n
a.shape 对象的尺度,数组的n行m列
a.size 元素的个数,相当于shape中n*m的值
a.dtype 元素类型
a.itemsize 每个元素的大小,以字节为单位
a.T a数组的转置


例:

1
2
3
4
5
6
7
8
9
import numpy as np
a=np.array([[1,2,3],[5,4,3]])
print(a) # 输出数组
print(a.ndim) #输出数组的维度
print(a.shape) #输出数组的尺度
print(a.size) #输出元素个数
print(a.dtype) #输出元素类型
print(a.itemsize) #输出元素大小
print(a.T) #输出数组的转置
1
2
3
4
5
6
7
8
9
10
[[1 2 3]
[5 4 3]]
2 #维度为2
(2, 3) # 2行3列数组
6 #个数为6
int32 #元素是int32类型
4 #元素大小为4字节
[[1 5]
[2 4]
[3 3]]

数据类型

数据类型 说明
bool 布尔类型,True或False
int8 字节长度的整数,取值:[-128,127]
int16 16位长度整数,取值在$[-2^{15}, 2^{15}-1]$
int32 32位长度整数,取值在$[-2^{31}, 2^{31}-1]$
int64 64位长度整数,取值在$[-2^{63}, 2^{63}-1]$
uint8 8位无符号整数,取值在[0,255]
uint16 16位无符号整数,取值在$[0,2^{16}-1]$
uint32 32位无符号整数,取值在$[0,2^{32}-1]$
float16 16位半精度浮点数:1位符号位,5位指数,10位尾数
complex64 复数类型,实部和虚部都是32位浮点数

Python基本语法只能支持整数,浮点数和复数,ndarray所支持的数据类型更加丰富


创建

一共4种方法

  1. 从Python中的列表,元组等类型创建ndarray数组
  2. 使用Numpy中函数创建ndarray数组,如:arrange,ones等
  3. 从字节流中创建
  4. 从文件中读取特定格式


  • Python中的列表,元组等类型创建ndarray数组

使用Numpy中的array函数,a=np.array(list/tuple,dtype=np.int16),表示将列表/元组转换为ndarray数组,数据类型是int16

如果不指定dtype的话,Numpy会根据数据情况关联一个dtype类型

1
x=np.array([1,2,3])  #从列表中创建数组


  • 使用Numpy中函数创建ndarray数组

np.arrange(n)函数:类似range()函数,返回ndarray类型,元素从0到n-1

1
2
3
print(np.arange(10))

#输出:[0 1 2 3 4 5 6 7 8 9]


np.ones(shape)函数:根据shape生成一个全1数组,shape是元组类型,用于指定数组的行列数

1
2
3
4
5
print(np.ones((2,2)))
"""
输出:[[1. 1.] 一个2行2列的全1二维数组
[1. 1.]]
"""


np.zeros(shape)函数:根据shape生成一个全0数组

1
2
3
4
5
print(np.zeros((2,2)))
"""
输出:[[0. 0.] 一个2行2列的全0二维数组
[0. 0.]]
"""


np.full(shape,val)函数:根据shape生成一个数组,每个元素值都是val

1
2
3
4
5
print(np.full((2,2),6))
"""
输出:[[6. 6.] 一个2行2列的全6二维数组
[6. 6.]]
"""


np.eye(n)函数:创建一个$n*n$的单位数组,对角线为1,其余为0

1
2
3
4
5
print(np.eye(2))
"""
输出:[[1. 0.] 一个2行2列的单位矩阵
[0. 1.]]
"""


np.linspace(start,end,num)函数:根据起止数据等间距地填充数据,形成数组

1
2
3
4
print(np.linspace(1,10,5))
"""
输出:[ 1. 3.25 5.5 7.75 10. ]
"""


总结

函数 说明
np.arange(n) 类似range()函数,返回ndarray类型,元素从0 到 n ‐ 1
np.ones(shape) 根据shape生成一个全1数组,shape是元组类型
np.zeros(shape) 根据shape生成一个全0数组,shape是元组类型
np.full(shape,val) 根据shape生成一个数组,每个元素值都是val
np.eye(n) 创建一个正方的n*n单位数组,对角线为1,其余为0
np.linspace() 根据起止数据等间距地填充数据,形成数组

变换

  • 维度变换

ndarray.reshape(shape)方法:不改变数组元素,返回一个shape形状数组,原数组不变

你可以直接在shape里面输入-1,表示该维度的大小应该由数组的总大小和其他维度的大小自动计算得出。

1
2
3
4
5
6
7
8
9
10
11
12
13
x=np.ones((2,3))
print(x)
y=x.reshape(3,2)
print(y)
"""
x是2行3列的数组
[[1. 1. 1.]
[1. 1. 1.]]
y是3行2列的数组
[[1. 1.]
[1. 1.]
[1. 1.]]
"""


ndarray.resize(shape)方法:与reshape功能一致,但修改原数组

1
2
3
4
5
6
7
8
9
10
11
12
13
x=np.ones((2,3))
print(x)
x.resize(3,2)
print(x)
"""
x是2行3列的数组
[[1. 1. 1.]
[1. 1. 1.]]
修改后的x是3行2列的数组
[[1. 1.]
[1. 1.]
[1. 1.]]
"""


ndarray.swapaxes(ax1,ax2)方法:将数组n个维度中的两个维度进行调换

flattern():对数组进行降维,返回折叠后的一维数组,原数组不变

1
2
3
4
5
6
7
8
9
10
11
12
x=np.ones((2,3))
print(x)
y=x.flatten()
print(y)
"""
x是2行3列的数组
[[1. 1. 1.]
[1. 1. 1.]]

y是一维的数组
[1. 1. 1. 1. 1. 1.]
"""


  • 类型变换

ndarray.astype(dtype)方法:会创建一个dytpe类型的新的数组,数据和原数组一致

1
2
a=np.ones((2,2),dtype=np.int)
b=a.astype(np.float)


ndarray.tolist()方法:创建一个列表,列表元素和数组一致

1
2
3
4
5
6
7
8
9
x=np.ones((2,3))
print(x)
lst=x.tolist()
print(lst)
"""
[[1. 1. 1.]
[1. 1. 1.]]
[[1.0, 1.0, 1.0], [1.0, 1.0, 1.0]]
"""


总结:

方法 说明
.reshape(shape) 不改变数组元素,返回一个shape形状的数组,原数组不变
.resize(shape) 与.reshape()功能一致,但修改原数组
.swapaxes(ax1,ax2) 将数组n个维度中两个维度进行调换
.flatten() 对数组进行降维,返回折叠后的一维数组,原数组不变

运算

数组与标量之间的运算作用于数组的每一个元素

1
2
3
4
5
6
7
8
9
a=np.arrange(10).reshape(2,5)
print(a)
a=a*2
print(a)
"""
[[0 1 2 3 4]
[5 6 7 8 9]]
[[ 0 2 4 6 8]
[10 12 14 16 18]]

可以看到,每个元素都乘以2了


一元函数

函数 说明
np.sort(x) 排序,并返回一个排序后的数组
np.abs(x) 计算数组各元素的绝对值
np.sqrt(x) 计算数组各元素的平方根
np.square(x) 计算数组元素各元素的平方
np.log(x) 计算数组各元素的自然对数
np.rint(x) 计算数组各元素的四舍五入的值
np.cos(x) 计算数组各元素的余弦函数
np.exp(x) 计算数组各元素的指数值
np.sign(x) 计算数组各元素的符号值 1,0,-1


二元函数

函数 说明
+ - * / 两个数组各元素进行对应运算
@ 两个数组进行矩阵乘法
np.power(x,y) 求元素的幂
np.maximum(x,y) 求元素的最大值
np.mod(x,y) 元素级的模运算
np.copysign(x,y) 将数组y中各元素符号赋值给x
> < == != 算术比较,比产生一个布尔型数组


这里讲一下元素乘法*和矩阵乘法@之间的区别

1
2
3
4
5
6
7
8
9
import numpy as np

X = np.array([[1, 2, 3], [4, 5, 6]])
theta = np.array([7, 8, 9])
print(X @ theta) # 输出:[ 50 122]
print(X * theta)
# 输出:
# [[ 7 16 27]
# [28 40 54]]

对于X @ theta(矩阵乘法),结果是一个一维数组,其元素是X的每一行和theta的点积:这里,50 = 1*7 + 2*8 + 3*9122 = 4*7 + 5*8 + 6*9

对于X * theta(元素级别的乘法),结果是一个二维数组,其元素是Xtheta的对应元素的乘积:这里,第一行[7, 16, 27][1, 2, 3][7, 8, 9]的元素级别的乘积,第二行[28, 40, 54][4, 5, 6][7, 8, 9]的元素级别的乘积。


矩阵

ndarray中的array只是数组,进行矩阵运算,比如求逆矩阵之类的,很复杂,将ndarrayarray数组转换为matrix矩阵形式,可以很快的求解逆矩阵

np.matrix()方法:创建方法和np.array()类似


matrix对象有如下属性:

属性 说明
I 返回矩阵的逆矩阵,必须是方阵
H 返回矩阵的共轭转置矩阵,必须是方阵
T 返回矩阵的转置矩阵
A 返回矩阵的数组视图

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
m=np.matrix([[1,2],[3,4]])
print(m.A) #展示矩阵
print(m.T) #求矩阵m的转置
print(m.I) #求矩阵m的逆矩阵

"""
[[1 2]
[3 4]]
[[1 3]
[2 4]]
[[-2. 1. ]
[ 1.5 -0.5]]
"""

修改

插入

np.insert(x,place,element,axis) 函数:

  • x:被插入元素的数组名称
  • place:插入的位置
  • element:插入的元素
  • axis:指定插入的轴(维度),如果是0,表示按行删除;如果是1,表示按列删除

最后会返回一个新的数组

1
2
3
4
5
6
7
A = np.array ([[1, 2, 3], [6, 7, 8]])
B = np.insert (A, 2, [4, 5], axis=1)
print (B)
"""
[[1 2 4 3]
[6 7 5 8]]
"""

具体到例子中来,A表示要被插入的数组,2表示插入的位置第2个,[4,5]表示插入的元素,而最后的axis=1表示,在第1个维度上插入,也就是列,所以最后会把[4,5]插入到第2列之后去

再写一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
A=np.arange(6).reshape((2,3))
print(A)
B=np.zeros((1,3))
C=np.insert(A,0,B,0)
print(C)
"""
[[0 1 2]
[3 4 5]]
[[0 0 0]
[0 1 2]
[3 4 5]]
"""

np.insert(A,0,B,0)表示,把B插入到A中,在第0个位置,并且维度是0,也就是第0行



拼接

np.concatenate((tuple),axis) 函数:

  • tuple:要连接的数组的元组(),如果是(a,b),代表将a和b连接在一起
  • axis:指定连接的维度
1
2
3
4
5
6
7
8
A = np.array ([[1, 2, 3], [6, 7, 8]])
B = np.array ([[4], [5]])
C = np.concatenate ((A, B), axis=1)
print (C)
"""
[[1 2 3 4]
[6 7 8 5]]
"""

np.concatenate ((A, B), axis=1)表示,要把数组A和B链接起来,并且维度是1,也就是列



删除

np.delete(x,place,axis)

  • x :要删除元素的数组
  • place:删除的位置或索引
  • axis:指定按行或列删除
1
2
3
4
5
6
7
8
A = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
A = np.delete(A, 1, axis=1) # 删除第二列
print(A)
"""
[[1 3]
[4 6]
[7 9]]
"""



分割

在使用函数之前,使用python自带的切片语法是最方便的:

1
2
3
4
5
6
7
data=np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(data)
"""
[[1 2 3]
[4 5 6]
[7 8 9]]
"""

data[a:b,c:d]:切片的语法,其中a,b,c,d代表了行和列的起始和终止的位置,也就是取[a,b)行,[c,d)列,注意是左闭右开的范围,如果a,c省略,则默认是最开始的位置,b,d省略了,这默认是最末尾的位置


例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
data=np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
a=data[0:1,1:3]
b=data[:2,2:]
c=data[:,0:1]
print(data)
print(a)
print(b)
print(c)
"""
[[1 2 3]
[4 5 6]
[7 8 9]]

a:[[2 3]]

b:[[3]
[6]]

c:[[1]
[4]
[7]]

"""


data[0:1,1:3]表示的是:取[0,1)行,切片第0行在数组表示中也就是第1行,取[1,3)列,也就是第2,3列,那么结果是第1行的第2,3列的元素集合

data[:2,2:]表示的是:取[0,2)行,也就是数组的第1,2行,取[2,3)列,也就是第3列,那么结果是第1,2行和第3列的元素结合

c=data[:,0:1]表示的是:取[0,3)行,也就是所有行,0表示第1列,所以会取出第1列的所有元素


可以观察到,b和c都是二维数组,保留了其二维结构,如果我们想要取出列后,将其变成1维数组,那么可以省略后一个冒号:

以下是例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
data=np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
c=data[:,0:1]
d=data[:,0]
print(data)
print(c)
print(d)
"""
[[1 2 3]
[4 5 6]
[7 8 9]]
c:[[1]
[4]
[7]]

d: [1 4 7]
"""

可以看到,在省略后一个冒号:之后,提取出来的列变为了1维数组,更方便计算


np.split(x,place,axis)

  • x:要分割的数组
  • place:分割的位置或份数
  • axis:指定分割的维度
1
2
3
4
A = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
B = np.split(A, 3, axis=0) # 按行分割
print(B[1]) # 打印第二行
#结果是:[[4 5 6]]

np.split(A, 3, axis=0)的意思是,按行分割,把数组切割成3份,形成3个新数组,并把数组装进一个列表B

1
2
3
4
5
A = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
B = np.split(A, [1], axis=0) # 按行分割
print(B[1]) # 打印第二行

#结果是:[array([[1, 2, 3]]), array([[4, 5, 6],[7, 8, 9]])]

np.split(A, [1], axis=0)的意思是,按行分割,在第1行和第2行之间切割,把数组分成了2部分,装入列表B中


也可以使用hsplit函数切割横向,vsplit函数切割纵向,这样就不用写第三个axis参数了


统计函数

函数 说明
np.sum(a, axis) 根据给定轴axis计算数组a相关元素之和
np.mean(a, axis=None) 根据给定轴axis计算数组a相关元素的算术平均值
np.average(a,axis=None,weights=None) 根据给定轴axis计算数组a相关元素的加权平均值
np.std(a, axis=None) 根据给定轴axis计算数组a相关元素的标准差
np.var(a, axis=None) 根据给定轴axis计算数组a相关元素的方差
np.min(a) max(a) 计算数组a中元素的最小值、最大值
np.ptp(a) 计算数组a中元素最大值与最小值的差
np.median(a) 计算数组a中元素的中位数(中值)
np.unravel_index(index, shape) 根据shape将一维下标index转换成多维下标


以下举例说明用法:

np.sum(a,axis):用于计算数组元素之和的函数

  • a是要求和的数组,可以是一维或多维的
  • axis是指定求和的维度,可以是整数或元组,例如0(0,1)
1
2
3
4
5
6
7
8
9
a = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
print(np.sum(a)) #会输出所有元素的和:78
print(np.sum(a,axis=1))
"""
输出一个一维数组[10, 26, 42]
表示第一行的和是10,第二行的和是26,第三行的和是42
"""

注意:numpyaxis=1指定的是行,而在Pandas中,axis=1指定的是列,两者截然相反



随机数函数

numpy中的随机数函数都是基于np.random的方法

函数 说明
rand(d0,d1….dn) 根据d0-dn的范围创建随机数数组,在0到1之间均匀分布
randn(d0,d1….dn) 根据d0-dn的范围创建随机数数组,标准正态分布
seed(s) 随机数种子,s是给定的种子值

print(np.random.randn(2,5))的意思是生成一个2行5列的二维数组,每个元素都是一个服从标准正态分布的随机数。

1
2
[[ 0.75238979 -0.05053056 -0.77662364 -1.4862594   0.55068062]
[ 0.54593743 1.02283708 0.64404996 1.52941035 0.4409481 ]]

补充一个numpy.random.choice(a, size=None, replace=True)函数

  • a:数据范围
    • 如果是数组,表示从中进行随机抽样。
    • 如果是整数,表示范围是 [0, a)
  • size: 输出的大小。如果是整数,表示输出的是一维数组,如果是元组,表示输出的是多维数组。
  • replace: 表示是否允许有放回地抽样。如果为 True,则允许重复抽样,如果为 False,则不允许重复抽样。



Matplotlib

简介

matplotlib是一个Python的绘图库,它可以用来创建各种类型的图表和可视化。它有很多功能和参数,可以让你自定义图形的样式和效果。它也可以和其他的Python库如numpyscipy一起使用,进行科学计算和数据分析。

Matplotlib库由各种可视化类构成,内部结构复杂,受Matlab启发,matplotlib.pyplot是绘制各类可视化图形的命令子库,相当于快捷方式

import Matplotlib.pyplot as plt


plot函数

plot(x, y, format, data=None, **kwargs):是绘制二维图形的一个常用函数,它可以接受多种参数来控制图形的样式和效果

  • x:表示X轴的数据,可以是列表,数组或者其他可迭代的对象
  • y:表示Y轴的数据,可以是列表,数组或者其他可迭代的对象
  • format:是一个可选的字符串,用来指定颜色,字符,标记等
字符串 说明 字符串 说明
‘b’ 蓝色 ‘r’ 红色
‘g’ 绿色 ‘y’ 黄色
‘#008000’ RGB颜色 ‘0.8’ 灰度值
‘-‘ 实线 ‘—‘ 破折线
‘:’ 虚线 ‘’’’ 无线条
‘.’ 点标记 ‘o’ 实心圆
‘v’ 倒三角 ‘^’ 上三角
  • data:是一个可选的参数,用来传入一个对象数据类型,比如字典
  • **kwargs:是一些关键字参数,可以设置第二组或更多的(x,y,format),或者是用来设置图形的其他属性,比如标题,标签,刻度

如果plot函数只有一个列表或数组输入,参数会被当做y轴,x轴以索引自动生成,也就是说,如果你输入一个数组$a=[a_0, a_1, a_2, …, a_n]$,那么plot函数会绘制出n+1个点,它们的坐标分别是$(0, a_0), (1, a_1), (2, a_2), …, (n, a_n)$。然后用线段连接这些点,形成一条曲线

1
2
3
import Matplotlib.pyplot as plt
plt.plot([5,1,3,2,4])
plt.show

image-20231031024211178


输入多个数组会将两个相邻数组看做x,y轴的数据,从而绘制出曲线

1
2
3
4
import Matplotlib.pyplot as plt
import numpy as np
a=np.arange(10)
plt.plot(a,a*1.5,'r',a,a*2.5,'c',,a,a*3.5,'b',a,a*4.5,'g')

image-20231031025635206

实际上,我觉得这样写更好,虽然麻烦一些,但是可读性高:

1
2
3
4
5
6
a=np.arange(10)
plt.plot(a,a*1.5,'r')
plt.plot(a,a*2.5,'c')
plt.plot(a,a*3.5,'b')
plt.plot(a,a*4.5,'g')



文本显示

函数 说明
plt.xlabel() 对 X轴增加文本标签
plt.ylabel() 对 Y轴增加文本标签
plt.title() 对图形整体增加文本标签
plt.grid(bool) True代表显示网格
plt.axis() 规定坐标轴的起始范围
plt.legend() 指定图例的位置和字体大小


这里注意,pyplot默认是无法显示中文的,如果要用中文输出的话,增加一个属性:fontproperties,后面的'SimHei'表示用的是黑体


1
2
3
4
5
6
7
8
9
10
11
a=np.arange(0,5.0,0.02)

plt.xlabel('横轴:时间',fontproperties='SimHei')
plt.ylabel('纵轴:振幅',fontproperties='SimHei')
plt.title('振幅图像',fontproperties='SimHei')
plt.plot(a,np.cos(2*np.pi*a),'r--',label='cosx') #设置图例名字叫cosx
plt.plot(a,np.sin(2*np.pi*a),'b--',label='sinx') #设置图例名字叫sinx
plt.legend(loc='best',fontsize=10) #展示图例,位置为最佳,大小为10
plt.grid('True') # 开启网格
plt.axis([-1,6,-2,2]) #指定坐标轴范围
plt.show()

image-20231031061422811


散点图

直接使用plt.scatter()函数就可以绘制散点图,例:

1
2
plt.scatter(10*np.random.randn(100),10*np.random.randn(100))
plt.show()

image-20231031050028841

生成了100个服从正态分布的随机数,并放大10倍,同时参数为'o',即实心圆点


还有一种面向对象的散点图绘制方法:

1
2
3
fig,ax=plt.subplots()
ax.scatter(10*np.random.randn(100),10*np.random.randn(100))
plt.show() # 显示图形窗口

一样可以绘制散点图,实际上,这种方法是官方推荐的办法,因为创建了plt的对象,让操作更加方便

fig,ax=plt.subplots()

  • fig是图形窗口对象,代表整个绘图区域,包括子图、图表标题、轴标签等

  • ax则是子图对象的一个列表,用于设置每个子图的属性和绘制图形

  • subplots()表示创建了一个子图


以下是一些子图对象ax的绘制方法,plt也能直接调用这些方法

方法 说明
ax.plot 曲线图
ax.bar 柱状图
ax.pie 饼状图
ax.scatter 散点图

以散点图scatter为例,解释一下绘制图形时的参数

ax.scatter(x, y, s=None, c=None, marker=None, cmap=None,data,**kwargs)

  • xy是表示横纵坐标的数据,它们可以是列表、数组或其他可迭代的对象。
  • s是表示点的大小的参数,
  • c是表示点的颜色的参数,
  • marker是表示点的形状的参数,
  • cmap是表示颜色映射的参数,
  • data是表示传入对象数据类型的参数,
  • **kwargs是表示其他关键字参数

可以看到,可以调整的参数远比plot函数多


1
2
3
4
5
6
7
8
9
10
11
12
# 创建一个图形窗口和一个子图
fig, ax = plt.subplots()

ax.scatter(10*np.random.randn(50), 10*np.random.randn(50),c='r',s=30)
ax.scatter(10*(np.random.randn(50)+5), 10*(np.random.randn(50)+5),c='g',s=30)

ax.set_title('图表',fontproperties='SimHei')
ax.set_xlabel('X轴',fontproperties='SimHei')
ax.set_ylabel('Y轴',fontproperties='SimHei')

# 显示图形窗口
plt.show()

image-20231031061700412

这里设置标题的方法和plot有所不同,不过差别很小


Pandas

简介

Pandas 是一个用于数据分析的 Python 库,它基于 NumPymatplotlib,提供了高效、易用的数据结构和数据处理工具

Pandas 的主要数据结构是Series(一维数据)和 DataFrame(二维数据),它们可以方便地对数据进行分组、聚合、合并、透视等操作

import pandas as pd



Series类型

定义

Series类型由一组数据及与之相关的数据索引组成

使用方法和NumPy的数组类似,不同之处在于,Series会给数据生成一个索引

image-20231101035942794

s = pd.Series(data, index, name=, dtype=)

  • data:必要的参数,表示数据
  • index:可选的参数,表示数据的索引,默认是从0开始增加
  • name:可选的参数,表示Series的名字
  • dtype:可选的参数,指定数据类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import pandas as pd 

data = [1, 2, 3, 4]
index1 = ("a", "b", "c", "d")
s = pd.Series(data, index1, name="example", dtype=int)
print(s)

"""
输出结果:
a 1
b 2
c 3
d 4
Name: example, dtype: int32
"""

a,b,c,d就是指定的索引,如果不写,那么就是0,1,2,3



创建

Series可以由多种数据类型创建,以下类型比较常见:

  • Python列表:index与列表元素个数一致
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import pandas as pd
data = [1, 2, 3, 4]
index1 = ["a", "b", "c", "d"]
s1 = pd.Series(data) # 使用默认索引
s2 = pd.Series(data, index1) # 使用指定索引
"""
0 1
1 2
2 3
3 4

a 1
b 2
c 3
d 4

"""
  • 标量值:index表达Series类型的尺寸
1
2
3
4
5
6
7
8
9
10
11
import pandas as pd
data = 5
index1 = ["a", "b", "c", "d"]
s5 = pd.Series(data, index1) # 使用标量值作为数据,重复填充到每个索引位置
"""
a 5
b 5
c 5
d 5
"""

  • Python字典:键是索引,值是数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
data = {"a": 1, "b": 2, "c": 3, "d": 4}
s3 = pd.Series(data) # 使用字典的键作为索引
s4 = pd.Series(data, index = ["a", "b", "e"]) # 使用指定索引,只保留字典中的"a"和"b","e"对应的值为NaN

"""
a 1
b 2
c 3
d 4

a 1.0
b 2.0
e NaN
"""
  • 使用其他Series对象作为数据,可以指定索引标签,也可以使用原Series对象的索引
1
2
3
4
5
6
7
8
9
10
import pandas as pd
data = pd.Series([1, 2, 3, 4], index = ["a", "b", "c", "d"])
s6 = pd.Series(data) # 使用原Series对象的索引和数据
s7 = pd.Series(data, index = ["a", "b", "e"]) # 使用指定索引,只保留原Series对象中的"a"和"b","e"对应的值为NaN

"""
a 1.0
b 2.0
e NaN
"""

属性

属性 说明
index 返回 Series 对象的索引,可以是字符串、数字或其他类型
values 返回 Series 对象的数据,以 numpy 数组的形式
dtype 返回 Series 对象的数据类型,可以是 int、float、str
size 回 Series 对象的个数
name 返回 Series 对象的名称,可以自定义或默认为 None
empty 返回一个布尔值,表示 Series 对象是否为空


可以通过Series对象的index属性和values属性直接输出Series中的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import pandas as pd 

data = [1, 2, 3, 4]
index1 = ("a", "b", "c", "d")
s = pd.Series(data, index1)
print(s.index)
print(s.values)
print(s.shape)

"""
Index(['a', 'b', 'c', 'd'], dtype='object')
[1 2 3 4]
4
"""



Index索引

正如上面的代码,执行index属性会返回Series对象的索引类型,类型名称就叫Index类型,Index类型是一个无法修改的类型

index索引有很多函数,方便直接修改索引

方法 说明
.append(idx) 连接另一个Index对象
.diff(idx) 计算差集
.intersection(idx) 计算交集
.union(idx) 计算并集
.delete(loc) 删除loc位置处的元素
.insert(loc,e) 在loc位置增加一个元素e

注意,由于index无法修改,以上操作都会返回一个新的index对象

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
data = [1, 2, 3, 4]
index1 = ("a", "b", "c", "d")
s = pd.Series(data, index1)
"""
a 1
b 2
c 3
d 4
"""
index2 = s.index.insert(1, 'e')
# 使用Index.insert方法在索引的第1个位置插入'e',返回一个新的Index对象
s1 = pd.Series(s, index2)
# 使用新的Index对象创建一个新的Series对象,数据为s的值


"""
a 1.0
e NaN
b 2.0
c 3.0
d 4.0
"""
index3=s1.index.delete(4)
# 使用Index.delete方法在索引的第4个位置删除d,返回一个新的Index对象
s2=pd.Series(s1,index3)
s2
"""
a 1.0
e NaN
b 2.0
c 3.0

"""

操作

不难看出,Series对象本质上是ndarray对象和Python中自带的字典类型的结合体,所以ndarray和字典能用的函数,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
28
data = [8, 9, 5, 4]
index = ("a", "b", "c", "d")
s = pd.Series(data, index)


print(np.square(s)) #输出s的values值的平方
print(s[:3]) #输出s的前三个数据
print(s[s>np.median(s)]) #输出s中比s中位数大的数据

"""
平方后:
a 64
b 81
c 25
d 16
dtype: int64

前2个数据:
a 8
b 9
dtype: int64

比中位数大的数据
a 8
b 9
c 5
dtype: int64
"""

都是经典的ndarray数组操作,Series对象一样适用


1
2
3
4
5
6
7
8
9
10
11
12
13
data = [8, 9, 5, 4]
index = ("a", "b", "c", "d")
s = pd.Series(data, index)
print(s['a']) #字典操作,根据key值寻找value
print(s.get('e')) #利用get方法,输入key值寻找对应的value
print( 5 in s) # 判断5是否在value中

"""
8
None
False

"""



DataFrame类型

定义

DataFrame类型由共用相同索引的一组列组成

image-20231101193850145

DataFrame是一个表格型的数据类型,每列值类型可以不同,既有行索引,也有列索引

可以看到,DataFrame类型类似于excel格式,常用于表达二维数据,但可以表达多维数据



创建

  • 可以从二维的ndarray对象来创建
1
2
3
4
5
6
7
8
9
10
11
12
13
import pandas as pd
import numpy as np
pd.DataFrame(np.arange(10,0,-1).reshape(5,2))
"""
输出结果:
0 1
0 10 9
1 8 7
2 6 5
3 4 3
4 2 1

"""

可以看到,行索引和列索引都是自动生成的,是从0开始的整数


  • 从一维的ndarray对象字典创建
1
2
3
4
5
6
7
8
9
10
dt={'one':pd.Series([1,2,3],index=['a','b','c']),'two':pd.Series([9,8,7,6],index=['a','b','c','d'])}
d=pd.DataFrame(dt)
d
"""
one two
a 1.0 9
b 2.0 8
c 3.0 7
d NaN 6
"""

可以看到,我们用index指定了DataFrame对象的行索引,系统会将字典的key当做是列索引,同时,会自动对齐格式,如果有缺失的项,会用NaN表示空


  • 直接从列表类型的字典创建
1
2
3
4
5
6
7
8
9
10
11
dl={'one':[1,2,3,4],'two':[9,8,7,6]}
d=pd.DataFrame(dl,index=['a','b','c','d'])
d
"""
one two
a 1 9
b 2 8
c 3 7
d 4 6

"""

操作


定位

df.head(n)方法:查看DataFrame对象的前n行,默认是前5行

df.tail(n)方法:查看DataFrame对象的最后n行,默认是后5行


使用df.loc方法和df.iloc方法可以访问并修改DataFrame中的任意行列数据

  • loc是基于标签label)来选择数据,即行索引和列索引的名称。例如,df.loc[‘A’:‘C’, ‘c1’:‘c3’]表示选择行索引为A到C(包含C),列索引为c1到c3(包含c3)的数据
  • iloc是基于位置index)来选择数据,即行索引和列索引的整数位置。例如,df.iloc[1:3, 2:4]表示选择第1行到第3行(不包含第3行),第2列到第4列(不包含第4列)的数据

lociloc实现了ndarray中的切片操作


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
df = pd.DataFrame({'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
'age': [25, 30, 35, 40, 45],
'gender': ['F', 'M', 'M', 'M', 'F'],
'score': [90, 80, 70, 60, 50]})
df.index = ['a1', 'a2', 'a3', 'a4', 'a5']
print(df)

"""
name age gender score
a1 Alice 25 F 90
a2 Bob 30 M 80
a3 Charlie 35 M 70
a4 David 40 M 60
a5 Eve 45 F 50
"""


df.loc['a2':'name']:输出Bob

df.loc[:,'name','gender']:会输出namegender列的所有数据

df.loc['a1:'a3',:]:会输出a1a3列的所有数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
"""
Bob

name gender
a1 Alice F
a2 Bob M
a3 Charlie M
a4 David M
a5 Eve F

name age gender score
a1 Alice 25 F 90
a2 Bob 30 M 80
a3 Charlie 35 M 70


"""


df.iloc[0,2]:会直接输出Charlie

df.iloc[:,[0,-1]]:会输出第1列和最后一列,注意这里的-1表示最后一列

df.iloc[0:3,:]:会输出第1行到第3行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
"""
name score
a1 Alice 90
a2 Bob 80
a3 Charlie 70
a4 David 60
a5 Eve 50

name age gender score
a1 Alice 25 F 90
a2 Bob 30 M 80
a3 Charlie 35 M 70


"""

以上就是如果定位到DataFrame对象中的数据,修改就不必多说了,因为能够定位,就能够修改,比如:

df.iloc[3,1:3]=('55','F','100')

执行该语句会将df中的第4行的第2个数据到第4个数据依次改为55,F,100



插入

DataFrame.insert(loc,column,value)用于在指定位置插入新列,它的主要参数如下:

  • loc - 插入列的索引位置,从0开始
  • column - 新插入列的列名
  • value - 新插入列的值,可以是标量、列表、数组等
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import pandas as pd

data = {'A':[1,2,3], 'B':[4,5,6]}
df = pd.DataFrame(data)

# 在索引位置0的位置插入新列C
df.insert(0, 'C', [7,8,9])

print(df)
"""
C A B
0 7 1 4
1 8 2 5
2 9 3 6
"""

重新索引

df.reindex(index or columns fill_value,method,copy)

  • index or columns :新的行列索引
  • fill_value :如果有缺失值的填充值,默认为NaN
  • method: 填充缺失值的方法,ffill当前值向前填充,bfill向后填充
  • copy:默认为True,生成新的对象,False时,新旧相等不复制


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
df = pd.DataFrame({'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
'age': [25, 30, 35, 40, 45],
'gender': ['F', 'M', 'M', 'M', 'F'],
'score': [90, 80, 70, 60, 50]})

df.index = ['a1', 'a2', 'a3', 'a4', 'a5']

"""
name age gender score
a1 Alice 25 F 90
a2 Bob 30 M 80
a3 Charlie 35 M 70
a4 David 40 M 60
a5 Eve 45 F 50
"""

a=df.reindex(index = ['a2', 'a1', 'a3', 'a4', 'a5'])
b=a.reindex(columns= ['age', 'name', 'gender', 'score'])
b
"""
age name gender score
a2 30 Bob M 80
a1 25 Alice F 90
a3 35 Charlie M 70
a4 40 David M 60
a5 45 Eve F 50

"""

其中a就是df交换了a1a2两行所生成的新对象,b是在a的基础上交换了age列和name列所生成的新对象


reindex可以通过改变Index这一索引类型,从而实现简便的操作,而这也是Pandas数据类型的核心思想


索引的增删

使用Index索引的insertdelete方法可以实现索引的增加或者删除,这在Series类型的Index索引这一小节中有所提及


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
df = pd.DataFrame({'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
'age': [25, 30, 35, 40, 45],
'gender': ['F', 'M', 'M', 'M', 'F'],
'score': [90, 80, 70, 60, 50]})

df.index = ['a1', 'a2', 'a3', 'a4', 'a5']

columns1 = df.columns.delete(2)
# 删除gender列
index1 = df.index.insert(3, 'a6')
# 在第3个位置插入'a6'索引
data1 = df.reindex(index = index1, columns = columns1,fill_value='0')
# 使用新的索引和列,不指定填充方法,默认值为0
data1.iloc[3,0:3]=('Frank','50.0','100.0')
#将第4行,第1个数据到第3个数据依次改为Frank,50,100
data1
"""
name age score
a1 Alice 25.0 90.0
a2 Bob 30.0 80.0
a3 Charlie 35.0 70.0
a6 Frank 50.0 100.0
a4 David 40.0 60.0
a5 Eve 45.0 50.0
"""


删除指定的行或者列,更推荐使用drop方法

drop(name,axis)

  • name:指要删除的行列名称
  • axis:要删除的轴,默认是删除行,如果要删除列,则修改为1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
df = pd.DataFrame({'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
'age': [25, 30, 35, 40, 45],
'gender': ['F', 'M', 'M', 'M', 'F'],
'score': [90, 80, 70, 60, 50]})

df.index = ['a1', 'a2', 'a3', 'a4', 'a5']

df.drop('age',axis=1) #删除age列

"""

name gender score
a1 Alice F 90
a2 Bob M 80
a3 Charlie M 70
a4 David M 60
a5 Eve F 50
"""



运算

算术运算是根据行列索引,补齐后运算,运算默认产生浮点数,补齐时缺项填充NaN

可以直接使用+-*/进行运算,不过推荐使用算术方法

方法 说明
.add(d,**argws)
.sub(d,**argws)
.mul(d,**argws)
.div(d,**argws)


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
import pandas as pd
import numpy as np

# 创建两个DataFrame对象
df1 = pd.DataFrame(np.arange(9).reshape(3, 3),
columns=['A', 'B', 'C'])
df2 = pd.DataFrame(np.arange(12).reshape(4, 3),
columns=['A', 'B', 'D'])
print(df1)
print(df2)
"""
输出:
A B C
0 0 1 2
1 3 4 5
2 6 7 8
A B D
0 0 1 2
1 3 4 5
2 6 7 8
3 9 10 11
"""
# 使用方法进行算术运算,指定填充值为0
print(df1.add(df2, fill_value = 0)) # 相加,用0替换NaN
print(df1.mul(df2, fill_value = 0)) # 相乘,用0替换NaN
"""
输出:
A B C D
0 0.0 2.0 2.0 2.0
1 6.0 8.0 5.0 5.0
2 12.0 14.0 8.0 8.0
3 9.0 10.0 0.0 11.0

A B C D
0 0.0 1.0 0.0 0.0
1 9.0 16.0 0.0 0.0
2 36.0 49.0 0.0 0.0
3 0.0 0.0 0.0 0.0


"""



数据排序

sort_index(ascending,axis)方法:按照索引(行或列)的顺序进行排序

  • ascending:默认是升序排列True,如果是降序排列,可改成asceding=False
  • axis:默认是按行索引排序,如果要改成列索引,可改成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
import pandas as pd
# 创建一个DataFrame对象
df = pd.DataFrame({'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
'age': [25, 30, 35, 40, 45],
'gender': ['F', 'M', 'M', 'M', 'F'],
'score': [90, 80, 70, 60, 50]})
df
"""
name age gender score
0 Alice 25 F 90
1 Bob 30 M 80
2 Charlie 35 M 70
3 David 40 M 60
4 Eve 45 F 50
"""
df.sort_index(axis=1, ascending=False)
# 按照列索引降序排序,即按字母表顺序降序
"""
score name gender age
0 90 Alice F 25
1 80 Bob M 30
2 70 Charlie M 35
3 60 David M 40
4 50 Eve F 45
"""


sort_values(by=name,ascending),根据values的值进行排序,默认是升序排列

  • by:后面添加要排序的行列的名称
  • ascending:选择是升序还是降序
1
2
3
4
5
6
7
8
9
10
df.sort_values(by='name', ascending=False)
# 按照name列降序排序
"""
name age gender score
4 Eve 45 F 50
3 David 40 M 60
2 Charlie 35 M 70
1 Bob 30 M 80
0 Alice 25 F 90
"""



CSV文件

定义

CSV文件是一种存储和表示表格数据的纯文本文件,它的全称是逗号分隔值(Comma-Separated Values)

CSV文件的特点是每行代表一条记录,每个数据用逗号分隔,如果数据中含有逗号,就用引号包围。

image-20231030044615325



保存

to_csvpandas库中的一个方法,它可以将一个DataFrameSeries对象写入到一个csv文件中,或者返回一个csv格式的字符串

pd.to_csv(path,sep,na_rep,columns,header,index,index_label)

  • path:这个参数指定了写入的目标,可以是一个文件路径,一个文件对象,或者None
  • sep:这个参数指定了字段之间的分隔符,默认是逗号(,)
  • na_rep:这个参数指定了缺失值的表示方式,默认是空字符串(‘’)。可以根据需要修改为其他字符串,例如’NA’或’NULL’
  • columns:这个参数指定了要写入的列,可以是一个列名的列表。如果不指定,那么会写入所有的列
  • header:这个参数指定了是否写入列名,可以是一个布尔值或者一个字符串的列表。如果是True,那么会写入默认的列名。如果是False,那么不会写入列名
  • index:这个参数指定了是否写入行索引,可以是一个布尔值。如果是True,那么会写入行索引。如果是False,那么不会写入行索引
  • index_label:这个参数指定了行索引的列名,可以是一个字符串或者一个字符串的列表。如果是None,那么会使用默认的行索引名。如果是False,那么不会写入行索引名


1
2
3
4
5
6
7
8
9
10
import pandas as pd
df = pd.DataFrame({'name': ['Alice', 'Bob', 'Charlie'], 'age': [25, 30, 35], 'gender': ['F', 'M', 'M']})
"""
name age gender
0 Alice 25 F
1 Bob 30 M
2 Charlie 35 M
"""
df.to_csv('example.csv', sep=',', na_rep='NA', index=False, header=True)

表示:将这个DataFrame对象写入到一个csv文件中,文件名是example.csv,分隔符是逗号(,),缺失值表示为’NA’,不写入行索引,但写入列名


最后会得到内容如下表的example.csv文件

name age gender
Alice 25 F
Bob 30 M
Charlie 35 M



读取

read_csvPandas库中的一个函数,它可以从一个文件或网址中读取逗号分隔值(csv)格式的数据,返回一个DataFrame对象

pd.read_csv(path,sep,header,names,index_col,usecol,dtype)

  • path:文件或网址的位置,可以是任何有效的字符串路径或URL
  • sep:分隔符,用来指定数据中的每个值之间的字符或正则表达式,默认为逗号,如果`sep=None,会从第一行有效的数据中推断出分隔符
  • header:列号或列号的序列,用来指定包含列名的行和数据的开始位置,从0开始计数,默认把第一行看做列名
  • names:列名的列表或字典,用来自定义列名,如果传入了names,那么header=None,不使用文件中的任何行作为列名,如果传入了字典,那么键是列的索引,值是列的名称
  • index_col:行号或行号的序列,用来指定作为行索引的列,从0开始计数,如果为None,那么没有行索引,只有默认的数字索引
  • usecols:列号或列名的列表,用来指定要读取的列,从0开始计数,可以传入一个函数来过滤列
  • dtype:数据类型,用来指定每列数据的类型,可以是一个类型
1
df = pd.read_csv('example.csv', sep=',', header=None,name=['x','y'], index_col=None)

表示:将这个csv文件读取为一个DataFrame对象,文件名是data.csv,分隔符是逗号,不将第一行看做是列名,自定义列名为xy,不使用任何列作为行索引



统计分析

Pandas数据类型可以直接使用NumPy中的统计函数

Pandas自带了describe()函数,可以很方便的展示信息

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 np
import pandas as pd

# 创建一个NumPy数组
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# 将NumPy数组转换为Pandas的DataFrame对象
df = pd.DataFrame(arr,columns=['A','B','C'],index=['A','B','C'])

"""

A B C
A 1 2 3
B 4 5 6
C 7 8 9
"""
# 调用describe函数,返回一个新的DataFrame对象,显示统计结果
df.describe()
# 输出:
A B C
count 3.0 3.0 3.0
mean 4.0 5.0 6.0
std 3.0 3.0 3.0
min 1.0 2.0 3.0
25% 2.5 3.5 4.5
50% 4.0 5.0 6.0
75% 5.5 6.5 7.5
  • count: 非空值的数量,即有效的观测值的个数。
  • mean: 所有数值的平均值,即算术平均值。
  • std: 所有数值的标准差,即数据的离散程度。
  • min: 最小值,即数据的最低点。
  • 25%: 第一四分位数,即数据的下四分位数,表示25%的数据低于或等于这个值。
  • 50%: 第二四分位数,即数据的中位数,表示50%的数据低于或等于这个值。
  • 75%: 第三四分位数,即数据的上四分位数,表示75%的数据低于或等于这个值。
  • max: 最大值,即数据的最高点。


相关性分析

方法 说明
.cov() 计算协方差矩阵
.corr(method,min_periods) 计算相关系数矩阵

method:相关性计算方法,可选值为’pearson’(默认)、‘kendall’和’spearman’。

  • pearson:表示使用皮尔逊相关系数衡量相关性,该系数是最常用的相关性度量,适用于线性相关的情况;

  • kendall:使用肯德尔相关系数衡量相关性,适合非线性但单调递增或递减的相关关系;

  • spearman:使用斯皮尔曼相关系数衡量相关性,也适用于非线性但单调递增或递减的相关关系。

min_periods:计算相关系数所需的最小观测值数,即样本量,缺失值不计入样本量。


Plot绘图

Pandasplot函数是一个用来绘制DataFrameSeries对象中的数据的方法,它可以根据不同的参数选择绘制的图形类型,如折线图、柱状图、饼图、散点图等,它也可以根据数据的索引和列名自动添加图例和标签,方便数据的可视化和分析。

可以说:Pandas中的plot函数是基于matplotlib库的一个封装

DataFrame.plot(x=None, y=None, kind=‘line’, ax=None, layout=None, figsize=None,label=None, color=None,title=None, grid=None, legend=True)

  • xy:表示标签或者位置的名称(必须),用来指定显示的索引,默认为None
  • kind:表示绘图的类型,默认为line,折线图,还可以选择其他类型,如柱状图bar,直方图hist,饼状图pie散点图scatter
  • ax:表示matplotlib的子图对象,用来在同一个画布上绘制多个图形,默认为None
  • layout:表示子图的行列布局,(rows, columns)的形式,默认为None
  • figsize:表示图形的尺寸大小,(width, height)的形式,默认为None
  • label:这个参数的值将作为图例中的标签
  • color:这个参数的值将决定图表的颜色
  • title:表示图形的标题,字符串类型,默认为None
  • grid:表示是否显示网格线,默认为None
  • legend:表示是否显示图例,默认为True


1
2
3
4
x1 = 10*np.random.randn(50)
y1 = 10*np.random.randn(50)
df = pd.DataFrame({'x1': x1, 'y1': y1})
df.plot(kind='scatter', x='x1', y='y1',title='graph',label='Group 1',grid=True,legend=True)

这段代码的意思是在df中创建一个散点图,其中x1是x轴,y1是y轴,标题是'graph',图例的标签是'Group 1',并且显示网格和图例。这个图将显示dfx1y1列的数据分布

image-20231105082024530

Pandasmatplotlib中的plot函数比较

matplotlib Pandas
数据输入 可以接受各种格式的数据,包括列表、numpy数组、pandas对象等 必须是DataFrame或Series对象中的数据
灵活性 提供了更多的灵活性,可以让你更加精细地控制图形的各个方面 灵活性较低,但对于基本的图形创建非常方便
代码复杂性 代码可能会比较复杂,特别是对于复杂的图形 代码通常更简洁,特别是当数据已经存储在DataFrame中时
适用情况 当你需要对数据进行复杂的操作或者转换,或者需要精细地控制图形的各个方面时,matplotlib可能会更加方便 当你的数据已经存储在DataFrame中,且你需要创建基本的图形时,Pandas的plot函数可能会更加方便



总结

比如现在有一个名叫ex1data1.txt的文件,里面有两列数据,要求绘制散点图

操作如下:

  • 导入NumPyPandas
1
2
import numpy as np
import pandas as pd
  • 利用pd.read_csv()函数读取文件
1
2
df=pd.read_csv('ex1data1.txt',header=None,names=['x', 'y'])
#读入ex1data1的数据,将x和y作为第1列和第2列的名称
  • 利用df.plot()函数绘制散点图
1
2
df.plot(x='x',y='y,kind='scatter')
#x轴的数据为x列,y轴的数据为y列,类型是散点图,其余参数默认

这样就可以生成散点图