Numpy的相关操作

56 阅读15分钟

初始Numpy

Numpy主要用于数组计算、矩阵运算和科学计算。

Numpy概述

NumPy像是一个魔方,它是Python数组计算、矩阵运算和科学计算的核心库,NumPy这个词来源于Numerical和Python两个单词。NumPy提供了一个高性能的数组对象,让我们轻松创建一维数组、二维数组和多维数组,以及大量的函数和方法,帮助我们轻松地进行数组计算,从而广泛地应用于数据分析、机器学习、图像处理和计算机图形学、数学任务等领域当中。

numpy的用途是以数组的形式对数据进行操作。机器学习中充斥着大量的数组运算,而Numpy使得这些操作变得简单!由于Numpy是C语言实现的,所以其运行速度非常快。具体功能如下:

1、有一个强大的n维数组对象 ndarray

2、广播功能函数

3、线性代数、傅立叶变换、随机随生成、图形操作等功能。

4、整合C/C++代码等工具

数组相关概念

数组可以分为一维数组,二维数据,三维数组,其中三维数组是最常见的多维数组。

image.png

一维数组

一维数组,基本和python中的列表一样,区别在于数组切片针对的是原始数组(这就意味着,如果对数组进行修改,原始数组也会跟着进行更改。)

二维数组

二维数组本质上是以数组作为数组元素的数组。二维数组包括行与列,类似于表格形状,又称为矩阵

三维数组

三维数组是指维度为3的数组结构,也称矩阵列表。三维数组是最常见的多维数组,由于其可以用来描述三维空间中的位置或状态而被广泛使用。

轴的概念

轴是numpy中的axis,指定某个axis,就是沿着这个axis做相关操作,其中二维数组中两个axis的指向如下图所示。

image.png

对于一维数组,情况有点特殊,他不像二维数组从上向下的操作,而是水平的,因此一维数组其axis=0指向如下图2所示。

image.png

创建数据

通过Numpy的内置函数array()可以创建ndarray对象,其语法格式如下:

numpy.array(object,dtype=None,copy=True,order=None,ndmin=0)

参数说明:

  • object:表示一个数组序列
  • dtype: 通过它可以更改数组的数据类型,可以自填参数
  • copy: 表示数组能否被复制,默认值为True
  • order: 以哪种内存布局创建数组,有 3 个可选值,分别是 C(行序列)/F(列序列)/A(默认)
  • ndmin: 用于指定数组的维度

创建简单数组

import numpy as np

n1 = np.array([1, 2, 3])
n2 = np.array([0.1, 0.2, 0.3])
n3 = np.array([[1, 2], [3, 4]])

print(n1, n2, n3, sep='\n')

image.png

为数组指定数据类型

"""为数组指定数据类型
Numpy支持比Python更多种类的数据类型,通过dtype参数可以指定数组的数据类型。
"""
import numpy as np
li = [1, 2, 3]
# 创建浮点型数组
n4 = np.array(li, dtype=np.float_)   #float_可换成float64
print(n4, type(n4), n4.dtype)
print(type(n4[0]))

image.png

数组的复制

"""数组的复制
当运算和处理数组时,为了不影响到原数组,就需要对原数组进行复制,而对复制后的数组进行修改删除
等操作都不会影响到原数组。数组的复制可以通过copy参数进行实现。
"""
import numpy as np
n5 = np.array([1, 2, 3])
print(n5, id(n5), type(n5))
new_n5 = np.array(n5, copy=True)
print(new_n5, id(new_n5), type(new_n5))

n5[2] = 110
new_n5[1] = 119
print(n5, new_n5)

image.png

控制数组维度

"""控制最小维度
数组可以分为一维,二维,三维数组,通过ndmin参数可以控制数组的最小维数。
无论给出的数据的维度是多少,ndmin参数都会根据最小维数创建指定位数的数组。
"""
import numpy as np
nd1 = [1, 2, 3]
nd2 = np.array(nd1, ndmin=3)  #np.array(nd1)默认ndmin=1
print(nd2)

不同方式创建数组

创建指定维度

import numpy as np

"""创建指定维度和数据类型未初始化的数组
主要使用到empty()函数
"""
n1 = np.empty((3,3))  #未赋初始值,因此输出的是随机数
n1.dtype = int
print(n1)

"""
创建指定维度(以0填充)的数组
主要使用到zeros()函数
"""

n2 = np.zeros(3)
print(n2)
"""创建指定维度(以1填充)的数组
主要使用到ones()函数
"""
n3 = np.ones(3)
print(n3)
"""创建指定维度和类型的数组并以指定值填充
主要使用到full()函数
"""
n4 = np.full((2,3,5), 8)  #full((2,3,5),2代表个数,3代表行,5代表列
print(n4)

从数值范围创建数组

import numpy as np
import pandas as pd

"""通过arange()函数创建数组
arange()函数同python内置的函数相似,区别在于返回值
arange()函数返回的是数组,range()函数的返回值是一个列表。
"""
n1 = np.arange(1,12,2)
print(n1)

"""使用linspace()函数创建等差数列"""
n2 = np.linspace(7500,10000,6,dtype=int)  #指定类型int,不指定为float类型
print(n2)

"""使用logspace()函数创建等比数列"""
import numpy as np
# np.set_printoptions(threshold=np.inf)
#输出时打印不换行
np.set_printoptions(linewidth=500)
#n = np.logspace(0,63,64,base=2,dtype='int')
n = np.logspace(0,63,64,base=2,dtype='uint64')
# print(n)
#数组重塑8*8矩阵
print(n.reshape(8,8))

生成随机数组

import numpy as np
"""随机数组的生成主要使用Numpy的random模块"""

"""rand()函数
用于生成(0,1)之间的随机数组,传入一个值随机生成一维数组,
传入一堆纸则随机生成二维数组"""
n1 = np.random.rand(5)
print('随机生成一个0-1的一维数组')
print(n1)

n2 = np.random.rand(2,5)
print('随机生成一个0-1的二维数组')
print(n2)

"""randn()函数
用于从正态分布中返回随机生成的数组"""
n3 = np.random.randn(5)
print('随机生成一个满足正太分布的一维数组')
print(n3)
n4 = np.random.randn(2,5)
print('随机生成一个满足正太分布的二维数组')
print(n4)

"""randint()函数
与Numpy中的arange()函数类似,randint()函数用于生成一定范围内的随机数组,
左闭右开区间"""
n5 = np.random.randint(1,3,10)
print('随机生成10个1-3之间且不包括3的整数')
print(n5)
n6 = np.random.randint(5,10)
print('size数组大小为空随机返回一个整数')
print(n6)
n7 = np.random.randint(5,size=(2,5))
print('随机生成5以内二维数组')
print(n7)

"""normal()函数
用于正态分布的随机数"""
n8 = np.random.normal(0,0.1,10)
print(n8)

数组的基本操作

数组类型

Numpy的数据类型比Python数据类型增加了更多种类的数值类型,如下表图所示。为了区别数据类型,像bool、int、float、complex、str等数据类型的名称末尾都加了短下划线。

image.png

image.png

每一种数据类型都有相应的数据转换函数,如下所示。

import numpy as np

n1 = np.int8(3.14159)
n2 = np.float64(8)
n3 = np.float32(8)
print(n1,n2,n3,sep='\n')
# 在创建ndarray数组是,可以直接指定数值类型
a = np.arange(8,dtype=float)
print(a)

image.png

数组运算

不用编写循环即可对数据执行批量运算,这就是Numpy数组运算的特点,Numpy称之为矢量化。大小相等的数组之间的任何运算Numpy都可以实现。

数组示意图

image.png

简单运算之加减乘除幂运算

import numpy as np

n1 = np.array([1,2])
n2 = np.array([3,4])
print(n1+n2)
print(n1-n2)
print(n1*n2)
print(n1/n2)
print(n1**n2)  #幂运算

image.png

数组的比较运算

数组的比较运算是数组中对应位置元素的比较运算,比较后的结果是布尔值数组。

import numpy as np
n1 = np.array([1,2])
n2 = np.array([3,4])
print(n1>=n2)
print(n1==n2)
print(n1<=n2)
print(n1!=n2)

image.png

数组的标量运算

首先要了解两个概念,即标量和矢量。标量其实是一个单独的数;而向量是一组数,这组数是顺序排列的,这个咱们理解为数组。那么,数组的标量运算也可以理解为是向量与标量之间的运算。

数组的标量运算(m---->km) image.png

import numpy as np

n1 = np.linspace(7500, 10000, 6, dtype='int')
print(n1)
print(n1 / 1000)

image.png

数组的切片与索引

Numpy数组元素是通过数组的索引和切片来访问和修改的,因此索引和切片是Numpy中最重要、最常用的操作。

索引

所谓数组的索引,即用于标记数组中对应元素的唯一数字,从0开始,即数组中的第一个元素的索引是0,以此类推。Numpy数组可以使用标准Python语法x[obj]的语法对数组进行索引,其中x是数组,obj是索引。

import numpy as np
n1 = np.array([1,2,3])
print(n1[0])

n2 = np.array([[1,2,3],[4,5,6]])
print(n2[1][2])  #第二行第三列

image.png

切片式索引

数组的切片可以理解为对数组的分割,按照等分或者不等分,将一个数组切割为多个片段,它与Python中列表的切片操作一样。Numpy中的切片用冒号分隔切片参数来进行切片操作。语法如下:

[srart:stop:step]  #包头不包尾

image.png

n3 = np.array([1,2,3])
print(n3)
print(n3[0])
print(n3[1])
print(n3[0:2])
print(n3[1:])
print(n3[:2])

image.png

数组重塑

数组重塑是更改数组的形状,例如,将原来2行3列的数组重塑为3行4列的数组。在Numpy中主要使用reshape()方法,该方法用于改变数组的形状。

一维数组重塑

一维数组重塑就是将数组重塑为多行多列的数组

import numpy as np

n1 = np.arange(6) # 创建一维数组[0 1 2 3 4 5]
print(n1)
n2 = n1.reshape(2,3) # 将数组重塑为2行3列的二维数组
print(n2)
"""注意点:数组重塑是基于数组元素不发生改变的情况,重塑后的数组所包含的元素个数必须
与原数组元素个数相同,如果数组元素发生改变,程序就会报错"""

'''古诗格式转化'''
n=np.array(['床','前','明','月','光','疑','是','地','上','霜','举','头','望','明','月','低','头','思','故','乡'])
n3=n.reshape(4,5)
print(n3)

image.png

多维数组重塑

多维数组重塑依然使用reshape()方法。

import numpy as np
n=np.array([[0,1,2],[3,4,5]]) #创建二维数组
print(n)
n1=n.reshape(3,2)   #将数组重塑为32列的二维数组
print(n1)

image.png

数组转置

数组转置指的是数组的行列转换,可以通过数组的T属性和transpose()函数实现

import numpy as np
n1 = np.arange(24).reshape(4,6)    #创建4行6列的二维数组
print(n1)
print(n1.T)                        #T属性行列转置,或者print(n1.transpose())

'''客户销售数据转换'''
n2 = np.array([['A',100],['B',200],['C',300],['D',400],['E',500]])
print(n2)
print(n2.T)                        #T属性行列转置
# transpose函数也可以实现数组转置
print(n2.transpose())                #transpose()函数行列转置

image.png

数组的增删改查

数组的增加

数组数据的增加可以按照水平方向增加数据,也可以按照垂直方向增加数据。水平方向增加数据主要使用hstack()函数,垂直方向增加数据主要使用vstack()函数。

# 创建两个二维数组,然后实现数组数据的增加
import numpy as np

# 创建二维数组
n1 = np.array([[1, 2], [3, 4], [5, 6]])
n2 = np.array([[10, 20], [30, 40], [50, 60]])
print(np.hstack((n1, n2)))  # 水平方向增加数据
print(np.vstack((n1, n2)))  # 垂直方向增加数据

image.png

数组的删除

修改数组或数组元素时,直接为数组或数组元素赋值即可。

import numpy as np

# 创建二维数组
n1 = np.array([[1, 2], [3, 4], [5, 6]])
print(n1)
n1[1] = [30, 40]  # 修改第2行数组[3,4][30,40]
n1[2][1] = 88  # 修改第3行第3个元素688
print('修改后的数组:', '\n', n1)

image.png

数组的查询

数组的查询同样可以使用索引和切片方法来获取指定范围的数组或数组元素,还可以通过where()函数查询符合条件的数组或数组元素。where函数语法如下:

numpy.where(condition,x,y)
第一个参数为一个布尔数组
第二个和第三个参数可以是标量也可以是数组。
满足条件condition,输出参数x,不满足条件参数输出参数y。
import numpy as np

n1 = np.arange(10)  # 创建一个一维数组
print(n1)
print(np.where(n1 > 5, 1, 0))  # 大于5输出1,不大于5输出0
#如果不指定参数x和y,则输出满足条件的数组元素的坐标
n2 = n1[np.where(n1 > 5)]
print(n2)

image.png

矩阵的基本操作

Numpy函数库中存在两种不同的数据类型(矩阵matrix和数组array),它们都可以用于处理行列表示的数组元素,虽然他们看起来很相似,但是在这两种数据类型上执行相同的数学运算,可能得到不同的结果。

在Numpy中,矩阵应用十分广泛。例如,每个图像可以被看作像素值矩阵。假设一个像素值仅为0和1,那么5x5大小的图像就是一个5x5的矩阵,而3x3大小的图像就是一个3x3的矩阵。

image.png

创建简单的矩阵mat()

使用mat()函数创建矩阵。

import numpy as np
a = np.mat('5 6;7 8')
b = np.mat([[1, 2], [3, 4]])
print(a,type(a))
print(b,type(b))

n1 = np.array([[1, 2], [3, 4]])
print(n1,type(n1))
"""mat()函数创建的是矩阵类型,array()创建的是数组类型,而用mat()函数创建的矩阵才能进行一些线性代数的操作"""

image.png

创建常见的矩阵mat()

import numpy as np
# 创建一个3*3的零矩阵
data1 = np.mat(np.zeros((3,3)),dtype=int)  #不指定dtype默认float
print('3*3的零矩阵:')
print(data1)
# 创建一个2*41矩阵
data1 = np.mat(np.ones((2,4)))
print('2*41矩阵:')
print(data1)

#使用rand()函数创建一个3*30~1之间随机产生的二维数组
data1 = np.mat(np.random.rand(3,3))
print('3*30~1之间随机产生的二维数组:')
print(data1)

#创建一个1~8之间的随机整数矩阵
data1 = np.mat(np.random.randint(1,8,size=(3,5)))
print('1~8之间的随机整数矩阵:')
print(data1)

# 创建对角矩阵
print('对角矩阵:')
data1 = np.mat(np.eye(2,2,dtype=int)) #2*2对角矩阵
print(data1)
data1 = np.mat(np.eye(4,4,dtype=int)) #4*4对角矩阵
print(data1)

#创建对角线矩阵
print('对角线矩阵:')
a = [1,2,3]
data1 = np.mat(np.diag(a))  #对角线123矩阵
print(data1)
b = [4,5,6]
data1 = np.mat(np.diag(b))  #对角线456矩阵
print(data1)

**注意:** mat()函数只适用于二维数组,维数超过2以后,mat()函数就不适用了,因此array()函数更具通用性。

矩阵运算

矩阵计算之加减除运算

image.png

import numpy as np

'''加法运算'''
# 创建矩阵
data1 = np.mat([[1, 2], [3, 4], [5, 6]])
data2 = np.mat([1, 2])
print('加法')
print(data1 + data2)  # 矩阵加法运算
'''减法除法运算'''
print('减法')
print(data1 - data2)  # 矩阵减法法运算
print('除法')
print(data1 / data2)  # 矩阵除法运算,(data1 // data2):取整数,也就可以去掉小数点

'''乘法运算
矩阵的乘法运算,要求左边矩阵的列和右边矩阵的行数要一致'''
data1 = np.mat([[1, 2], [3, 4], [5, 6]])
data2 = np.mat([[1, 2], [3, 4]])
print('乘法')
print(data1 * data2)  #第一行第一列=1x1+2x3=7

image.png

矩阵运算之数组相乘与数组点乘比较

数组运算和矩阵运算的一个关键区别是矩阵相乘使用的是点乘。点乘也称点积。是数组中元素对应位置一一相乘之后求和的操作。在Numpy中专门提供了点乘方法,即dot()方法,该方法返回的是两个数组的点乘/点积。

import numpy as np

'''加法运算'''
# 创建矩阵
data1 = np.mat([[1, 2], [3, 4], [5, 6]])
data2 = np.mat([1, 2])
# print(data1)
# print(data2)
# print('加法')
# print(data1 + data2)  # 矩阵加法运算
'''减法除法运算'''
import numpy as np
#创建数组
n1 = np.array([1, 2, 3])
n2= np.array([[1, 2, 3], [1, 6, 3], [1, 2, 3]])
print(n1)
print(n2)
print('数组相乘结果为:','\n', n1*n2) #数组相乘,数组的位置元素相乘,例如:[1 2 3]x1,[1 2 3]x2
print('数组相乘结果为:','\n', n2*n1) 
print('数组点乘结果为:','\n', np.dot(n2, n1)) #数组点乘,前面的数组乘以后面数组的转置
print('数组点乘结果为:','\n', np.dot(n1, n2)) 
print(np.multiply(n1,n2))

image.png

矩阵运算之矩阵元素之间的相乘运算

import numpy as np
n1 = np.mat('1 3 3;4 5 6;7 12 9') # #创建矩阵,使用分号隔开数据
n2 = np.mat('2 6 6;8 10 12;14 24 18')
print(n1)
print(n2)
print('矩阵相乘结果为:\n',n1*n2)  #矩阵相乘
print('矩阵对应元素相乘结果为:\n',np.multiply(n1,n2))

image.png

矩阵转换

矩阵转置

使用T属性实现矩阵转置。

import numpy as np
n1 = np.mat('1 3 3;4 5 6;7 12 9')
print(n1)
print('矩阵转置结果为:',n1.transpose(),sep='\n')  #n1.transpose()可以用n1.T代替

image.png

矩阵求逆

矩阵要可逆,否则意味着该矩阵为奇异矩阵(即矩阵的行列式的值为0)。矩阵求逆主要使用I属性。

import numpy as np

n1 = np.mat('1 3 3;4 5 6;7 12 9')
print(n1)
print('矩阵求逆结果为:',n1.I,sep='\n')