NumPy中数据类型包含array(数组)、matrix(矩阵)和character(字符串数组)。array类旨在成为用于多种数值计算的通用n维数组,matrix类则专门用于促进线性代数计算,而chararray类的存在是为了向后兼容Numarray(不建议用于新开发)。
本文主要介绍array类及其子类matrix的基本使用方法。
#导入numpy库
import numpy as np
#查看numpy库版本
np.__version__
一、array:一个具有矢量运算和复杂广播能力的快速且节省空间的多维数组,返回值为ndarray类型,ndarray里的数学运算默认为点乘
创建ndarray :两种方式,使用列表创建和使用函数创建
1 使用np.array由python list创建
- numpy默认ndarray的所有元素的类型是相同的,如果传进来的列表中包含不同的类型,则统一为同一类型,优先级:str>float>int
data = [1, 2, 3]
nd = np.array(data) # array([1, 2, 3])
2 使用np的routine函数创建(部分常用)
- np.ones(shape, dtype=None, order='C') 返回一个给定形状和类型的新数组,用一个填充。
- np.zeros(shape, dtype=float, order='C') 返回给定形状和类型的新数组,用零填充。
- np.full(shape, fill_value, dtype=None, order='C') 返回给定形状和类型的新数组,填充fill_value。
- np.eye(N, M=None, k=0, dtype=float) 返回一个二维数组,其中对角线为1,零点为零。
- np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None) 在指定的间隔内返回均匀间隔的数字。
- np.arange([start, ]stop, [step, ]dtype=None) 在给定的间隔内返回均匀间隔的值。
- np.random.randint(low, high=None, size=None, dtype='l') 生成多维随机数列
- np.random.randn(d0, d1, ..., dn) 正态分布
- np.random.normal(loc=0.0, scale=1.0, size=None) 标准正态分布
- np.random.random(size=None) 生成0-1的随机数,左闭右开
ndarray的属性
- ndarray.ndim 维度,即数组轴的个数,python中,轴的个数被称作秩
- ndarray.shape 形状(各维度的长度),是一个指示数组在每个维度上大小的整数元组。例如一个n排m列的矩阵,它的shape属性将是(n,m),这个元组的长度显然是秩,即维度或者ndim属性
- ndarray.size 数组元素的总个数,等于shape属性中元组元素的乘积。
- ndarray.dtype 一个用来描述数组中元素类型的对象,可以通过创造或指定dtype使用标准Python类型。
- ndarray.itemsize 数组中每个元素的字节大小。例如,一个元素类型为float64的数组itemsiz属性值为8(=64/8)
- ndarray.data 包含实际数组元素的缓冲区,通常不需要使用这个属性,因为我们总是通过索引来使用数组中的元素。
ndarray基本操作
1 索引:使用同列表
nd = np.random.randint(0,100, size = (4,4))
nd[1,1] # 使用同nd[1][1]
# 可以根据索引修改数据
nd[2,3] = 20
2 切片:使用同列表
#一维
nd[start:end:step]
#二维
nd[row_start:row_end:step,col_start:col_end:step]
#二维数组赋值:如果赋值的数据不足,numpy会自动填充,例如:本来是2,2的数据,现在只填充一个数据,numpy会把这一个数据赋值给这四个数据,这种方式叫广播机制
nd[row_start:row_end,col_start:col_end] = np.random.randint(start,end,size = (1,1))
#三维
nd[row_start:row_end:step,col_start:col_end:step,index] # x行y列的第index个数据
3 变形
- reshape(a, new_shape[, order]) 返回一个数组,该数组包含具有新形状的相同数据。reshape可以传负数,实现降维(升维)操作。
nd1 = nd.reshape(new_shape)
# 重塑形状的数据的个数必须和原来的数据保持一致,比如:原来是3*4,重塑形状的数量也必须为12(如2*6)
data = np.array([[1,1],[2,2],[3,3]]) # (3,2)
data.reshape(-1).shape # (6,)
data.reshape(-1,1).shape # (6, 1)
data.reshape(1,-1).shape # (1, 6)
- a.ravel([order]) 返回一个扁平的数组。(一维)
4 级联
1)多个数组之间进行级联
- concatenate(arrays[, axis]) 沿给定轴连接一系列数组。
需要注意:参数为列表(一定要加中括号或小括号);维度必须相同;形状必须相符;级联的方向默认是shape这个tuple的第一个值所代表的维度方向,可通过axis参数改变级联的方向(axis为0以行为轴,axis为1以列为轴)
nd1 = np.random.randint(0,10,size = (4,6))
nd2 = np.random.randint(50,100, size = (2,6))
np.concatenate([nd1,nd2], axis = 0) # 以行进行级联 保证列必须相同
nd1 = np.random.randint(0,10,size = (4,6))
nd2 = np.random.randint(50,100, size = (4,3))
np.concatenate([nd1,nd2], axis = 1) # 以列进行级联 保证行必须相同
2)同一个数组进行水平级联与垂直级联(进行维度的变更)
- hstack(tup) 按顺序堆叠数组(列式)
- vstack(tup) 垂直堆叠数组(行方式)
nd = np.random.randint(0,10,size = (10,1))
np.hstack(nd) # 把列变成行,看并且维度降维了
np.vstack(nd) # 把行变成列, 并且维度增加
- 当以数组作为参数使用时,r_ 和c_ 类似于其默认行为中的 vstack 和 hstack ,但是允许一个可选参数给出要沿其连接的轴的编号。
X_test = np.c_[aa.ravel(), bb.ravel()] # c_水平叠加两个数组(把两个一维数组,分别依据元素的位置进行合并)
5 切分
- split(ary, indices_or_sections[, axis]) 将数组拆分为多个子数组。
- hsplit(ary, indices_or_sections) 将数组水平拆分为多个子数组(按列)。
- vsplit(ary, indices_or_sections) 将数组垂直拆分为多个子数组(逐行)。
nd = np.random.randint(0,100,size = (5,6))
'''
array([[42, 99, 41, 0, 23, 46],
[22, 43, 34, 32, 10, 73],
[80, 70, 83, 94, 72, 49],
[87, 58, 30, 37, 7, 33],
[73, 10, 27, 81, 21, 35]])
'''
np.vsplit(nd, [1,2,3])
'''
[array([[42, 99, 41, 0, 23, 46]]),
array([[22, 43, 34, 32, 10, 73]]),
array([[80, 70, 83, 94, 72, 49]]),
array([[87, 58, 30, 37, 7, 33],
[73, 10, 27, 81, 21, 35]])]
'''
np.hsplit(nd, [1,3,5])
'''
[array([[42],
[22],
[80],
[87],
[73]]), array([[99, 41],
[43, 34],
[70, 83],
[58, 30],
[10, 27]]), array([[ 0, 23],
[32, 10],
[94, 72],
[37, 7],
[81, 21]]), array([[46],
[73],
[49],
[33],
[35]])]
'''
np.split(nd, [2],axis = 1) # axis = 0 , 同vsplit ; axis = 1 , 同hsplit
'''
[array([[42, 99],
[22, 43],
[80, 70],
[87, 58],
[73, 10]]), array([[41, 0, 23, 46],
[34, 32, 10, 73],
[83, 94, 72, 49],
[30, 37, 7, 33],
[27, 81, 21, 35]])]
'''
6 副本
1)浅拷贝:所有赋值运算不会为ndarray的任何元素创建副本。对赋值后的对象的操作也对原来的对象生效。
nd_copy = nd
2)深拷贝:对深拷贝后的对象的操作不会对原来的对象生效。
- copy([order]) 返回数组的副本。
nd_copy = nd.copy()
ndarray常用聚合函数
- prod(a[, axis, dtype, out, keepdims]) 返回给定轴上的数组元素的乘积。
- nanprod(a[, axis, dtype, out, keepdims]) 返回给定轴上的数组元素的乘积,将非数字(NaN)视为1。
- sum(a[, axis, dtype, out, keepdims]) 给定轴上的数组元素的总和。
- nansum(a[, axis, dtype, out, keepdims]) 返回给定轴上的数组元素的总和,将非数字(NaN)视为零。
- mean([axis, dtype, out, keepdims]) 返回给定轴上数组元素的平均值
- nanmean(a[, axis, dtype, out, keepdims]) 计算沿指定轴的算术平均值,忽略NAS。
- std(a[, axis, dtype, out, ddof, keepdims]) 计算沿指定轴的标准偏差。
- nanstd(a[, axis, dtype, out, ddof, keepdims]) 计算指定轴上的标准偏差,而忽略NAS。
- var(a[, axis, dtype, out, ddof, keepdims]) 计算沿指定轴的方差。
- nanvar(a[, axis, dtype, out, ddof, keepdims]) 计算指定轴上的方差,同时忽略NAS。
- max([axis, out, fill_value, …]) 沿给定轴返回最大值。
- nanmax(a[, axis, out, keepdims]) 返回数组的最大值或沿轴方向的最大值,忽略任何NAS。
- argmax(a[, axis, out]) 返回沿轴的最大值的索引。
- nanargmax(a[, axis]) 返回指定轴上最大值的索引,忽略NAS。
- min([axis, out, keepdims]) 沿给定轴返回最小值。
- nanmin(a[, axis, out, keepdims]) 返回数组的最小值或沿轴的最小值,忽略任何NAS。
- argmin(a[, axis, out]) 返回沿轴的最小值的索引。
- nanargmin(a[, axis]) 返回指定轴上的最小值的索引,忽略NAS。
- power(x1, x2, /[, out, where, casting, …]) 第一个数组元素从第二个数组提升到幂,逐个元素。
- median(a[, axis, out, overwrite_input, keepdims]) 沿指定轴计算中值。
- nanmedian(a[, axis, out, overwrite_input, …]) 在忽略NAS的情况下,沿指定的轴计算中值。
- percentile(a, q[, axis, out, …]) 计算数据沿指定轴的第qth百分位数。
- nanpercentile(a, q[, axis, out, …]) 在忽略NaN值的情况下,沿着指定的轴计算数据的第qth百分位数。
- any([axis, out, keepdims]) 如果求值的任何元素为True,则返回True。
- all([axis, out, keepdims]) 如果所有元素都计算为True,则返回True。
ndarray的矩阵操作
1 基本矩阵操作
1)算术运算符
nd = np.random.randint(0,10,size = (5,5))
np.add(nd, 3) # 同nd + 3
np.subtract(nd, 3) # 同nd - 3
np.multiply(nd, 3) # 同nd * 3
np.divide(nd, 3) # 同nd / 3
2)矩阵函数
- np.meshgrid(*xi, **kwargs) 从坐标向量返回坐标矩阵。
a = np.array([4,5,6,7])
b = np.array([2,3,4])
aa,bb = np.meshgrid(a,b)
'''
array([[4, 5, 6, 7],
[4, 5, 6, 7],
[4, 5, 6, 7]])
'''
'''
array([[2, 2, 2, 2],
[3, 3, 3, 3],
[4, 4, 4, 4]])
'''
aa.ravel() # array([4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7])
bb.ravel() # array([2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4])
- dot(a, b[, out]) 两个数组的点积。(矩阵积)
nd1 = np.random.randint(0,10,size = (2,3))
nd2 = np.random.randint(1,10,size = (3,2))
np.dot(nd1,nd2)
2 广播机制
- 为缺失维度补1
- 假定缺失元素用已有值填充
a = np.arange(3).reshape((3,1)) # 3行1列
b = np.arange(3) # 1行3列
a + b # 3行3列
ndarray的排序
def sort_nd(nd):
for i in range(nd.size):
for j in range(i, nd.size):
if nd[i] > nd[j]:
nd[i],nd[j] = nd[j], nd[i]
return nd
def sort_nd2(nd):
for i in range(nd.size):
index_min = np.argmin(nd[i:])+ i
#当 i = 0 index_min = 9,
#当 i = 1 index_min = 9
#当 i = 2 index_min = 5
nd[i], nd[index_min] = nd[index_min], nd[i]
return nd
1 快速排序
- np.sort(a[, axis, kind, order]) 返回数组的排序副本。 不改变输入
- ndarray.sort([axis, kind, order]) 就地对数组进行排序。 本地处理,不占用空间,但改变输入
2 部分排序
- ndarray.partition(kth[, axis, kind, order]) 重新排列数组中的元素,使得第k个位置的元素值处于排序数组中的位置。(k为正时,得到最小的k个数;k为负时,得到最大的k个数)
二、matrix:matrix对象继承自ndarray,因此,它们具有相同的ndarrays属性和方法。其返回值为matrices类型
创建matrix
- matrix(data[, dtype, copy]) 从类数组对象或数据字符串返回矩阵。
参数data可以是字符串
a=np.mat('1 2 3; 4 5 3') # "mat"是NumPy中"matrix"的别名。
'''
matrix([[1, 2, 3],
[4, 5, 3]])
'''
嵌套序列
np.mat([[1,5,10],[2,3,4]])
'''
matrix([[ 1, 5, 10],
[ 2, 3, 4]])
'''
数组
mat = np.mat(np.random.rand(2,2))
'''
matrix([[0.85493952, 0.43864614],
[0.82225678, 0.84431019]])
'''
- asmatrix(data[, dtype]) 将输入解释为矩阵。
- bmat(obj[, ldict, gdict]) 从字符串,嵌套序列或数组构建矩阵对象。
matrix对象的属性
- matrix.T [transpose] 返回矩阵的转置矩阵
- matrix.H [hermitian (conjugate) transpose] 返回复数矩阵的共轭元素矩阵
- matrix.I [inverse] 返回矩阵的(乘法)逆矩阵
- matrix.A [base array] 返回矩阵基于的数组(将自己作为ndarray对象返回。)