目录
深度学习与数据分析四剑客
Python被大量应用在数据挖掘和深度学习领域,其中使用极其广泛的是Numpy,Pandas,Matplotlib,PIL等库
Numpy:Python科学计算库的基础,包含了强大的N维数组对象和向量运算
Pandas:建立在Numpy基础上的高效数据分析处理库,是Python的重要数据分析库
Numpy就是用来进行矩阵计算的,而Pandas则基于Numpy,丰富并简化了Numpy的操作
Matplotlib:一个主要用于绘制二维图形的Python库 用途:绘图、可视化
PIL库:一个具有强大图像处理能力的第三方库 用途:图像处理
Numpy库
Numpy ( Numerical Python的简称)是高性能科学计算和数据分析的基础包,其部分功能如下:
ndarray,一个具有矢量算术运算和复杂广播能力的快速且节省空间的多维数组。
用于对整组数据进行快速运算的标准数学函数(无需编写循环)。
用于读写磁盘数据的工具以及用于操作内存映射文件的工具。
线性代数、随机数生成以及傅里叶变换功能。
Numpy中文网:https://www.Numpy.org.cn/
Numpy库使用
创建ndarray :
创建数组最简单的办法就是使用array函数,它接受一切序列型的对象(包括其他数组),然后产生一个新的含有传入数据的Numpy数组,其中,嵌套序列(比如由一组等长列表组成的列表)将会被转换为一个多维数组
除了np.array之外,还有一些函数也可以新建数组∶
zeros和ones分别可以创建指定长度或者形状的全0或全1数组
empty可以创建一个没有任何具体值的数组
import numpy as np
if __name__ == '__main__':
a = [1, 2, 3, 4] # 创建简单的列表
b = np.array(a) # 将列表转换为数组
print(a, b)
# [1, 2, 3, 4] [1 2 3 4]
# 创建10行10列的数值为浮点0的矩阵
array_zero = np.zeros([10, 10])
# 创建10行10列的数值为浮点1的矩阵
array_one = np. ones([10, 10])
print(array_zero)
print(array_one)
[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]
创建随机数组
if __name__ == '__main__':
# 均匀分布
# 创建指定形状的数组
a = np.random.rand(10, 10)
print(a)
# [[0.57105896 0.03298237 0.25009948 0.51357552 0.39439911 0.92600165
# 0.78356221 0.08882266 0.76976565 0.0871099 ]
# [0.20325148 0.35023107 0.76521877 0.69059151 0.94176802 0.4189306
# 0.07765417 0.69074058 0.73704862 0.88142614]
# [0.46915609 0.34093237 0.21846482 0.0306095 0.33110904 0.77963166
# 0.95344235 0.18029132 0.15351416 0.18226492]
# [0.16233291 0.15021262 0.35543941 0.1701797 0.8155672 0.16904821
# 0.73277468 0.94183731 0.38364079 0.9787078 ]
# [0.91186773 0.89815541 0.18322909 0.39500335 0.97340084 0.62980503
# 0.28168104 0.71848602 0.07679584 0.84120895]
# [0.94883274 0.56429457 0.15294376 0.157195 0.91923712 0.26444221
# 0.70194544 0.42780421 0.38708824 0.11264052]
# [0.62785335 0.63063169 0.5953131 0.96105641 0.03893192 0.8342848
# 0.75451869 0.53669816 0.2724713 0.60406847]
# [0.85786293 0.73769985 0.89119559 0.37818646 0.55522772 0.56170438
# 0.1993785 0.76460757 0.21637988 0.09340406]
# [0.0177829 0.278054 0.29314078 0.89271157 0.44030146 0.85607566
# 0.01938481 0.98405482 0.35985012 0.10623284]
# [0.84460293 0.47065062 0.38670223 0.74835551 0.37896417 0.81894054
# 0.37687113 0.17824471 0.93655048 0.17621064]]
# 创建指定范围内的一个数
b = np.random.uniform(0, 100)
print(b)
# 6.362164686517991
# 创建指定范围内的一个整数
c = np.random.randint(0, 100)
print(c)
# 15
# 正态分布
# 给定均值/标准差/维度的正态分布
d = np.random.normal(1.75, 0.1, (2, 3))
print(d)
# [[1.87221684 1.81910221 1.8540107 ]
# [1.74976639 1.81741999 1.744564 ]]
查看数组属性的用法
用法 | 说明 |
b.size | 数组元素个数 |
b.shape | 数组形状 |
b.ndim | 数组维度 |
b.dtype | 数组元素类型 |
print(a.size)
#100
print(a.shape)
#(10, 10)
print(a.ndim)
#2
print(a.dtype)
#float64
数组与标量之间的计算
numpy数组通常叫做矢量(vector ),大小相等的数组之间的任何算术运算都会将运算应用到元素级,同样,数组与标量的算术运算也会将那个标量值传播到各个元素
if __name__ == '__main__':
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr)
# [[1 2 3]
# [4 5 6]]
print(arr-arr)
# [[0 0 0]
# [0 0 0]]
print(arr*arr)
# [[ 1 4 9]
# [16 25 36]]
print(arr**0.5)
# [[1. 1.41421356 1.73205081]
# [2. 2.23606798 2.44948974]]
print(1/arr)
# [[1. 0.5 0.33333333]
# [0.25 0.2 0.16666667]]
数组的索引与切片
表面上看,Python列表的功能相似
跟列表最重要的区别在于,数组切片是原始数组的视图,这意味着数据不会被复制,视图上的任何修改都会直接反映到源数组上
将一个标量值赋值给一个切片时,该值会自动传播到整个选区
if __name__ == '__main__':
arr = np.arange(10)
print(arr)
# [0 1 2 3 4 5 6 7 8 9]
print(arr[5])
# 5
print(arr[5:8])
# [5 6 7]
arr[5:8] = 12
print(arr)
# [ 0 1 2 3 4 12 12 12 8 9]
arr1 = arr[5:8]
arr1[1] = 12345
print(arr)
# [ 0 1 2 3 4 12 12345 12 8 9]
arr1[:] = 64
print(arr)
# [ 0 1 2 3 4 64 64 64 8 9]
多维数组切片
传入一个以逗号隔开的索引列表来选取单个元素
if __name__ == '__main__':
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
print(arr)
# [[[ 1 2 3]
# [ 4 5 6]]
# [[ 7 8 9]
# [10 11 12]]]
print(arr[0])
# [[1 2 3]
# [4 5 6]]
print(arr[0][1])
# [4 5 6]
print(arr[0, 1])
# [4 5 6]
数学与统计方法
可以通过数组上的一组数学函数对整个数组或某个轴向的数据进行统计计算
sum、mean以及标准差std等聚合计算既可以当做数组的实例方法调用,也可以当做顶级Numpy函数使用
if __name__ == '__main__':
arr = np.random.randn(5, 4) # 正态分布的数据
#求平均
print(arr.mean())
print(np.mean(arr))
# -0.022341797127577216
#求和
print(arr.sum())
# -0.44683594255154435
mean和sum这类的函数可以接受一个axis参数(用于计算该轴向上的统计值),最终结果是一个少一维的数组
print(arr.mean(axis=1))
# [-0.35470117 0.06785491 0.02250157 -0.41614488 0.54509174]
print(arr.sum(0))
# [ 0.68637923 -6.88562962 3.32167684 2.33598224]
基本数组统计方法
方法 | 说明 |
sum | 对数组中全部或某轴向的元素求和。零长度的数组的sum为0 |
mean | 算术平均数。零长度的数组的mean为NaN |
std, var | 分别为标准差和方差,自由度可调(默认为n ) |
min, max | 最大值和最小值 |
argmin, argmax | 分别为最大和最小元素的索引 |
cumsum | 所有元素的累加 |
cumprod | 所有元素的累积 |
线性代数
线性代数(如矩阵乘法、矩阵分解、行列式以及其他方阵数学等)是任何数组库的重要组成部分
Numpy提供了一个用于矩阵乘法的dot函数(既是一个数组方法,也是Numpy命名空间中的一个函数)
if __name__ == '__main__':
x = np.array([[1, 2, 3], [4, 5, 6]])
y = np.array([[1, 2], [3, 4], [5, 6]])
print(x)
# [[1 2 3]
# [4 5 6]]
print(y)
# [[1 2]
# [3 4]
# [5 6]]
# 矩阵乘法
print(x.dot(y))
# [[22 28]
# [49 64]]
Numpy.linalg中有一组标准的矩阵分解运算以及诸如求逆和行列式之类的东西
它们跟 MATLAB和R等语言所使用的是相同的行业标准级Fortran库
常用的 Numpy.linalg 函数︰
函数 | 说明 |
diag | 以一维数组的形式返回方阵的对角线(或非对角线)元素,或将一维数组转换为方阵(非对角线元素为0) |
dot | 矩阵乘法 |
trace | 计算对角线元素的和 |
det | 计算矩阵行列式 |
eig | 计算方阵的特征值和特征向量 |
inv | 计算方阵的逆 |
pinv | 计算矩阵的Mooer-Penrose伪逆 |
qr | 计算OR分解 |
svd | 计算奇异值分解(SVD) |
solve | 解线性方程组Ax=b,其中A为一个方阵 |
lstsq | 计算Ax=b的最小二乘解 |
Pandas库
Pandas是Python第三方库,提供高性能易用数据类型和分析工具
Pandas基于Numpy实现,常与Numpy和matplotlib一同使用
Pandas中有两大核心数据结构︰Series (一维数据,键值对,键可以重复)和DataFrame(多特征数据,既有行索引,又有列索)
Pandas中文网: https://www.pyPandas.cn/
Pandas库使用
Series
Series是一种类似于一维数组的对象,它由一维数组(各种Numpy数据类型)以及一组与之相关的数据标签(即索引)组成
Series的创建︰
使用Python数组创建
使用Numpy数组创建
使用Python字典创建
注意∶与字典不同的是: Series允许索引重复·
if __name__ == '__main__':
print(pd.Series([11, 12], index=["北京", "上海"]))
# 北京 11
# 上海 12
# dtype: int64
print(pd.Series(np.arange(3, 6)))
# 0 3
# 1 4
# 2 5
# dtype: int32
print(pd.Series({"北京": 11, "上海": 12, "深圳": 14}))
# 北京 11
# 上海 12
# 深圳 14
# dtype: int64
Series的字符串表现形式为∶索引在左边,值在右边
如果没有为数据指定索引,则自动创建一个0到N-1(N为数据的长度)的整数型索引可以通过 Series的values和index属性获取其数组表示形式和索引对象
与普通Numpy数组相比,可以通过索引的方式选取Series中的单个或一组值
if __name__ == '__main__':
a = pd.Series([4, 7, -5, 3])
print(a.values)
# [ 4 7 -5 3]
print(a.index)
# RangeIndex(start=0, stop=4, step=1)
print(a[2])
# -5
a[1]=8
print(a[[0, 1, 3]])
# 0 4
# 1 8
# 3 3
# dtype: int64
Series中最重要的一个功能是∶它会在算术运算中自动对齐不同索引的数据
if __name__ == '__main__':
obj2 = pd.Series({"Ohio": 35000, "Oregon": 16000,"Texas":71000, "Utah": 5000})
obj3 = pd.Series({"California": np.nan, "Ohio": 35000, "Oregon": 16000, "Texas": 71000})
print(obj3+obj2)
# California NaN
# Ohio 70000.0
# Oregon 32000.0
# Texas 142000.0
# Utah NaN
# dtype: float64
Series对象本身及其索引都有一个name属性,该属性跟Pandas其他的关键功能关系非常密切Series的索引可以通过赋值的方式就地修改
if __name__ == '__main__':
obj2 = pd.Series({"Ohio": 35000, "Oregon": 16000, "Texas": 71000, "Utah": 5000})
obj2.index.name = 'state'
obj2.name = 'population'
print(obj2)
# state
# Ohio 35000
# Oregon 16000
# Texas 71000
# Utah 5000
# Name: population, dtype: int64
obj = pd.Series([4, 7, -5, 3])
obj.index = ['b', 's', 'j', 'r']
print(obj)
# b 4
# s 7
# j -5
# r 3
# dtype: int64
DataFrame
DataFrame是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等)
DataFrame既有行索引也有列索引,它可以被看做由Series组成的字典(共用同一个索引)跟其他类似的数据结构相比(如R语言的data.frame ) ,DataFrame中面向行和面向列的操作基本上是平衡的
构成DataFrame的方法很多,最常用的一种是直接传入一个由等长列表或Numpy数组组成的字典
DataFrame结果会自动加上索引(跟Series一样),且全部会被有序排列
if __name__ == '__main__':
data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'], 'year': [2000, 2001, 2002, 2001, 2002],
'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}
frame = pd.DataFrame(data)
print(frame)
# # state year pop
# 0 Ohio 2000 1.5
# 1 Ohio 2001 1.7
# 2 Ohio 2002 3.6
# 3 Nevada 2001 2.4
# 4 Nevada 2002 2.9
如果指定了列顺序,则DataFrame的列就会按照指定顺序进行排列
跟原Series一样,如果传入的列在数据中找不到,就会产生NAN值
if __name__ == '__main__':
data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'], 'year': [2000, 2001, 2002, 2001, 2002],
'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}
frame = pd.DataFrame(data,columns=['year','pop','state','debt'],index=['one','two','three','four','five'])
print(frame)
# year pop state debt
# one 2000 1.5 Ohio NaN
# two 2001 1.7 Ohio NaN
# three 2002 3.6 Ohio NaN
# four 2001 2.4 Nevada NaN
# five 2002 2.9 Nevada NaN
列可以通过赋值的方式进行修改
例如,给“debt”列赋上一个标量值或一组值
frame['debt']=16.5
print(frame)
# year pop state debt
# one 2000 1.5 Ohio 16.5
# two 2001 1.7 Ohio 16.5
# three 2002 3.6 Ohio 16.5
# four 2001 2.4 Nevada 16.5
# five 2002 2.9 Nevada 16.5
将列表或数组赋值给某个列时,其长度必须跟DataFrame的长度相匹配
如果赋值的是一个Series,就会精确匹配DataFrame的索引,所有空位都将被填上缺失值
val = pd.Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five'])
frame['debt'] = val
print(frame)
# year pop state debt
# one 2000 1.5 Ohio NaN
# two 2001 1.7 Ohio -1.2
# three 2002 3.6 Ohio NaN
# four 2001 2.4 Nevada -1.5
# five 2002 2.9 Nevada -1.7
为不存在的列赋值会创建出一个新列
关键字del用于删除列
frame['eastern'] = frame.state == 'Ohio'
print(frame)
# year pop state debt eastern
# one 2000 1.5 Ohio NaN True
# two 2001 1.7 Ohio NaN True
# three 2002 3.6 Ohio NaN True
# four 2001 2.4 Nevada NaN False
# five 2002 2.9 Nevada NaN False
del frame['eastern']
print(frame.columns)
# Index(['year', 'pop', 'state', 'debt'], dtype='object')
将嵌套字典(也就是字典的字典)传给DataFrame,它就会被解释为∶外层字典的键作为列,内层键则作为行索引
也可以对上述结果进行转置
if __name__ == '__main__':
pop = {'Nevada':{2001:2.4,2002:2.9},'Ohio':{2000:1.5,2001:1.7,2002:3.6}}
frame=pd.DataFrame(pop)
print(frame)
# Nevada Ohio
# 2001 2.4 1.7
# 2002 2.9 3.6
# 2000 NaN 1.5
print(frame.T)
# 2001 2002 2000
# Nevada 2.4 2.9 NaN
# Ohio 1.7 3.6 1.5
如果设置了DataFrame的index和columns的name属性,则这些信息也会被显示出来
frame.index.name='year'
frame.columns.name='state'
print(frame)
# state Nevada Ohio
# year
# 2001 2.4 1.7
# 2002 2.9 3.6
# 2000 NaN 1.5
跟Series一样,values属性也会以二维ndarray的形式返回DataFrame中的数据
如果DataFrame各列的数据类型不同,则数组的数据类型就会选用能兼容所有列的数据类型
print(frame.values)
# [[2.4 1.7]
# [2.9 3.6]
# [nan 1.5]]
Pandas的索引对象负责管理轴标签和其他元数据(比如轴名称等)
构建DataFrame时,所用到的任何数组或其他序列的标签都会被转换成一个IndexIndex对象是不可修改的,因此用户不能对其进行修改
Pandas的每个索引都有一些方法和属性,它们可用于设置逻辑并回答有关该索引包含的数据的常见问题。
列出了Index的方法和属性
方法 | 说明 |
append | 连接另一个Index对象,产生一个新的Index |
diff | 计算差集,并得到一个Index |
intersection | 计算交集 |
union | 计算并集 |
isin | 计算一个指示各值是否都包含在参数集合中的布尔型数组 |
delete | 删除索引处的元素,并得到新的Index |
drop | 删除传入的值,并得到新的Index |
insert | 将元素插入到索引处,并得到新的Index |
is_monotonic | 当各元素均大于等于前一个元素时,返回True |
is_unique | 当Index没有重复值时,返回True |
unique | 计算Index中唯一值的数组 |
Matplotlib库
Matplotlib库由各种可视化类构成,内部结构复杂
受Matlab启发,matplotlib.pylot是绘制各类可视化图形的命令字库,相当于快捷方式
Matplotlib中文网: https://www.matplotlib.org.cn
Matplotlib库使用
plt.plot()只有一个输入列表或数组时,参数被当做Y轴,X轴以索引自动生成
plt.savefig()将输出图形存储为文件,默认PNG格式,可以通过dpi修改输出质量
import matplotlib.pyplot as plt
if __name__ == '__main__':
plt.plot([3, 1, 4, 5, 2])
plt.ylabel("Grade")
plt.savefig("test", dpi=600) # PNG文件
plt.show()
pyplot的绘图区域
plt.subplot(nrows, ncols, plot_number)
在全局绘图区域中创建一个分区体系,并定位到一个子绘图区域
pyplot的基础图标函数如下
函数 | 说明 |
plt.plot(x,y,fmt...) | 绘制一个坐标图 |
plt.boxplot(data, notch, position) | 绘制一个箱形图 |
plt.bar(left, height, width, bottom) | 绘制一个条形图 |
plt.barh(width, bottom, left, height) | 绘制一个横向条形图 |
plt.polar(theta, r) | 绘制极坐标图 |
plt.pie(data, explode) | 绘制饼图 |
plt.contour(X,Y,Z,N) | 绘制等值图 |
plt.vlines() | 绘制垂直图 |
plt.stem(x, y, linefmt, markerfmt) | 绘制柴火图 |
plt.plot_date() | 绘制数据日期 |
饼图的绘制
import matplotlib.pyplot as plt
if __name__ == '__main__':
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
sizes = [15, 30, 45, 10]
explode = (0, 0.1, 0, 0)
plt.pie(sizes, explode=explode, labels=labels,
autopct='%1.1f%%', shadow=False, startangle=90)
# x:浮点型数组,表示每个扇形的面积。
#
# explode:数组,表示各个扇形之间的间隔,默认值为0。
#
# labels:列表,各个扇形的标签,默认值为 None。
#
# colors:数组,表示各个扇形的颜色,默认值为 None。
#
# autopct:设置饼图内各个扇形百分比显示格式,%d%% 整数百分比,%0.1f 一位小数, %0.1f%% 一位小数百分比, %0.2f%% 两位小数百分比。
#
# labeldistance:标签标记的绘制位置,相对于半径的比例,默认值为 1.1,如 <1则绘制在饼图内侧。
#
# pctdistance::类似于 labeldistance,指定 autopct 的位置刻度,默认值为 0.6。
#
# shadow::布尔值 True 或 False,设置饼图的阴影,默认为 False,不设置阴影。
#
# radius::设置饼图的半径,默认为 1。
#
# startangle::起始绘制饼图的角度,默认为从 x 轴正方向逆时针画起,如设定 =90 则从 y 轴正方向画起。
#
# counterclock:布尔值,设置指针方向,默认为 True,即逆时针,False 为顺时针。
#
# wedgeprops :字典类型,默认值 None。参数字典传递给 wedge 对象用来画一个饼图。例如:wedgeprops={'linewidth':5} 设置 wedge 线宽为5。
#
# textprops :字典类型,默认值为:None。传递给 text 对象的字典参数,用于设置标签(labels)和比例文字的格式。
#
# center :浮点类型的列表,默认值:(0,0)。用于设置图标中心位置。
#
# frame :布尔类型,默认值:False。如果是 True,绘制带有表的轴框架。
#
# rotatelabels :布尔类型,默认为 False。如果为 True,旋转每个 label 到指定的角度
plt.axis('equal') # 正圆
# loc = 'upper right' 位于右上角
# bbox_to_anchor=[0.5, 0.5] # 外边距 上边 右边
# ncol=2 分两列
# borderaxespad = 0.3图例的内边距
# plt.savefig(filepath+'\name.png',dpi=120,bbox_inches='tight') #可通过这个方法保存可视化的图片
plt.show()
直方图的绘制
if __name__ == '__main__':
np.random.seed(0)
mu, sigma = 100, 20 # 均值和标准值
a = np.random.normal(mu, sigma, size=100)
plt.hist(a, 20, density=True
, histtype='stepfilled', facecolor='b', alpha=0.75)
# x: 作直方图所要用的数据,必须是一维数组;多维数组可以先进行扁平化再作图;必选参数;
# bins: 直方图的柱数,即要分的组数,默认为10;
# range:元组(tuple)或None;剔除较大和较小的离群值,给出全局范围;如果为None,则默认为(x.min(), x.max());即x轴的范围;
# density:布尔值。如果为true,则返回的元组的第一个参数n将为频率而非默认的频数;
# weights:与x形状相同的权重数组;将x中的每个元素乘以对应权重值再计数;如果normed或density取值为True,则会对权重进行归一化处理。这个参数可用于绘制已合并的数据的直方图;
# cumulative:布尔值;如果为True,则计算累计频数;如果normed或density取值为True,则计算累计频率;
# bottom:数组,标量值或None;每个柱子底部相对于y=0的位置。如果是标量值,则每个柱子相对于y=0向上/向下的偏移量相同。如果是数组,则根据数组元素取值移动对应的柱子;即直方图上下便宜距离;
# histtype:{‘bar’, ‘barstacked’, ‘step’, ‘stepfilled’};'bar’是传统的条形直方图;'barstacked’是堆叠的条形直方图;'step’是未填充的条形直方图,只有外边框;‘stepfilled’是有填充的直方图;当histtype取值为’step’或’stepfilled’,rwidth设置失效,即不能指定柱子之间的间隔,默认连接在一起;
# align:{‘left’, ‘mid’, ‘right’};‘left’:柱子的中心位于bins的左边缘;‘mid’:柱子位于bins左右边缘之间;‘right’:柱子的中心位于bins的右边缘;
# orientation:{‘horizontal’, ‘vertical’}:如果取值为horizontal,则条形图将以y轴为基线,水平排列;简单理解为类似bar()转换成barh(),旋转90°;
# rwidth:标量值或None。柱子的宽度占bins宽的比例;
# log:布尔值。如果取值为True,则坐标轴的刻度为对数刻度;如果log为True且x是一维数组,则计数为0的取值将被剔除,仅返回非空的(frequency, bins, patches);
# color:具体颜色,数组(元素为颜色)或None。
# label:字符串(序列)或None;有多个数据集时,用label参数做标注区分;
# stacked:布尔值。如果取值为True,则输出的图为多个数据集堆叠累计的结果;如果取值为False且histtype=‘bar’或’step’,则多个数据集的柱子并排排列;
# edgecolor: 直方图边框颜色;
# alpha: 透明度;
plt.title('Histogram')
plt.show()
散点图的绘制
if __name__ == '__main__':
fig, ax = plt.subplots()# 它是用来创建 总画布/figure“窗口”的,有figure就可以在上边(或其中一个子网格/subplot上)作图了,(fig:是figure的缩写)
ax.plot(10 * np.random.randn(100), 10 * np.random.randn(100), 'o')
ax.set_title('Simple Scatter')
plt.show()
PIL库
PIL库是一个具有强大图像处理能力的第三方库
在命令行下的安装方法:pip install pillow
在使用过程中的引入方法:from PIL import Image
Image是PIL库中代表一个图像的类(对象)
PIL库使用
图像的数组表示
图像是一个由像素组成的二维矩阵,每个元素是一个RGB值
读取图片
from PIL import Image
if __name__ == '__main__':
im = Image.open('test.png')
im.rotate(45).show()# 将图片旋转,并用系统自带的图片工具显示图片
创建缩略图
缩略图不能直接双击打开,要使用PIL.Image的open读取,然后使用show()方法进行显示。
import requests as req
from PIL import Image
from io import BytesIO
def make_thumb(url, sizes=(128, 128)):
"""
生成指定尺寸缩略图
:param url: 图像链接
:param sizes: 指定尺寸
:return: 无返回,直接保存图片
"""
response = req.get(url)
im = Image.open(BytesIO(response.content))
mode = im.mode
if mode not in ('L', 'RGB'):
if mode == 'RGBA':
# 透明图片需要加白色底
alpha = im.split()[3]
bgmask = alpha.point(lambda x: 255 - x)
im = im.convert('RGB')
im.paste((255, 255, 255), None, bgmask)
else:
im = im.convert('RGB')
# 切成方图,避免变形
width, height = im.size
if width == height:
region = im
else:
if width > height:
# h*h
delta = (width - height) / 2
box = (delta, 0, delta + height, height)
else:
# w*w
delta = (height - width) / 2
box = (0, delta, width, delta + width)
region = im.crop(box)
# resize
thumb = region.resize((sizes[0], sizes[1]), Image.Resampling.LANCZOS)
# 保存图片
filename = url.split('/')[-1]
name, ext = filename.split('.')
savename = name + str(sizes[0]) + '_' + str(sizes[1]) + '.' + ext
thumb.save(savename, quality=100)
if __name__ == '__main__':
url = 'https://scpic.chinaz.net/files/pic/pic9/201910/zzpic20739.jpg'
make_thumb(url)
常用的图片的融合或者合成函数如下
PIL.image.alpha_composite(im1,im2)
PIL.image.blend(im1,im2,alpha)
PIL.Image.composite(im1,im2,mask)
上述方法要求im1和im2的mode和size要一致; alpha代表图片占比的意思;mask是mode可以为”1”;”L”或者”RGBA“(彩色图/灰度图)
实现图像的灰度化处理
if __name__ == '__main__':
#url = 'https://scpic.chinaz.net/files/pic/pic9/201910/zzpic20739.jpg'
#make_thumb(url)
im = Image.open('zzpic20739128_128.jpg')
im = im.convert("L")
im.show()
Image.copy(0)
#将读取的图片复制一份
获取图片基本信息
if __name__ == '__main__':
#url = 'https://scpic.chinaz.net/files/pic/pic9/201910/zzpic20739.jpg'
#make_thumb(url)
im = Image.open('zzpic20739128_128.jpg')
bands = im.getbands()#显示该图像的所有通道,返回一个tuple
print(bands)
# ('R', 'G', 'B')
bboxs=im.getbbox()
print(bboxs)
# (0, 0, 128, 128)
图像粘贴操作
Image.paste(im, box=None, maske=None)
使用im粘贴到原图片中
两个图片的mode和size要求一致,不一致可以使用convert()和resize()进行调整