Numpy 学习
Ndarray对象
特点
-
N 维数组对象 一系列同类型数据的集合 下标从0开始
-
每个元素在内存中占有相同存储大小
-
由什么构成
- 指向数据(内存中的一块数据)的指针
- 元素的数据类型dtype,指示数组中固定大小的格子
- 表示数组形状(shape)的元组,表示每一维的大小
- 跨度元组(stride)指示前进到当前维度下一个元素需要跨多少字节长度
构造
nd.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0 )
参数说明:
名称 | 描述 |
---|---|
object | 数组或嵌套的数列、元组(用什么来初始化n维数组) |
dtype | 数组元素的数据类型,可选 |
copy | 对象是否需要复制,可选 |
order | 创建数组的样式,C为行方向,F为列方向,A为任意方向(默认) |
subok | 默认返回一个与基类类型一致的数组 |
ndmin | 指定生成数组的最小维度 |
数据类型 dtype
numpy自带类型
-
bool_
-
int_
-
int8
-
int16
-
int32
-
int64
int8, int16, int32, int64 四种数据类型可以使用字符串 ‘i1’, ‘i2’,‘i4’,‘i8’ 代替
-
-
uint8 12 32 64
-
float_
- float16 32 64
-
complex_
- complex64 128
内建类型都有一个唯一定义它的字符代码,如下:
字符 | 对应类型 |
---|---|
b | 布尔型 |
i | (有符号) 整型 |
u | 无符号整型 integer |
f | 浮点型 |
c | 复数浮点型 |
m | timedelta(时间间隔) |
M | datetime(日期时间) |
O | (Python) 对象 |
S, a | (byte-)字符串 |
U | Unicode |
V | 原始数据 (void) |
dtype 表述数组的内存区域如何使用: 存储什么类型的数据,占有多大的内存 ,依赖于
- 数据类型
- 数据大小
- 字节顺序(大端 还是小端)
- 元素是结构化数据类型: 字段的名称、每个字段的数据类型、以及每个字段占内存的大小
- 数据类型是字数组,形状和数据类型
构造
numpy.dtype(object, align, copy)
通过自带类型的组合成自己想要的类型
-
object - 要转换为的数据类型对象
-
align - 如果为 true,填充字段使其类似 C 的结构体。 大端还是小端 可以使用’<i4’表示
-
copy - 复制 dtype 对象 ,如果为 false,则是对内置数据类型对象的引用
创建成功后表示一个结构数据类型, ndarray的每个元素都是这个类型,类似类的实例
结构化数据类型使用
-
结构化数据类型对象使用列表[]括起来, 每个数据类型用()括起来,包括字段名+ 字段值类型
dt = np.dtype([('age','i1')]) >>> dt dtype([('age', 'i1')]) >>> np.array([12, 16], dtype = dt) array([(12,), (16,)], dtype=[('age', 'i1')]) >>> arr = np.array([12, 16], dtype = dt) >>> arr['age'] array([12, 16], dtype=int8) >>> arr[0]['age'] 12
-
构建ndarray对象的时候,每个元素数据由()括起来,并按照dtype数据类型的顺序赋值
Numpy 数组属性
维度
-
秩 rank 或 轴 axis
-
axis = 0 表示第一轴, 按列看 对每一列进行操作; axis= 1 表示第二轴, 按行看,对每一行进行操作
NumPy 的数组中比较重要 ndarray 对象属性有:
属性 | 说明 |
---|---|
ndarray.ndim | 秩,即轴的数量或维度的数量 |
ndarray.shape | 数组的维度,对于矩阵,n 行 m 列 只有一个参数的话 (2,)表示有2列 可以通过直接赋值来改变维度 或者 通过 reshape |
ndarray.size | 数组元素的总个数,相当于 .shape 中 n*m 的值 |
ndarray.dtype | ndarray 对象的元素类型 |
ndarray.itemsize | ndarray 对象中每个元素的大小,以字节为单位 |
ndarray.flags | ndarray 对象的内存信息 |
ndarray.real | ndarray元素的实部 |
ndarray.imag | ndarray 元素的虚部 |
ndarray.data | 包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。 |
ndarray.T | 转置 |
ndarray.copy(oder) | 按order重新进行存储,直接赋值是指向同一块内存 |
创建数组
创建空数组
-
np.empty(shape, dtype = float, order = 'c')
创建一个
shape
规定的几维几列的数组, dtype 是元素数据类型,oder 是行优先还是列优先存储内存中因为没有初始化,每个元素值是随机值
-
np.zeros(shape, dtype = float, order = 'c')
默认是浮点数, 按列优先, 全0 数组
-
np.ones(shape, dtype = None, order = 'c')
数据类型可选 , 默认也是float ,全1数组
根据已有对象创建nd数组
-
通过
np.array(object, dtype=)
5个参数 -
np.asarray(a, dtype = None, order = None)
a 可以是 列表 元组、
-
numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)
用于实现动态数组。
参数说明:
参数 描述 buffer 可以是任意对象,会以流的形式读入。 dtype 返回数组的数据类型,可选 count 读取的数据数量,默认为-1,读取所有数据。 offset 读取的起始位置,默认为0。 -
numpy.fromiter(iterable, dtype, count=-1)
可迭代对象中建立 ndarray 对象,返回一维数组。
迭代对象 不知道数据类型,因此需要指定数据类型 dtype
从数值范围创建数组
-
numpy.arange(start, stop, step, dtype)
创建数值范围并返回 ndarray 对象
参数说明:
参数 描述 start
起始值,默认为 0
stop
终止值(不包含) step
步长,默认为 1
dtype
返回 ndarray
的数据类型,如果没有提供,则会使用输入数据的类型。 -
np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
创建等差数列, 给定起始结束值,和数列值的个数,自动设置步长进行划分
参数说明:
参数 描述 start
序列的起始值
可以从低到高,也可以从高到低stop
序列的终止值,如果 endpoint
为true
,该值包含于数列中num
要生成的等步长的样本数量,默认为 50
endpoint
该值为 true
时,数列中中包含stop
值,反之不包含,默认是True。retstep
如果为 True 时,生成的数组中会显示间距,反之不显示。
如过输出的时候设置为True,返回的是一个tuple对象,可供输出查看,不是ndarray对象
默认不显示dtype
ndarray
的数据类型 -
np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
创建一个于等比数列。
base 参数意思是取对数的时候 log 的下标。
参数 描述 start
序列的起始值为:base ** start stop
序列的终止值为:base ** stop。如果 endpoint
为true
,该值包含于数列中num
要生成的等步长的样本数量,默认为 50
endpoint
该值为 true
时,数列中中包含stop
值,反之不包含,默认是True。base
对数 log 的底数。 dtype
ndarray
的数据类型
访问数组
切片索引
ndarray 数组可以基于 0 - n 的下标进行索引(切片的时候可以写n 因为它不会取最后一个 ,但是索引的时候不可以写n 越界),切片对象可以通过内置的 slice 函数,并设置 start, stop 及 step 参数进行,从原数组中切割出一个新数组。start stop是索引,不是表示第几个
-
a = np.arange(10) s = slice(2,7,2) # 从索引 2 开始到索引 7 停止,间隔为2 print (a[s])
slice 使用作为一个条件,得到的是一个slice类对象实例,通过它作为索引进行切片
-
冒号分隔切片参数
a = np.arange(10) b = a[2:7:2] # 从索引 2 开始到索引 7 停止,间隔为 2 print(b)
按索引进行切片,不会包含索引7
多维数组也可以进行切割,还可以使用省略号
print (a[...,1]) print(a[:, 1])
高级索引
一般访问多维数组采用 a[2][3] 或者 上面的切片 还可以一次访问多个位置元素
-
整数数组索引
x = np.array([[1, 2], [3, 4], [5, 6]]) y = x[[0,1,2], [0,1,0]] print (y)
将 全部要索引的坐标的第一维 坐标写到列表中, 第二维坐标写到列表中 然后作为参数 进行 索引
-
通过一个布尔数组来作为索引 来索引目标数组。
通过数组名对其中元素进行条件判断
- x[x > 5]
- ~np.isnan(x) 过滤掉空值
- a[np.iscomplex(a)]
-
花式索引
也是利用整数数组进行索引。
不同的是花式索引根据索引数组的值作为目标数组的某个轴的下标来取值
- 目标数组是一维 那就是 索引位置
- 二维的话 按照第几行进行索引
花式整数数组的值是负的话,那就是倒数的行数
-
传入多个索引数组(要使用np.ix_)
x[np.ix_([1,5,7,2],[0,3,1,2])]
就是按照 第 1行 后面所有列进行索引
np.xi_ 中输入两个列表,则第一个列表存的是待提取元素的行标,第二个列表存的是待提取元素的列标,第一个列表中的每个元素都会遍历第二个列表中的每个值,构成新矩阵的一行元素。
总的来说
-
如果索引是一个数组,那就是花式索引
-
如果索引是多个数组,就按整数数组索引的最小的[] 进行判断 且格式是一样的
>>> a[[[1,2],[3,0]],[[1,2],[3,0]]] array([[ 6, 12], [18, 0]]) # 得到的序列与[[1,2],[3,0]] 格式一样
广播 数组计算
两个数组维数、且每一维的长度相同时,进行简单的计算。以上不相同时,触发广播机制
原理:
- 长数组的每一维长度相同 ,短数组只有1维,将短数组copyn维进行运算
- 或者短数组只有1维,且长度为1 ,将其copy成长数组形状进行运算
- 否则不能运算
判断过程:
对两个数组,分别比较他们的每一个维度(若其中一个数组没有当前维度则忽略),满足:
-
数组拥有相同形状。
-
当前维度的值相等。
-
当前维度的值有一个是 1。
若条件不满足,抛出 “ValueError: frames are not aligned” 异常。
tile(b,(m,n))
把某一个数组复制m行n列
迭代数组
迭代器对象 numpy.nditer 提供了一种灵活访问一个或者多个数组元素的方式。
可以通过for循环访问数组元素,在不知道数组形状的情况下
for x in np.nditer(a):
print (x, end=", " )
print ('\n')
- a 和 a.T 的遍历顺序是一样的,也就是他们在内存中的存储顺序也是一样的,默认按照内存存储顺序进行遍历,但是 a.T.copy(order = ‘C’) 的遍历结果是不同的,那是因为它和前两种的存储方式是不一样的,默认是按行访问。
修改遍历顺序
-
for x in np.nditer(a, order='F'):
Fortran order,即是列序优先; -
for x in np.nditer(a.T, order='C'):
C order,即是行序优先;显式设置,来强制 nditer 对象使用某种顺序:内存存储是按照默认顺序存储的,只是遍历的时候进行强制转移地址
迭代器进行遍历的同时修改元素值
nditer 对象有另一个可选参数 op_flags。 默认情况下,nditer 将视待迭代遍历的数组为只读对象(read-only),为了在遍历数组的同时,实现对数组元素值得修改,必须指定 read-write 或者 write-only 的模式。
遍历取值
for x in np.nditer(a, op_flags=['readwrite']):
x[...]=2*x
遍历得到多个元素组成的一数组 不是单个元素
for x in np.nditer(a, flags = ['external_loop'], order = 'F'):
print (x, end=", " )
同时遍历多个可广播的数组
a : 3*4
b : 1*4
for x,y in np.nditer([a,b]):
print ("%d:%d" % (x,y), end=", " )
数组操作
修改数组形状
-
reshape(arr, newshape, order='C')
在不改变数据的条件下修改形状,返回一个副本
-
ndarray.flat
展平数组对数组中每个元素都进行处理,可以使用flat属性,该属性是一个数组元素迭代器:
for element in a.flat: print (element)
-
ndarray.flatten(order='C')
展平数组返回一份展开的数组拷贝(作为1维数组),对拷贝所做的修改不会影响原始数组
-
ndarray.ravel(order = 'c')
展平数组上面几种对array对象修改形状是不修改原始数组,ravel()函数会修改本数组
将原数组展开成一维数组 可以指定 ‘c’‘F’
翻转数组
-
numpy.transpose(arr, axes)
参数说明:
arr
:要操作的数组axes
:整数列表,对应维度,通常所有维度都会对换。
改变原数组的秩 和 形状。
-
ndarray.T
不会修改原数组,只是返回一个副本
-
numpy.rollaxis(arr, axis, start)
返回一个修改后的副本,不会修改原数组参数说明:
arr
:数组axis
:要向后滚动的轴,其它轴的相对位置不会改变start
:默认为零,表示完整的滚动。会滚动到特定位置。
相当于将立方体旋转
-
numpy.swapaxes(arr, axis1, axis2)
和上述功能一样,返回一个副本arr
:输入的数组axis1
:对应第一个轴的整数axis2
:对应第二个轴的整数
修改数组维度
-
np.broadcast(x,y)
广播用于模仿广播的对象,它返回一个对象,该对象封装了将一个数组广播到另一个数组的结果。
该函数使用两个数组作为输入参数
如果
b.iters
得到迭代器,每一个位置元素有两个,分别是广播后的x 和y数组对应位置的元素c.flat = [u + v for (u,v) in b]
计算两个维度不同的数组的加法运算
-
numpy.broadcast_to(array, shape, subok)
广播在原始数组上返回只读视图。 它通常不连续。 如果新形状不符合 NumPy 的广播规则,该函数可能会抛出ValueError。
-
numpy.expand_dims(arr, axis)
插入轴对这个arr数组对象插入一个轴,在axis的位置上
- 如果是0 a.shape 原来是(2,2) 插入之后就是(1,2,2)
- 如果是1 a.shape 原来是(2,2) 插入之后就是(2,1,2)
-
numpy.squeeze(arr, axis)
删除轴函数从给定数组的形状中删除一维的条目,函数格式如下:
-
arr
:输入数组 -
axis
:整数或整数元组,用于选择形状中一维条目的子集要删除的这一维 应该是只有一维 比如 .shape = (1,3,3) 那么axis =0 的就可以删除
-
连接数组
-
numpy.concatenate((a1, a2, ...), axis)
水平、垂直连接参数说明:
-
a1, a2, ...
:相同类型的数组 相同形状,维度和长度相同 -
axis
:沿着它连接数组的轴,默认为 0比如按第0轴,原来是(2,2),第0 轴就是按行进行连接,连接之后变成(4,2)
如果按第1轴,原来是(2,2) 连接之后就变成了(2,4)
不会创建新的轴
-
-
numpy.stack(arrays, axis)
增加维度函数用于沿新轴连接数组序列,格式如下:
参数说明:
-
arrays
相同形状的数组序列 -
axis
:返回数组中的轴,输入数组沿着它来堆叠会产生新的轴 如果沿0轴,就是直接添加一维,如果是沿1轴,就是将原来的行轴立起来作为深度
-
-
numpy.hstack((arr,arr)
numpy.stack 函数的变体,它通过水平堆叠来生成数组。
直接扩展低维的长度,不会产生新的轴
-
numpy.vstack((arr,arr)
是 numpy.stack 函数的变体,它通过垂直堆叠来生成数组。
垂直方向的维度的长度扩增没有产生新的轴
分割数组
-
numpy.split(ary, indices_or_sections, axis)
将一个数组分割为多个子数组 函数沿特定的轴将数组分割为子数组,
参数说明:
-
ary
:被分割的数组 -
indices_or_sections
:如果是一个整数,就用该数平均切分,如果是一个数组,为沿轴切分的位置(左开右闭)数组的时候,数组边界值作为切割点 下界属于第2部分,上界属于第三部分
-
axis
:沿着哪个维度进行切向,默认为0,横向切分。为1时,纵向切分
-
-
numpy.hsplit(indices_or_sections)
用于水平分割数组,通过指定要返回的相同形状的数组数量来拆分原数组。(按列)
-
numpy.vsplit (indices_or_sections)
沿着垂直轴分割,其分割方式与hsplit用法相同。
按行进行分隔
数组元素的添加与删除
-
numpy.resize(arr, shape)
返回指定大小的新数组。
使用这个可以将小的数组转换成大的 比如(2,3)的可以转换成(3,3)的,但是内容会有重复
reshape()虽然也可以改变数组大小,但是元素的数量不可以改变,否则报错,这是不同的地方。
-
numpy.append(arr, values, axis=None)
在数组的末尾添加值。 追加操作会分配整个数组,并把原来的数组复制到新数组中。 此外,输入数组的维度必须匹配否则将生成ValueError。
参数说明:
arr
:输入数组values
:要向arr
添加的值,需要和arr
形状相同(除了要添加的轴) 维度需要是一样的,指定维的长度也需要相等axis
:默认为 None。当axis无定义时,是横向加成,**返回总是为一维数组!**当axis有定义的时候,分别为0和1的时候。当axis为1时,数组是加在右边(行数要相同)。
-
numpy.insert(arr, obj, values, axis)
函数在给定索引之前,沿给定轴在输入数组中插入值。
如果值的类型转换为要插入,则它与输入数组不同。 插入没有原地的,函数会返回一个新数组。 此外,如果未提供轴,则输入数组会被展开。
参数说明:
arr
:输入数组obj
:在其之前插入值的索引values
:要插入的值axis
:沿着它插入的轴,如果未提供,则输入数组会被展开
注:
-
如果axis的值未提供,在插入之前输入数组会被展开,索引值也是按行平展开后的一维数组的索引进行插入,
-
如果axis=0,则按行索引进行插入,如果提供的values与行的长度不同,短的话进行广播之后添加
如果axis=1,则按列索引进行插入,如果提供的value与列的长度不同,短的话进行广播之后添加
-
Numpy.delete(arr, obj, axis)
函数返回从输入数组中删除指定子数组的新数组。 与 insert() 函数的情况一样,如果未提供轴参数,则输入数组将展开。
参数说明:
-
arr
:输入数组 -
obj
:可以被切片,整数或者整数数组,表明要从输入数组删除的子数组如果是单个整数,
- 且axis没有给出的情况下,平展开之间按索引删除单个元素
- 如果axis给出的情况下,比如axis =0,则这个整数指的是行的索引,按此进行删除一整行
- 如果axis=1,则指的是列的索引,按此索引删除一整列
-
axis
:沿着它删除给定子数组的轴,如果未提供,则输入数组会被展开
-
-
numpy.unique(arr, return_index, return_inverse, return_counts)
函数用于去除数组中的重复元素。
参数说明:
arr
:输入数组,如果不是一维数组则会展开return_index
:如果为true
,返回新列表元素在旧列表中的位置(下标),并以列表形式储return_inverse
:如果为true
,返回旧列表元素在新列表中的位置(下标),并以列表形式储return_counts
:如果为true
,返回去重数组中的元素在原数组中的出现次数
位运算
NumPy “bitwise_” 开头的函数是位运算函数。
NumPy 位运算包括以下几个函数:
函数 | 描述 |
---|---|
bitwise_and | 对数组元素执行位与操作 |
bitwise_or | 对数组元素执行位或操作 |
invert | 按位取反 |
left_shift | 向左移动二进制表示的位 |
right_shift | 向右移动二进制表示的位 |
字符串函数
函数在字符数组类(numpy.char)中定义。
函数 | 描述 |
---|---|
add() | 对两个数组的逐个字符串元素进行连接 |
multiply() | 返回按元素多重连接后的字符串 |
center() | 居中字符串 |
capitalize() | 将字符串第一个字母转换为大写 |
title() | 将字符串的每个单词的第一个字母转换为大写 |
lower() | 数组元素转换为小写 |
upper() | 数组元素转换为大写 |
split() | 指定分隔符对字符串进行分割,并返回数组列表 |
splitlines() | 返回元素中的行列表,以换行符分割 |
strip() | 移除元素开头或者结尾处的特定字符 |
join() | 通过指定分隔符来连接数组中的元素 |
replace() | 使用新字符串替换字符串中的所有子字符串 |
decode() | 数组元素依次调用str.decode |
encode() | 数组元素依次调用str.encode |
数学函数
下面函数的参数都可以是数组
三角函数
NumPy 提供了标准的三角函数:sin()、cos()、tan()。
arcsin,arccos,和 arctan 函数返回给定角度的 sin,cos 和 tan 的反三角函数。
这些函数的结果可以通过 numpy.degrees() 函数将弧度转换为角度。
舍入函数
- numpy.around() 函数返回指定数字的四舍五入值。
numpy.around(a,decimals)
默认舍入到小数点后面
1 的话舍入到小数点后1位
-1 舍入到小数点前1位
-
numpy.floor()
numpy.floor() 返回小于或者等于指定表达式的最大整数,即向下取整。
-
numpy.ceil()
返回大于或者等于指定表达式的最小整数,即向上取整。
算数函数
-
加减乘除: add(),subtract(),multiply() 和 divide()
-
numpy.reciprocal()
函数返回参数逐元素的倒数 -
numpy.power()
函数将第一个输入数组中的元素作为底数,计算它与第二个输入数组中相应元素的幂参数可以是单个数 也可以是一个数组,与第一个参数arr的长度相同
-
numpy.mod()
计算输入数组中相应元素的相除后的余数。 函数numpy.remainder()
也产生相同的结果。
统计函数
-
numpy.amin()
用于计算数组中的元素沿指定轴的最小值。第二个参数是轴 沿哪一个维度去取值
-
numpy.amax()
用于计算数组中的元素沿指定轴的最大值。
关于 axis的 方向:
axis=i,则Numpy沿着第i个下标变化的方向进行操作
- 比如axis=1,本来表示第1层即按列,进行amax()运算的时候按列下标变化的方向进行操作,也就变成列对每一行进行统计
具体见知乎解答
-
numpy.ptp()
函数计算数组中元素最大值与最小值的差(最大值 - 最小值)没有给出axis值的话,默认按展开之后进行计算。
- 如果axis=0 则沿0层下标变化的方向进行统计,统计完之后0层维度遭到降维
- axis =1,则按列下标变化的方向进行统计,统计完之后1层维度消失i
-
numpy.percentile(a, q, axis)
百分位数是统计中使用的度量,表示小于这个值的观察值的百分比。这个函数就是用来计算数组的某一轴数中某一百分比的数是多少(某一轴的amin作为最低,amax作为最高,求中间百分数)
参数说明:
- a: 输入数组
- q: 要计算的百分位数,在 0 ~ 100 之间
- axis: 沿着它计算百分位数的轴
-
numpy.median()
函数用于计算数组 a 中元素的中位数(中值)也可以指定轴来计算
-
numpy.mean()
函数返回数组中元素的算术平均值。 如果提供了轴,则沿其计算。 -
numpy.average()
函数根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值。该函数可以接受一个轴参数。 如果没有指定轴,则数组会被展开。returned 参数设为 true,则返回权重的和
加权平均值即将各数值乘以相应的权数,然后加总求和得到总体值,再除以总的单位数。
考虑数组[1,2,3,4]和相应的权重[4,3,2,1],通过将相应元素的乘积相加,并将和除以权重的和,来计算加权平均值。
加权平均值 = (1*4+2*3+3*2+4*1)/(4+3+2+1)
-
标准差
numpy.std(a)
标准差是一组数据平均值分散程度的一种度量。
标准差是方差的算术平方根。
标准差公式如下:
std = sqrt(mean((x - x.mean())**2))
-
方差
numpy.var(a)
排序、条件过滤
-
numpy.sort()
函数返回输入数组的排序副本。函数格式如下:numpy.sort(a, axis, kind, order)
参数说明:
-
a: 要排序的数组
-
axis: 沿着它排序数组的轴,如果没有数组会被展开(并没有),沿着最后的轴排序, axis=0 按行下标变化的方向,axis=1 按列下标变化的方向进行排序
-
kind: 默认为’quicksort’(快速排序)
除了快排 还有其他的方法,差别在于
种类 速度 最坏情况 工作空间 稳定性 'quicksort'
(快速排序)1 O(n^2)
0 否 'mergesort'
(归并排序)2 O(n*log(n))
~n/2 是 'heapsort'
(堆排序)3 O(n*log(n))
0 否 -
order: 如果数组包含字段,则是要排序的字段
数据类型是结构化数据类型,那么排序的时候可以通过
order
指定排序字段名
-
-
numpy.argsort()
函数返回的是数组值从小到大的索引值。对一维数组排序得到的是一个索引列表,多维数组排序得到的是多个索引列表,每一个表示1个维度的全部索引
怎么使用呢?
可以通过
x[y]
按排序后的顺序重构原数组 -
numpy.lexsort((a,b))
用于对多个序列进行排序。放在后面的序列b的优先级最高,然后从后往前依次降低。 排序结束返回的是索引列表
例子:
import numpy as np # 录入了四位同学的成绩,按照总分排序,总分相同时语文高的优先 math = (10, 20, 50, 10) chinese = (30, 50, 40, 60) total = (40, 70, 90, 70) # 将优先级高的项放在后面 ind = np.lexsort((math, chinese, total)) for i in ind: print(total[i],chinese[i],math[i]) # 结果如下 40 30 10 70 50 20 70 60 10 90 40 50
-
msort、sort_complex、partition、argpartition
函数 描述 msort(a) 数组按第一个轴排序,返回排序后的数组副本。np.msort(a) 相等于 np.sort(a, axis=0)。 sort_complex(a) 对复数按照先实部后虚部的顺序进行排序。 partition(a, kth[, axis, kind, order]) 指定一个数,对数组进行分区
这个数字是sort排完序之后,小于索引为num(第三个数 不是从0算起) 的元素放在该数字前面,比该数字大的放到该数字后面argpartition(a, kth[, axis, kind, order]) 可以通过关键字 kind 指定算法沿着指定轴对数组进行分区 -
numpy.nonzero()
函数返回输入数组中非零元素的索引。如果是多维数组,返回的是多个数组,每个数组指示某一维的非零元素在原数组的位置,这两个数组的对应位置组合起来得到的位置才是非零元素在原数组的位置
-
numpy.where()
函数返回输入数组中满足给定条件的元素的索引。参数可以写各种判断条件语句 比如(== != > < )
还可以直接使用
a[a>9]
返回的是数组满足条件的数据而不是索引列表 -
numpy.extract()
函数根据某个条件从数组中抽取元素,返回满条件的元素。例子:
x = np.arange(9.).reshape(3, 3) print ('我们的数组是:') print (x) # 定义条件, 选择偶数元素 condition = np.mod(x,2) == 0 print ('按元素的条件值:') print (condition) print ('使用条件提取元素:') print (np.extract(condition, x))
可以用来提取指定条件的值
字节交换
多字节对象都被存储为连续的字节序列,分为大端模式 和 小端模式
-
numpy.ndarray.byteswap()
函数将 ndarray 中每个元素中的字节进行大小端转换参数设置为True即可
视图 与 副本⚑
副本是一个数据的完整的拷贝,如果我们对副本进行修改,它不会影响到原始数据,物理内存不在同一位置。
视图是数据的一个别称或引用,通过该别称或引用亦便可访问、操作原有数据,但原有数据不会产生拷贝。如果我们对视图进行修改,它会影响到原始数据,物理内存在同一位置。
视图一般发生在:
-
1、numpy 的切片操作返回原数据的视图。
这里list 与 numpy的切片有一些区别:
-
list2=list1 直接赋值,实质上指向的是同一个内存值。任意一个变量 list1(或list2)发生改变,都会影响另一个 list2(或list1)。
-
而 list3 和 list4 是通过切片对 list1 的复制操作,分别指向了新的值。任意改变 list3 或 list4 的值,不会影响其他。
-
数组切片是原始数组的视图,这意味着数据不会被复制,视图上的任何修改都会被直接反映到源数组上。
array1, array2, array3, array4 实际指向同一个内存值,任意修改其中的一个变量,其他变量值都会被修改。
-
-
2、调用 ndarray 的 view() 函数产生一个视图。
id()返回 Python 对象的通用标识符,类似于 C 中的指针。通过view()创建的视图的id不是一样的,因此对b的修改并不会导致a 的元素变化
副本一般发生在:
-
Python 序列的切片操作,调用deepCopy()函数。
-
调用 ndarray 的 copy() 函数产生一个副本。
副本的id不一样,因此一个修改并不会改变另一个
矩阵库(Matrix)
基本对象
NumPy 中包含了一个矩阵库 numpy.matlib,该模块中的函数返回的是一个矩阵,而不是 ndarray 对象。
-
numpy.matlib.empty(shape, dtype, order)
函数返回一个新的矩阵
参数说明:
- shape: 定义新矩阵形状的整数或整数元组
- Dtype: 可选,数据类型
- order: C(行序优先) 或者 F(列序优先)
默认填充的是随机数据
-
numpy.matlib.zeros()
函数创建一个以 0 填充的矩阵。 -
numpy.matlib.ones()
函数创建一个以 1 填充的矩阵。 -
numpy.matlib.eye()
函数返回一个矩阵,主对角线元素为 1,其他位置为零。函数格式如下:
numpy.matlib.eye(n, M,k, dtype)
参数说明:
- n: 返回矩阵的行数
- M: 返回矩阵的列数,默认为 n
- k: 对角线的索引
- dtype: 数据类型
主对角线为1的矩阵, 但是不一定是单位矩阵,行 和 列可以不相同
-
numpy.matlib.identity()
函数返回给定大小的单位矩阵。和上面
eye()
函数的功能差不多,但是得到的是单位矩阵可以指定dtype
-
numpy.matlib.rand()
函数创建一个给定大小的矩阵,数据是随机填充的
矩阵总是二维的,而 ndarray 是一个 n 维数组。 两个二维的对象之间都是可互换的。
>>> i = np.matrix('1,2;3,4')
>>> i
matrix([[1, 2],
[3, 4]])
>>> j = np.asarray(i)
>>> j
array([[1, 2],
[3, 4]])
>>> k = np.asmatrix(j)
>>> k
matrix([[1, 2],
[3, 4]])
矩阵线性代数
-
numpy.dot()
对于两个一维的数组,计算的是这两个数组对应下标元素的乘积和(数学上称之为内积);对于二维数组,计算的是两个数组的矩阵乘积;对于多维数组,它的通用计算公式如下,即结果数组中的每个元素都是:数组a的最后一维上的所有元素与数组b的倒数第二位上的所有元素的乘积和: dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])。
简单来说,就是a第i行 乘以 b的第j列求和作为 结果的(i,j)位置的元素
-
numpy.vdot()
函数是两个向量的点积。 如果第一个参数是复数,那么它的共轭复数会用于计算。 如果参数是多维数组,它会被展开。简单的说,就是最后得到一个标量值
-
numpy.inner()
函数返回一维数组的向量内积。对于更高的维度,它返回最后一个轴上的和的乘积。和 dot()函数功能一样
-
numpy.matmul()
函数返回两个数组的矩阵乘积。 虽然它返回二维数组的正常乘积,但如果任一参数的维数大于2,则将其视为存在于最后两个索引的矩阵的栈,并进行相应广播。另一方面,如果任一参数是一维数组,则通过在其维度上附加 1 来将其提升为矩阵,并在乘法之后被去除。
对于二维数组,它就是矩阵乘法.
可以实现不同维度的数组的向量乘积–自动进行广播
-
numpy.linalg.det()
函数计算输入矩阵的行列式。对于 2×2 矩阵,它是左上和右下元素的乘积与其他两个的乘积的差。
换句话说,对于矩阵[[a,b],[c,d]],行列式计算为 ad-bc
-
numpy.linalg.solve()
函数给出了矩阵形式的线性方程的解。 -
numpy.linalg.inv()
函数计算矩阵的乘法逆矩阵。逆矩阵(inverse matrix):设A是数域上的一个n阶矩阵,若在相同数域上存在另一个n阶矩阵B,使得: AB=BA=E ,则我们称B是A的逆矩阵,而A则被称为可逆矩阵。注:E为单位矩阵。逆矩阵和原矩阵的内急为单位矩阵
例子:
a = np.array([[1,1,1],[0,2,5],[2,5,-1]]) print ('数组 a:') print (a) ainv = np.linalg.inv(a) print ('a 的逆:') print (ainv) print ('矩阵 b:') b = np.array([[6],[-4],[27]]) print (b) print ('计算:A^(-1)B:') x = np.linalg.solve(a,b) print (x) # 这就是线性组的解
结果也可以使用以下函数获取:
x = np.dot(ainv,b)
绘图库
matplotlib