numpy 总结笔记
偶然翻到一篇以前整理的numpy笔记,由于数据分析是人工智能很重要很基础的内容,因此稍作整理和大家共享
一、Ndarray 对象
ndarray 内部由以下内容组成:
-
一个指向数据(内存 | 内存映射文件中的一块数据)的指针。
-
数据类型或 dtype,描述在数组中的 固定大小值的格子。
-
一个表示数组形状(shape)的元组,表各维度大小的元组。
-
一个跨度元组(stride),其中的整数指的是 为了前进到当前维度 下一个元素需要"跨过"的字节数。
跨度可以是负数,这样会使数组在内存中后向移动,切片中 obj[::-1] 或 obj[:,::-1] 就是如此。
创建一个 ndarray 只需调用 NumPy 的 array 函数即可:
numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
参数说明:
名称 | 描述 |
---|---|
object | 数组或嵌套的数列 |
dtype | 数组元素的数据类型,可选 |
copy | 对象是否需要复制,可选 |
order | 创建数组的样式,C为行方向,F为列方向,A为任意方向(默认) |
subok | 默认返回一个与基类类型一致的数组 |
ndmin | 指定生成数组的最小维度 |
二、NumPy 数据类型
1):基本数据类型
名称 | 描述 |
---|---|
bool_ | 布尔型数据类型(True 或者 False) |
int_ | 默认的整数类型(类似于 C 语言中的 long,int32 或 int64) |
intc | 与 C 的 int 类型一样,一般是 int32 或 int 64 |
intp | 用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64) |
int8 | 字节(-128 to 127) |
int16 | 整数(-32768 to 32767) |
int32 | 整数(-2147483648 to 2147483647) |
int64 | 整数(-9223372036854775808 to 9223372036854775807) |
uint8 | 无符号整数(0 to 255) |
uint16 | 无符号整数(0 to 65535) |
uint32 | 无符号整数(0 to 4294967295) |
uint64 | 无符号整数(0 to 18446744073709551615) |
float_ | float64 类型的简写 |
float16 | 半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位 |
float32 | 单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位 |
float64 | 双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位 |
complex_ | complex128 类型的简写,即 128 位复数 |
complex64 | 复数,表示双 32 位浮点数(实数部分和虚数部分) |
complex128 | 复数,表示双 64 位浮点数(实数部分和虚数部分) |
-
numpy 的数值类型实际上是 dtype 对象的实例,并且对应唯一的字符,如 np.bool_,np.int32,np.float32,等等。
-
int8, int16, int32, int64 四种数据类型可以使用字符串 ‘i1’, ‘i2’,‘i4’,‘i8’ 代替
2):数据类型对象dtype
dtype 对象使用以下语法构造:
numpy.dtype(object, align, copy)
-
object 要转换为的数据类型对象
-
align 如果为 true,填充字段使其类似 C 的结构体。
-
copy 复制 dtype 对象 ,若为 false,则是对内置数据类型对象的引用
每个内建类型都有一个唯一定义它的字符代码,如下:
字符 | 对应类型 |
---|---|
b | 布尔型 |
i | (有符号) 整型 |
u | 无符号整型 integer |
f | 浮点型 |
c | 复数浮点型 |
m | timedelta(时间间隔) |
M | datetime(日期时间) |
O | (Python) 对象 |
S, a | (byte-)字符串 |
U | Unicode |
V | 原始数据 (void) |
实例:
print(np.dtype(np.int32))
>int32
print(np.dtype('i4'))
>int32
print(np.dtype('<i4'))
>int32
print(np.dtype([('age',np.int8)]))
>[('age', 'i1')]
dt = np.dtype([('age',np.int8)])
print(np.array([(10,),(20,),(30,)], dtype = dt))
>[(10,) (20,) (30,)]
dt = np.dtype([('age',np.int8)])
a = np.array([(10,),(20,),(30,)], dtype = dt)
print(a['age'])
>[10 20 30]
student = np.dtype([('name','S20'), ('age', 'i1'), ('marks', 'f4')])
print(student)
>[('name', 'S20'), ('age', 'i1'), ('marks', 'f4')]
student = np.dtype([('name','S20'), ('age', 'i1'), ('marks', 'f4')])
print(np.array([('abc', 21, 50),('xyz', 18, 75)], dtype = student))
>[('abc', 21, 50.0), ('xyz', 18, 75.0)]
三、数组
1):数组属性
属性 | 说明 |
---|---|
ndarray.ndim | 秩,即轴的数量或维度的数量 |
ndarray.shape | 数组的维度,对于矩阵,n 行 m 列 |
ndarray.size | 数组元素的总个数,相当于 .shape 中 n*m 的值 |
ndarray.dtype | ndarray 对象的元素类型 |
ndarray.itemsize | ndarray 对象中每个元素的大小,以字节为单位 |
ndarray.flags | ndarray 对象的内存信息 |
ndarray.real | ndarray 元素的实部 |
ndarray.imag | ndarray 元素的虚部 |
ndarray.data | 包含实际数组元素的缓冲区由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。 |
ndarray.reshape | ndarray重新分配大小,包括秩等等都可以变换 |
ndarray.flags 返回 ndarray 对象的内存信息,包含以下属性:
属性 | 描述 |
---|---|
C_CONTIGUOUS © | 数据是在一个单一的C风格的连续段中 |
F_CONTIGUOUS (F) | 数据是在一个单一的Fortran风格的连续段中 |
OWNDATA (O) | 数组拥有它所使用的内存或从另一个对象中借用它 |
WRITEABLE (W) | 数据区域可以被写入,将该值设置为 False,则数据为只读 |
ALIGNED (A) | 数据和所有元素都适当地对齐到硬件上 |
UPDATEIFCOPY (U) | 这个数组是其它数组的一个副本当这个数组被释放时,原数组的内容将被更新 |
实例:
x = np.array([1,2,3,4,5])
print (x.flags)
>C_CONTIGUOUS : True
>F_CONTIGUOUS : True
>OWNDATA : True
>WRITEABLE : True
>ALIGNED : True
>WRITEBACKIFCOPY : False
>UPDATEIFCOPY : False
a = np.array([[1,2,3],[4,5,6]])
a.shape = (3,2)
print (a)
>[[1 2]
[3 4]
[5 6]]
# 数组的 dtype 为 int8(一个字节)
x = np.array([1,2,3,4,5], dtype = np.int8)
print (x.itemsize)
# 数组的 dtype 现在为 float64(八个字节)
y = np.array([1,2,3,4,5], dtype = np.float64)
print (y.itemsize)
-
一个元素类型为float64的数组,itemsize属性值为8(float64占用64个bits,每个字节长度为8,所以64/8占用 8 个字节)
-
一个元素类型为complex32的数组item属性为4(32/8)
2):创建数组
numpy.zeros(shape, dtype = float, order = 'C')
numpy.ones(shape, dtype = None, order = 'C')
# 默认为浮点数
x = np.ones(5) print(x)
# 设置类型为整数
y = np.zeros((5,), dtype = np.int) print(y)
# 自定义类型
z = np.zeros((2,2), dtype = [('x', 'i4'), ('y', 'i4')]) print(z)
# 输出
[1. 1. 1. 1. 1.]
[0 0 0 0 0]
[[(0, 0) (0, 0)]
[(0, 0) (0, 0)]]
3):从已有的数组创建数组
1、asarray
numpy.asarray(a, dtype = None, order = None)
属性 | 描述 |
---|---|
a | 任意形式的输入参数,可以是 列表, 列表的元组, 元组, 元组的元组, 元组的列表,多维数组 |
dtype | 数据类型,可选 |
order | 可选,有"C"和"F"两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序。 |
x = [(1,2,3),(4,5)] a = np.asarray(x)
print (a)
# 输出
[(1, 2, 3) (4, 5)]
2、numpy.frombuffer
numpy.frombuffer 用于实现动态数组。
numpy.frombuffer 接受 buffer 输入参数,以流的形式读入转化成 ndarray 对象。
numpy.frombuffer(buffer, dtype = float, count = -1, offset = 0)
- 注:
buffer是字符串的时候,Python3默认str是Unicode 类型所以要转成bytestring在原str前加上b。
参数 | 描述 |
---|---|
buffer | 可以是任意对象,会以流的形式读入 |
dtype | 返回数组的数据类型,可选 |
count | 读取的数据数量,默认为-1,读取所有数据 |
offset | 读取的起始位置,默认为0 |
s = b'Hello World' a = np.frombuffer(s, dtype = 'S1')
print (a)
# 输出
[b'H' b'e' b'l' b'l' b'o' b' ' b'W' b'o' b'r' b'l' b'd']
3、numpy.fromiter
numpy.fromiter 方法从可迭代对象中建立 ndarray 对象,返回一维数组。
numpy.fromiter(iterable, dtype, count=-1)
参数 | 描述 |
---|---|
iterable | 可迭代对象 |
dtype | 返回数组的数据类型 |
count | 读取的数据数量,默认为-1,读取所有数据 |
# 使用 range 函数创建列表对象
list=range(5)
it=iter(list)
# 使用迭代器创建 ndarray
x=np.fromiter(it, dtype=float)
print(x)
# 输出
[0. 1. 2. 3. 4.]
4):从数值范围创建数组
1、numpy.arange
numpy 包中的使用 arange 函数创建数值范围并返回 ndarray 对象:
numpy.arange(start, stop, step, dtype)
参数 | 描述 |
---|---|
start | 序列的起始值 |
stop | 序列的终止值,若endpoint为true,该值包含于数列中 |
num | 要生成的等步长的样本数量,默认为50 |
endpoint | 该值为 true 时,数列中包含stop值,反之不包含,默认True |
retstep | 如果为 True 时,生成的数组中会显示间距,反之不显示 |
dtype | ndarray 的数据类型 |
2、numpy.logspace
numpy.logspace 函数用于创建一个于等比数列。格式如下:
np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
参数 | 描述 |
---|---|
start | 序列的起始值为:base ** start |
stop | 序列的终止值为:base ** stop。如果endpoint为true,该值包含于数列中 |
num | 要生成的等步长的样本数量,默认为50 |
endpoint | 该值为true时,数列中中包含stop值,反之不包含,默认True |
base | 对数 log 的底数,取对数的时候 log 的下标 |
dtype | ndarray 的数据类型 |
print (np.logspace(1.0, 2.0, num = 10))
>[ 10. 12.91549665 16.68100537 21.5443469 27.82559402
35.93813664 46.41588834 59.94842503 77.42636827 100. ]
print (np.logspace(0,9,10,base=2))
>[ 1. 2. 4. 8. 16. 32. 64. 128. 256. 512.]
3、索引、切片
a = np.arange(10)
s = slice(2,7,2) # 从索引 2 开始到索引 7 停止,间隔为2
print (a[s])
>[2 4 6]
b = a[2:7:2] # 从索引 2 开始到索引 7 停止,间隔为 2
print(b)
>[2 4 6]
切片还可以包括省略号 …
,来使选择元组的长度与数组的维度相同。
如果在行位置使用省略号,它将返回包含行中元素的 ndarray。
a = np.array([[1,2,3],[3,4,5],[4,5,6]])
print (a[...,1]) # 第2列元素
print (a[1,...]) # 第2行元素
print (a[...,1:]) # 第2列及剩下的所有元素
# 输出
>[2 4 5]
>[3 4 5]
>[[2 3]
[4 5]
[5 6]]
4、高级索引
- 整数索引
x = np.array([[1, 2], [3, 4], [5, 6]])
y = x[[0,1,2], [0,1,0]]
print (y)
# 输出
[1 4 5]
- 布尔索引
我们可以通过一个布尔数组来索引目标数组。
布尔索引通过布尔运算(如:比较运算符)来获取符合指定条件的元素的数组。
如大于 5 的元素:print (x[x > 5])
使用 ~
(取补运算符)来过滤 NaN:
a = np.array([np.nan, 1,2,np.nan,3,4,5]) print (a[~np.isnan(a)])
- 花式索引
关于 np.ix_ 的具体使用:
x[np.ix_([1,5,7,2],[0,3,1,2])]
这句话会输出一个4*4的矩阵,其中的元素分别是:
x[1,0] x[1,3] x[1,1] x[1,2]
x[5,0] x[5,3] x[5,1] x[5,2]
x[7,0] x[7,3] x[7,1] x[7,2]
x[2,0] x[2,3] x[2,1] x[2,2]
相当于:
y=np.array([[x[1,0], x[1,3], x[1,1], x[1,2]],\
[x[5,0], x[5,3], x[5,1],x[5,2]],\
[x[7,0] ,x[7,3], x[7,1], x[7,2]],\
[x[2,0], x[2,3], x[2,1], x[2,2]]])
就是说,如果 np.xi_ 中输入两个列表,则第一个列表存的是待提取元素的行标,第二个列表存的是待提取元素的列标,第一个列表中的每个元素都会遍历第二个列表中的每个值,构成新矩阵的一行元素。
5、数组广播
广播的规则:
-
让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加 1 补齐。
-
输出数组的形状是输入数组形状的各个维度上的最大值。
-
如果输入数组的某个维度和输出数组的对应维度的长度相同或者其长度为 1 时,这个数组能够用来计算,否则出错。
-
当输入数组的某个维度的长度为 1 时,沿着此维度运算时都用此维度上的第一组值。
简单理解:对两个数组,分别比较他们的每一个维度(若其中一个数组没有当前维度则忽略),满足:
-
数组拥有相同形状。
-
当前维度的值相等。
-
当前维度的值有一个是 1。
若条件不满足,抛出 “ValueError: frames are not aligned” 异常。
6、迭代器
a = np.arange(6).reshape(2,3)
print ('迭代输出:')
for x in np.nditer(a):
print (x, end=", " )
# 迭代输出:
0, 1, 2, 3, 4, 5,
- 控制遍历顺序
for x in np.nditer(a, order='F'): Fortran order,即是列序优先;
for x in np.nditer(a.T, order='C'): C order,即是行序优先;
- 修改数组中元素的值
nditer 对象另一个可选参数 op_flags
默认情况下,nditer 将视待迭代遍历的数组为只读对象(read-only)
为了在遍历数组的同时,实现对数组元素值得修改
必须指定 read-write 或者 write-only 的模式。
a = np.arange(0,60,5) a = a.reshape(3,4)
print ('原始数组:') print (a) print ('\n')
for x in np.nditer(a, op_flags=['readwrite']):
x[...]=2*x
print ('改后数组:') print (a)
#原始数组: 改后数组:
[[ 0 5 10 15] [[ 0 10 20 30]
[20 25 30 35] [ 40 50 60 70]
[40 45 50 55]] [ 80 90 100 110]]
外部循环
nditer 类的构造器拥有 flags 参数,它可以接受下列值:
参数 | 描述 |
---|---|
c_index | 可以跟踪 C 顺序的索引 |
f_index | 可以跟踪 Fortran 顺序的索引 |
multi_index | 每次迭代可以跟踪一种索引类型 |
external_loop | 给出的值是具有多个值的一维数组,而不是零维数组 |
7、数组操作
- 修改数组形状
函数 | 描述 |
---|---|
reshape | 不改变数据的条件下修改形状 |
flat | 数组元素迭代器 |
flatten | 返回一份数组拷贝,对拷贝所做的修改不会影响原始数组 |
ravel | 返回展开数组 |
numpy.reshape(arr, newshape, order='C')
-
arr:要修改形状的数组
-
newshape:整数或者整数数组,新的形状应当兼容原有形状
-
order:‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘k’ – 元素在内存中的出现顺序。
ndarray.flatten(order='C')
numpy.ravel(a, order='C')
-
numpy.ravel() 展平的数组元素,顺序通常是"C风格",返回的是数组视图(view,类似 C/C++引用reference),修改会影响原始数组。
-
翻转数组
函数 | 描述 |
---|---|
transpose | 对换数组的维度 |
ndarray.T | 和 self.transpose() 相同,转置 |
rollaxis | 向后滚动指定的轴 |
swapaxes | 对换数组的两个轴 |
- 修改数组维度
维度 | 描述 |
---|---|
broadcast | 产生模仿广播的对象 |
broadcast_to | 将数组广播到新形状 |
expand_dims | 通过在指定位置插入新的轴扩展数组形状 |
squeeze | 从数组的形状中删除一维条目 |
- numpy.broadcast :
用于模仿广播的对象,它返回一个对象,该对象封装了将一个数组广播到另一个数组的结果。
x = np.array([[1], [2], [3]])
y = np.array([4, 5, 6])
# 对 y 广播 x
b = np.broadcast(x,y)
# 它拥有 iterator 属性,基于自身组件的迭代器元组
-
numpy.broadcast_to(array, shape, subok):
将数组广播到新形状。它在原始数组上返回只读视图。 它通常不连续。 如果新形状不符合 NumPy 的广播规则,该函数可能会抛出ValueError。
-
numpy.expand_dims(arr, axis)
arr:输入数组
axis:新轴插入的位置
-
numpy.squeeze(arr, axis)
-
连接数组
函数 | 描述 |
---|---|
concatenate | 连接沿现有轴的数组序列 |
stack | 沿着新的轴加入一系列数组。 |
hstack | 水平堆叠序列中的数组(列方向) |
vstack | 竖直堆叠序列中的数组(行方向) |
numpy.concatenate((a1, a2, ...), axis)
-
a1, a2, …:相同类型的数组
-
axis:沿着它连接数组的轴,默认为0,即为竖直方向链接。1为水平方向链接。
#沿轴 0 连接两个数组: 沿轴 1 连接两个数组:
[[1 2] [[1 2 5 6]
[3 4] [3 4 7 8]]
[5 6]
[7 8]]
numpy.stack(arrays, axis)
用于沿新轴连接数组序列
-
arrays相同形状的数组序列
-
axis:返回数组中的轴,输入数组沿着它来堆叠
# 沿轴 0 堆叠两个数组: 沿轴 1 堆叠两个数组:
[[[1 2] [[[1 2]
[3 4]] [5 6]]
[[5 6] [[3 4]
[7 8]]] [7 8]]]
-
numpy.hstack(array1, array2) 水平堆叠
-
numpy.vstack(array1, array2) 竖直堆叠
-
分割数组
函数 | 数组及操作 |
---|---|
split | 将一个数组分割为多个子数组 |
hsplit | 将一个数组水平分割为多个子数组(按列) |
vsplit | 将一个数组垂直分割为多个子数组(按行) |
numpy.split(ary, indices_or_sections, axis)
-
ary:被分割的数组
-
indices_or_sections:若是一个整数,就用该数平均切分,若是一个数组,为沿轴切分的位置(左开右闭)
-
axis:设置沿着哪个方向进行切分,默认为 0,水平切分。为 1 时,竖直切分。
print (np.split(a,[4,7]))
>[array([0, 1, 2, 3]), array([4, 5, 6]), array([7, 8])]
- 数组元素添加&删除
函数 | 元素及描述 |
---|---|
resize | 返回指定形状的新数组 |
append | 将值添加到数组末尾 |
insert | 沿指定轴将值插入到指定下标之前 |
delete | 删掉某个轴的子数组,并返回删除后的新数组 |
unique | 查找数组内的唯一元素 |
numpy.resize(arr, shape)
函数返回指定大小的新数组。
如果新数组大小大于原始大小,则包含原始数组中的元素的副本。
-
arr:要修改大小的数组
-
shape:返回数组的新形状
numpy.append(arr, values, axis=None)
函数在数组的末尾添加值。 追加操作会分配整个数组,并把原来的数组复制到新数组中。
输入数组的维度必须匹配否则将生成ValueError。
-
append 函数返回的始终是一个一维数组。
-
arr:输入数组
-
values:要向arr添加的值,需要和arr形状相同(除了要添加的轴)
-
axis:默认为 None。当axis无定义时,是横向加成,*返回总是为一维数组*。
- 当axis为0时,数组是加在下边(列数要相同)
- 当axis为1时,数组是加在右边(行数要相同)
numpy.insert(arr, obj, values, axis)
函数在给定索引之前,沿给定轴在输入数组中插入值。
如果值的类型转换为要插入,则它与输入数组不同。
插入没有原地的,函数会返回一个新数组。
如果未提供轴,则输入数组会被展开。
-
arr:输入数组
-
obj:在其之前插入值的索引
-
values:要插入的值
-
axis:沿着它插入的轴,如果未提供,则输入数组会被展开
Numpy.delete(arr, obj, axis)
函数返回从输入数组中删除指定子数组的新数组。 与 insert() 函数情况一样,如果未提供轴参数,则输入数组将展开。
-
arr:输入数组
-
obj:可以被切片,整数或者整数数组,表明要从输入数组删除的子数组
-
axis:沿着它删除给定子数组的轴,如果未提供,则输入数组会被展开
numpy.unique(arr, return_index, return_inverse, return_counts)
用于去除数组中的重复元素。
-
arr:输入数组,若不是一维数组则会展开
-
return_index:为true,返回新列表元素在旧列表中的位置(下标),并以列表形式储
-
return_inverse:为true,返回旧列表元素在新列表中的位置(下标),并以列表形式储
-
return_counts:为true,返回去重数组中的元素在原数组中的出现次数
8、numpy位运算
函数 | 描述 |
---|---|
bitwise_and | 对数组元素执行位与操作 |
bitwise_or | 对数组元素执行位或操作 |
invert | 按位取反 |
left_shift | 向左移动二进制表示的位 |
right_shift | 向右移动二进制表示的位 |
四、字符串
函数 | 描述 |
---|---|
add() | 对两个数组的逐个字符串元素进行连接 |
multiply() | 返回按元素多重连接后的字符串 |
center() | 居中字符串 |
capitalize() | 将字符串第一个字母转换为大写 |
title() | 将字符串的每个单词的第一个字母转换为大写 |
lower() | 数组元素转换为小写 |
upper() | 数组元素转换为大写 |
split() | 指定分隔符对字符串进行分割,并返回数组列表 |
splitlines() | 返回元素中的行列表,以换行符分割 |
strip() | 移除元素开头或者结尾处的特定字符 |
join() | 通过指定分隔符来连接数组中的元素 |
replace() | 使用新字符串替换字符串中的所有子字符串 |
decode() | 数组元素依次调用str.decode |
encode() | 数组元素依次调用str.encode |
五、统计
-
numpy.amin() 用于计算数组中的元素沿指定轴的最小值。
-
numpy.amax() 用于计算数组中的元素沿指定轴的最大值。
-
numpy.ptp() 计算数组中元素最大值与最小值的差(最大值 - 最小值)。
-
numpy.percentile(a, q, axis)
百分位数是统计中使用的度量,表示小于这个值的观察值的百分比。
-
a: 输入数组
-
q: 要计算的百分位数,在 0 ~ 100 之间
-
axis: 沿着它计算百分位数的轴
第 p 个百分位数是这样一个值,它使得至少有 p% 的数据项小于或等于这个值,且至少有 (100-p)% 的数据项大于或等于这个值。
例子:入学考试成绩以百分位数的形式报告。假设某个考生在考试中的语文部分的原始分数为 54 分。相对于参加同一考试的其他学生来说,他的成绩如何并不容易知道。但是如果原始分数54分恰好对应的是第70百分位数,我们就能知道大约70%的学生的考分比他低,而约30%的学生考分比他高。这里的 p = 70。
-
-
numpy.median() 函数用于计算数组 a 中元素的中位数(中值)
-
numpy.mean() 返回数组中元素的算术平均值。 如果提供了轴,则沿其计算。
算术平均值是沿轴的元素的总和除以元素的数量。
-
numpy.average() 根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值。该函数可以接受一个轴参数。 如果没有指定轴,则数组会被展开。
加权平均值即将各数值乘以相应的权数,然后加总求和得到总体值,再除以总的单位数。
$$
加权平均值 = \frac{1*4+2*3+3*2+4*1}{4+3+2+1}
$$ -
标准差
numpy.std = sqrt(mean((x - x.mean())**2))
-
方差
numpy.var = mean((x - x.mean())** 2)
六、排序、条件刷选函数
种类 | 速度 | 最坏情况 | 工作空间 | 稳定性 |
---|---|---|---|---|
‘quicksort’(快速排序) | 1 | O(n^2) | 0 | 否 |
‘mergesort’(归并排序) | 2 | O(n*log(n)) | ~n/2 | 是 |
‘heapsort’(堆排序) | 3 | O(n*log(n)) | 0 | 否 |
-
numpy.sort(a, axis, kind, order)
-
a: 要排序的数组
-
axis: 沿着排序数组的轴,若没有数组则会被展开,沿着最后的轴排序,0按列,1按行
-
kind: 默认’quicksort’
-order: 如果数组包含字段,则是要排序的字段
-
-
numpy.argsort() 返回的是数组值从小到大的索引值。
-
numpy.lexsort() 用于对多个序列进行排序。
想象成对电子表格进行排序,每一列代表一个序列,排序时优先照顾靠后的列。
例子:在总成绩相同时,数学成绩高的优先录取,在总成绩和数学成绩都相同时,按照英语成绩录取…… 这里,总成绩排在电子表格的最后一列,数学成绩在倒数第二列,英语成绩在倒数第三列。
a = ('aaaa','arrr','raaa','rrmm')
b = ('fy','sy','sy','fy')
ind = np.lexsort((a,b))
print(ind)
>[0 3 1 2]
print ([a[i] + ", " + b[i] for i in ind])
>['aaaa, fy', 'rrmm, fy', 'arrr, sy', 'raaa, sy']
函数 | 描述 |
---|---|
msort(a) | 数组按第一个轴排序,返回排序后的数组副本。np.msort(a) 相当于 np.sort(a, axis=0)。 |
sort_complex(a) | 对复数按照先实部后虚部的顺序进行排序。 |
partition(a, kth[, axis, kind, order]) | 指定一个数,对数组进行分区 |
argpartition(a, kth[, axis, kind, order]) | 可以通过关键字 kind 指定算法沿着指定轴对数组进行分区 |
-
numpy.argmax() & numpy.argmin() 分别沿给定轴返回最大和最小元素的索引。
-
numpy.nonzero() 函数返回输入数组中非零元素的索引。
-
numpy.where() 函数返回输入数组中满足给定条件的元素的索引。
-
numpy.extract() 函数根据某个条件从数组中抽取元素,返回满条件的元素。
七、字节交换
在几乎所有的机器上,多字节对象都被存储为连续的字节序列。字节顺序,是跨越多字节的程序对象的存储规则。
-
大端模式:
指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。
-
小端模式:
指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低。
例如:在 C 语言中,一个类型为 int 的变量 x 地址为 0x100,那么其对应地址表达式&x的值为 0x100。且x的四个字节将被存储在存储器的 0x100, 0x101, 0x102, 0x103位置。
- numpy.ndarray.byteswap() 将 ndarray 中每个元素中的字节进行大小端转换。
>>> A = np.array([1,256,8755],dtype=np.int16)
>>> print(list(map(hex,A)))
['0x1', '0x100', '0x2233']
>>> print(A.byteswap(inplace=True))
[ 256 1 13090]
>>> print(list(map(hex,A)))
['0x100', '0x1', '0x3322']
八、线性代数
函数 | 速度 |
---|---|
dot | 两个数组的点积,即元素对应相乘 |
vdot | 两个向量的点积 |
inner | 两个数组的内积 |
matmul | 两个数组的矩阵积 |
determinant | 数组的行列式 |
solve | 求解线性矩阵方程 |
inv | 计算矩阵的乘法逆矩阵 |
linalg.det | 计算矩阵的行列式 |
linalg.solve | 求解线性矩阵方程 |
九、I/O
NumPy 为 ndarray 对象引入了一个简单的文件格式:npy。
npy 文件用于存储重建 ndarray 所需的数据、图形、dtype 和其他信息。
常用的 IO 函数:
-
load() 和 save() 函数是读写文件数组数据的两个主要函数,默认情况下,数组是以未压缩的原始二进制格式保存在扩展名为 .npy 的文件中。
-
savez() 函数用于将多个数组写入文件,默认情况下,数组是以未压缩的原始二进制格式保存在扩展名为 .npz 的文件中。
-
loadtxt() 和 savetxt() 函数处理正常的文本文件(.txt 等)
-
numpy.save(file, arr, allow_pickle=True, fix_imports=True)
将数组保存到以 .npy 为扩展名的文件中。
它们是 Numpy 专用的二进制格式后的数据
使用 load() 函数来读取数据才可以正常显示
- file:要保存的文件,扩展名为 .npy,如果文件路径末尾没有扩展名 .npy,该扩展名会被自动加上。
- arr: 要保存的数组
- allow_pickle: 可选,布尔值,允许使用 Python pickles 保存对象数组,Python 中的 pickle 用于在保存到磁盘文件或从磁盘文件读取之前,对对象进行序列化和反序列化。
- fix_imports: 可选,为了方便 Pyhton2 中读取 Python3 保存的数据。
-
numpy.savez(file, *args, **kwds)函数将多个数组保存到以 npz 为扩展名的文件中。
- file:要保存的文件,扩展名为 .npz,如果文件路径末尾没有扩展名 .npz,该扩展名会被自动加上。
- args: 要保存的数组,可以用关键字参数为数组起名,非关键字参数传递的数组会自动起名为 arr_0, arr_1, … 。
- kwds: 要保存的数组使用关键字名称。
-
savetxt() 以简单的文本文件格式存储数据,对应使用 loadtxt() 函数来获取数据。
np.loadtxt(FILENAME, dtype=int, delimiter=' ')
np.savetxt(FILENAME, a, fmt="%d", delimiter=",")
参数 delimiter 可以指定各种分隔符、针对特定列的转换器函数、需要跳过的行数等。
a=np.arange(0,10,0.5).reshape(4,-1)
np.savetxt("out.txt",a,fmt="%d",delimiter=",") # 改为保存为整数,以逗号分隔
b = np.loadtxt("out.txt",delimiter=",") # load 时也指定为逗号分隔
print(b)
# 输出
[[0. 0. 1. 1. 2.]
[2. 3. 3. 4. 4.]
[5. 5. 6. 6. 7.]
[7. 8. 8. 9. 9.]]