什么是 NumPy?
NumPy是Python中科学计算的基础包。它是一个Python库,提供多维数组对象,各种派生对象(如掩码数组和矩阵),以及用于数组快速操作的各种API,有包括数学、逻辑、形状操作、排序、选择、输入输出、离散傅立叶变换、基本线性代数,基本统计运算和随机模拟等等。
NumPy包的核心是 ndarray 对象。它封装了python原生的同数据类型的 n 维数组,为了保证其性能优良,其中有许多操作都是代码在本地进行编译后执行的。
NumPy数组 和 原生Python Array(数组)之间有几个重要的区别:
- NumPy 数组在创建时具有固定的大小,与Python的原生数组对象(可以动态增长)不同。更改ndarray的大小将创建一个新数组并删除原来的数组。
- NumPy 数组中的元素都需要具有相同的数据类型,因此在内存中的大小相同。 例外情况:Python的原生数组里包含了NumPy的对象的时候,这种情况下就允许不同大小元素的数组。
- NumPy 数组有助于对大量数据进行高级数学和其他类型的操作。通常,这些操作的执行效率更高,比使用Python原生数组的代码更少。
- 越来越多的基于Python的科学和数学软件包使用NumPy数组; 虽然这些工具通常都支持Python的原生数组作为参数,但它们在处理之前会还是会将输入的数组转换为NumPy的数组,而且也通常输出为NumPy数组。换句话说,为了高效地使用当今科学/数学基于Python的工具(大部分的科学计算工具),你只知道如何使用Python的原生数组类型是不够的 - 还需要知道如何使用 NumPy 数组。
安装最新的numpy
安装最新的稳定版本:pip install numpy
import numpy as np
print(np.__version__)
arr1 = np.array((1, 2, 3))
# arr1 = np.array(range(1, 4))
# arr1 = np.array([1, 2, 3])
print(arr1)
print(type(arr1))
print(isinstance(arr1, np.ndarray))
# print(isinstance(arr1, Iterable))
numpy的常用属性
# a = np.arange(15).reshape(3, 5)
a = np.array([
[[1, 2, 3], [4, 5, 6]],
[[7, 8, 9], [10,11, 12.]]
], dtype=np.int32)
print ("数组的形状:",a.shape)
print ("数组轴的个数:",a.ndim)
print ("数组元素类型:",a.dtype)
print ("数组中每个元素的字节大小:",a.itemsize)
print ("数组元素的总个数:", a.size)
print ("类型查询:",type(a))
print ("------------")
#创建一个数组
b = np.array([6, 7, 8])
print ("数组b:",b)
print ("数组的形状:",b.shape)
print ("数组轴的个数:",b.ndim)
print ("数组b类型:",type(b))
ndarray的常用函数
ndarray 多维数组(N Dimension Array)
NumPy数组是一个多维的数组对象(矩阵),称为ndarray,具有矢量算术运算能力和复杂的广播能力,并具有执行速度快和节省空间的特点。注意:ndarray的下标从0开始,且数组里的所有元素必须是相同类型。
array()
import numpy as np
a = np.array([2, 3, 4])
print ("数组a元素类型:",a)
print ("数组a类型:",a.dtype)
b = np.array([1.2, 3.5, 5.1])
print ("数组b元素类型:",b.dtype)
zeros() /ones()/empty()
函数function创建一个全是0的数组,函数ones创建一个全1的数组,函数empty创建一个内容随机并且依赖于内存状态的数组。默认创建的数组类型(dtype)都是float64
zeros1=np.zeros( (3,4) )
print ("数组zeros1:",zeros1)
ones1=np.ones((2,3,4))
print ("数组ones1:",ones1)
empty1 = np.empty((2, 3))
print ("数组empty1:",empty1)
arange()
arange() 类似 python 的 range() ,创建一个一维 ndarray 数组。
np_arange = np.arange(10, 20, 5,dtype=int)
print ("arange创建np_arange:",np_arange)
print( "arange创建np_arange的元素类型:",np_arange.dtype)
print ("arange创建np_arange的类型:",type(np_arange))
matrix()
matrix 是 ndarray 的子类,只能生成 2 维的矩阵
x1=np.mat("1 2;3 4")
print( x1)
x2=np.matrix("1,2;3,4")
print( x2)
x3=np.matrix([[1,2,3,4],[5,6,7,8]])
print( x3)
创建随机数矩阵random.rand()
import numpy as np
# 生成指定维度大小(3行4列)的随机多维浮点型数据(二维),rand固定区间0.0 ~ 1.0
arr = np.random.rand(3, 4)
print(arr)
print(type(arr))
# 生成指定维度大小(3行4列)的随机多维整型数据(二维),randint()可以指定区间(-1, 5)
arr = np.random.randint(-1, 5, size = (3, 4))
print(arr)
print(type(arr))
# 生成指定维度大小(3行4列)的随机多维浮点型数据(二维),uniform()可以指定区间(-1, 5)产生-1到5之间均匀分布的样本值
arr = np.random.uniform(-1, 5, size = (3, 4)) #
print(arr)
print(type(arr))
ndarray的数据类型
- dtype参数,指定数组的数据类型,类型名+位数,如float64, int32
- astype方法,转换数组的数据类型
# 初始化3行4列数组,数据类型为float64
zeros_float_arr = np.zeros((3, 4), dtype=np.float64)
print(zeros_float_arr)
print(zeros_float_arr.dtype) #float64
# astype转换数据类型,将已有的数组的数据类型转换为int32
zeros_int_arr = zeros_float_arr.astype(np.int32)
print(zeros_int_arr)
print(zeros_int_arr.dtype) #int32
等比/等差数列
np.logspace等比数列
logspace中,开始点和结束点是10的幂
我们让开始点为0,结束点为0,元素个数为10,看看输出结果。
a = np.logspace(0,0,10)
a
# 输出结果
# array([ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
● 我们看下面的例子,0代表10的0次方,9代表10的9次方。
a = np.logspace(0,9,10)
a
# 输出结果
# array([1.e+00, 1.e+01, 1.e+02, 1.e+03, 1.e+04, 1.e+05, 1.e+06, 1.e+07,
# 1.e+08, 1.e+09])
● 假如,我们想要改变基数,不让它以10为底数,我们可以改变base参数,将其设置为2试试。
a = np.logspace(0,9,10,base=2)
a
# 输出结果
# array([ 1., 2., 4., 8., 16., 32., 64., 128., 256., 512.])
np.linspace等差数列
np.linspace是用于创建一个一维数组,并且是等差数列构成的一维数组,它最常用的有三个参数。
● 第一个例子,用到三个参数,第一个参数表示起始点,第二个参数表示终止点,第三个参数表示数列的个数。
a = np.linspace(1,10,10)
a
# 输出结果
# array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.])
● linspace创建的数组元素是浮点型。
a.dtype
# 输出结果
# dtype('float64')
● 可以使用参数endpoint来决定是否包含终止值,默认值为True。
a = np.linspace(1,10,10,endpoint=False)
a
# 输出结果
# array([ 1. , 1.9, 2.8, 3.7, 4.6, 5.5, 6.4, 7.3, 8.2, 9.1])
NumPy内置函数
基本函数
- np.ceil(): 向上最接近的整数,参数是 number 或 array
- np.floor(): 向下最接近的整数,参数是 number 或 array
- np.rint(): 四舍五入,参数是 number 或 array
- np.isnan(): 判断元素是否为 NaN(Not a Number),参数是 number 或 array
- np.multiply(): 元素相乘,参数是 number 或 array
- np.divide(): 元素相除,参数是 number 或 array
- np.abs():元素的绝对值,参数是 number 或 array
- np.where(condition, x, y): 三元运算符,x if condition else y
# randn() 返回具有标准正态分布的序列。
arr = np.random.randn(2,3)
print(arr)
print(np.ceil(arr))
print(np.floor(arr))
print(np.rint(arr))
print(np.isnan(arr))
print(np.multiply(arr, arr))
print(np.divide(arr, arr))
print(np.where(arr > 0, 1, -1))
统计函数
- np.mean(), np.sum():所有元素的平均值,所有元素的和,参数是 number 或 array
- np.max(), np.min():所有元素的最大值,所有元素的最小值,参数是 number 或 array
- np.std(), np.var():所有元素的标准差,所有元素的方差,参数是 number 或 array
- np.argmax(), np.argmin():最大值的下标索引值,最小值的下标索引值,参数是 number 或 array
- np.cumsum(), np.cumprod():返回一个一维数组,每个元素都是之前所有元素的 累加和 和 累乘积,参数是 number 或 array
多维数组默认统计全部维度,axis参数可以按指定轴心统计,值为0则按列统计,值为1则按行统计。
arr = np.arange(12).reshape(3,4)
print(arr)
print(np.cumsum(arr)) # 返回一个一维数组,每个元素都是之前所有元素的 累加和
print(np.sum(arr)) # 所有元素的和
print(np.sum(arr, axis=0)) # 数组的按列统计和
print(np.sum(arr, axis=1)) # 数组的按行统计和
比较函数
假如我们想要知道矩阵a和矩阵b中所有对应元素是否相等,我们需要使用all方法,假如我们想要知道矩阵a和矩阵b中对应元素是否有一个相等,我们需要使用any方法。
- np.any(): 至少有一个元素满足指定条件,返回True
- np.all(): 所有的元素满足指定条件,返回True
arr = np.random.randn(2,3)
print(arr)
print(np.any(arr > 0))
print(np.all(arr > 0))
去重函数
np.unique():找到唯一值并返回排序结果,类似于Python的set集合
arr = np.array([[1, 2, 1], [2, 3, 4]])
print(arr)
print(np.unique(arr))
排序函数
对数组元素进行排序
arr = np.array([1, 2, 34, 5])
print ("原数组arr:",arr)
#np.sort()函数排序,返回排序后的副本
sortarr1= np.sort(arr)
print ("numpy.sort()函数排序后的数组:",sortarr1)
# ndarray直接调用sort,在原数据上进行修改
arr.sort()
print ("数组.sort()方法排序:",arr)
NumPy运算
基本运算
数组的算数运算是按照元素的。新的数组被创建并且被结果填充。
import numpy as np
a = np.array([20,30,40,50])
b = np.arange(4)
c = a-b
print("数组a:",a)
print("数组b:",b)
print("数组运算a-b:",c)
矩阵乘法
import numpy as np
x=np.array([[1,2,3],[4,5,6]])
y=np.array([[6,23],[-1,7],[8,9]])
print(x)
print(y)
print(x.dot(y))
print(np.dot(x,y))
a = np.array([[1,2,3], [4,5,6]])
b = np.array([[2,2,2],[3,3,3]])
print(a*b)
索引和切片
数组的索引和切片与 Python 中序列的索引和切片操作基本类似,不同点在于: 数组切片不会复制内部数组数据,只会生成原始数据的新视图数组支持多维数组的多维索引和切片
下标切片
slice对象
# slice 是一个实现切片的对象,主要用在切片操作函数里的参数传递。
# class slice(start, stop[, step])
# start 为切片起始位置,stop 为切片终止位置(不包括以 stop 索引的元素),step 为步长。
x = np.arange(10)
# 冒号 : 的解释:如果只放置一个参数,
# 如 [2],将返回与该索引相对应的单个元素。
# 如果为 [2:],表示从该索引开始以后的所有项都将被提取。
# 如果使用了两个参数,如 [2:8],那么则提取两个索引(不包括停止索引)之间的项。
arr_cut = slice(2,8,3)
print(x[arr_cut])
索引切片
import numpy as np
lis = [[1, 2], [3, 4], [5, 6]]
arr = np.array(lis)
print(arr)
print ("数组的形状:",arr.shape)
print ("数组轴的个数:",arr.ndim)
print ("数组元素类型:",arr.dtype)
print ("数组中每个元素的字节大小:",arr.itemsize)
print ("数组元素的总个数:", arr.size)
print ("类型查询:",type(arr))
print ("------------------")
print(arr[1, 0])
print ("------------------")
print(arr[1][1])
print ("------------------")
print(arr[:2, 1:2])
print ("------------------")
print(arr[:2][1:2])
# arr[:2, 1:2]是对多维数组进行同时切片操作,而arr[:2][1:2]是对切片结果进行连续切片操作,两者的结果会有所不同。
# print(arr[:2, 1:2]): 这种语法是对多维数组进行切片操作。
# 在这种情况下,arr[:2, 1:2]表示获取二维数组中行索引在0到1(不包括2)之间,列索引在1到2(不包括2)之间的子数组。换句话说,这个操作将获取二维数组的前两行中第二列的元素组成的子数组。
# print(arr[:2][1:2]): lis[:2]将会获取列表的前两个元素,即[[1, 2], [3, 4]],然后[1:2]将会获取该切片中的第二个元素,即[3, 4]。因此,print(result)的输出结果将会是[3, 4]。
[:2, 1:2])与[:2][1:2]的区别
arr[:2, 1:2]是对多维数组进行同时切片操作,
arr[:2][1:2]是对切片结果进行连续切片操作,两者的结果会有所不同。
布尔索引及切片
布尔型索引指的是一个布尔型ndarray数组(一般为一维)对应另一个ndarray数组的每行,布尔型数组的个数要必须与另一个多维数组的行数一致。若布尔型数组内的某个元素为True,则选取另一个多维数组的行,反之不选取。
# 布尔型索引及切片
# 布尔型索引指的是一个布尔型ndarray数组(一般为一维)对应另一个ndarray数组的每行,布尔型数组的个数要必须与另一个多维数组的行数一致。若布尔型数组内的某个元素为True,则选取另一个多维数组的行,反之不选取。
import numpy as np
zarten = np.random.randn(5,4)
print(zarten)
print('*' * 50)
## 选取第一行和最后一行
zarten_bool = np.array([True, False, False, False, True])
print(zarten[zarten_bool])
zarten = np.random.randn(5,4)
print(zarten)
print('*' * 50)
zarten_1 = np.array(['A', 'B', 'C', 'D', 'A'])
print(zarten[zarten_1 == 'A'])
print('*' * 50)
print(zarten[zarten_1 == 'A', 1:3]) #切片
花式索引及切片
花式索引跟布尔型索引类似,花式索引是可以使用整数数组进行索引,可以选取任意的行,跟布尔型索引的[True, False , False]类似,可以任意选取。花式索引更方便些。
注意:花式索引是传入整数数组。若为负数,将从末尾开始选取
import numpy as np
zarten = np.random.randn(5,4)
print(zarten)
print('*' * 50)
#选取第一行和第二行
#布尔型索引做法
zarten_bool = np.array([True, True, False, False, False])
print(zarten[zarten_bool])
print('*' * 50)
#花式索引做法
print(zarten[[0, 1]])
print('*' * 50)
#花式索引切片做法
print(zarten[[0, 1], 1:3])
axis参数
在numpy中,axis参数用于指定沿着哪个轴进行操作,例如对于一个二维数组,轴0表示沿着行的方向,轴1表示沿着列的方向。对于多维数组,每一个轴都对应一个维度。在numpy中许多函数都支持axis参数,常见的函数包括sum(),mean(),max(),min(),argmax()和argmin()等。
例如,对于以下二维数组:
arr = np.array([[1, 2, 3], [4, 5, 6]])
我们可以统计每列的和:
np.sum(arr, axis=0) # 返回数组 [5, 7, 9]
也可以统计每行的平均值:
np.mean(arr, axis=1) # 返回数组 [2., 5.]
需要注意的是,axis参数不止可以取0和1这样的值,对于多维数组,还可以取2,3等。而且,不同的函数对于axis参数的实现方式也可能有所不同,因此具体使用时需要查看文档或者自行尝试以确保正确使用。