Python的NumPy库(二)进阶用法

Python开发实用教程

接续前面的基础用法,本文学习NumPy的一些进阶用法,部分方法或函数或有重复,但主要是侧重于换个角度对这些方法的组织和学习。

数组迭代器

NumPy 提供了一个 nditer 迭代器对象,可以使用迭代器对数组进行遍历、修改等操作

遍历数组

nditer 迭代器可以配合 for 循环完成对数组元素的遍历。

import numpy as np
a = np.arange(0,60,5).reshape(3,4)
#使用nditer迭代器,并使用for进行遍历
for x in np.nditer(a):
    print(x)

for x in np.nditer(a.T):
    print(x)

‘’'
0
5
10
15
20
25
30
35
40
45
50
55
0
5
10
15
20
25
30
35
40
45
50
55
‘''

在内存中,Numpy 数组提供了两种存储数据的方式,分别是 C-order(行优先顺序)与 Fortrant-order(列优先顺序)。从上面的例子可以看到,a和a的转置(a.T)的遍历顺序是一样的,也就是说,它们在内存中的存储顺序是一样的。

下面以 C 样式访问转置数组的副本。示例如下:

import numpy as np
a = np.arange(0,60,5).reshape(3,4)

for x in np.nditer(a.T.copy(order='C')):
    print(x)

‘’'
0
20
40
5
25
45
10
30
50
15
35
55
‘''

可以看到,默认情况下,Python是以Fortrant-order(列优先顺序)存储的,在转成C的各式后,遍历的结果与此前不同。

nditer方法也可以直接指定遍历的顺序:

import numpy as np

a = np.arange(0,60,5).reshape(3,4)

for x in np.nditer(a, order='F'):
    print(x)
for x in np.nditer(a, order='C'):
    print(x)

修改数组元素

nditer 对象提供了一个可选参数op_flags,它表示能否在遍历数组时对元素进行修改。它提供了三种模式,如下所示:

  • read-only:只读模式,在这种模式下,遍历时不能修改数组中的元素。
  • read-write:读写模式,遍历时可以修改元素值。
  • write-only:只写模式,在遍历时可以修改元素值。
import numpy as np

a = np.arange(0,60,5).reshape(3,4)

for x in np.nditer(a, op_flags=['readwrite']):
    x[...] = 2*x
    #print(type(x)) #<class 'numpy.ndarray'>

print(a)

‘’'
[[  0  10  20  30]
 [ 40  50  60  70]
 [ 80  90 100 110]]
‘''

给元素赋值,一定要写成x[...]模式,直接写成x是没效果的。原因是x在这里的类型是<class 'numpy.ndarray'>

外部循环

nditer也可以作为外部循环使用,每次返回最低一个维度的数据。

nditer 对象的构造函数有一个“flags”参数,它可以接受以下参数值:

flags参数说明
参数值描述说明
c_index可以跟踪 C 顺序的索引。
f_index可以跟踪 Fortran 顺序的索引。
multi_index每次迭代都会跟踪一种索引类型。
external_loop返回的遍历结果是具有多个值的一维数组。
import numpy as np

a = np.arange(0,60,5).reshape(3,4)

for x in np.nditer(a, flags=['external_loop'], order = 'F'):
    print(f'-{x}’)

‘’'
-[ 0 20 40]
-[ 5 25 45]
-[10 30 50]
-[15 35 55]
‘''

一定要加上order = 'F',否则会把数组全部展开。

高纬度的情况可能看上去更复杂一些:

import numpy as np

a = np.arange(24).reshape(3,4,2)
print(a)
for x in np.nditer(a, flags=['external_loop'], order = 'F'):
    print(f'-{x}’)

‘’’
[[[ 0  1]
  [ 2  3]
  [ 4  5]
  [ 6  7]]

 [[ 8  9]
  [10 11]
  [12 13]
  [14 15]]

 [[16 17]
  [18 19]
  [20 21]
  [22 23]]]
-[ 0  8 16]
-[ 2 10 18]
-[ 4 12 20]
-[ 6 14 22]
-[ 1  9 17]
-[ 3 11 19]
-[ 5 13 21]
-[ 7 15 23]
’‘’

同时迭代多个数组

如果两个数组都能够被广播,那么 nditer 对象就可以同时对它们迭代。

import numpy as np

a = np.arange(12).reshape(3,4)
b = np.array([10,20,30,40])
for x,y in np.nditer([a, b]):
    print(f'{x},{y}’)

‘’'
0,10
1,20
2,30
3,40
4,10
5,20
6,30
7,40
8,10
9,20
10,30
11,40
‘''

注意:两个数组同时迭代,并不是笛卡尔积。

元素运算

NumPy提供了很多操作数组元素运算的方法,这里并不逐一举例,只是列表说明。

输入数组必须具有相同的形状,或者符合数组的广播规则,才可以执行运算。

数学运算

函数或方法名说明
np.add(a,b)逐个元素对应相加,生成一个新的形状相同的数组
np.subtract(a,b)逐个元素对应相减,生成一个新的形状相同的数组
np.multiply(a,b)逐个元素对应相乘,生成一个新的形状相同的数组
np.divide(a,b)逐个元素对应相除,生成一个新的形状相同的数组
np.true_divide(a,b)以元素方式返回输入的真正除法
np.divmode(a,b)返回逐元素的商和余数,返回两个数组构成的元组
np.negative(a)数字否定

np.absolute(a)

np.fabs(a)

逐个元素地计算绝对值
np.reciprocal(a)对数组中的每个元素取倒数,生成一个新的形状相同的数组
np.power(a,b)将 a 数组中的元素作为底数,把 b 数组中与 a 相对应的元素作幂 ,生成一个新的形状相同的数组

np.mod(a,b)

np.remainder(a,b)

逐个元素对应相除的余数生成一个新的形状相同的数组
np.real(a)逐个元素取实数部分,生成一个新的形状相同的数组
np.imag(a)逐个元素取虚数部分,生成一个新的形状相同的数组
np.conj(a)逐个元素更改虚部的符号得到共轭复数,生成一个新的形状相同的数组
np.angle(a, deg = True)逐个元素计算复数参数的角度,该函数的提供了一个 deg 参数,如果  deg=True,则返回的值会以角度制来表示,否则以以弧度制来表示。
np.sin(a)逐个元素求正弦,生成一个新的形状相同的数组
np.cos(a)逐个元素求余弦,生成一个新的形状相同的数组
np.tan(a)逐个元素求正切,生成一个新的形状相同的数组
np.arcsin(a)逐个元素求反正弦,生成一个新的形状相同的数组
np.arccos(a)逐个元素求反余弦,生成一个新的形状相同的数组
np.arctan(a)逐个元素求反正切,生成一个新的形状相同的数组
np.around(a,decimals)对数组的每个数值元素四舍五入到指定的小数位.

decimals:要舍入到的小数位数。它的默认值为0,如果为负数,则小数点将移到整数左侧。

np.floor(a)对数组中的每个元素向下取整数
np.ceil(a)对数组中的每个元素向上取整数
np.logaddexp(a,b)输入的取幂之和的对数。
greater(a,b)返回逐个元素的>比较结果的数组,生成一个新的形状相同的数组
greater_equal(a,b)返回逐个元素的>=比较结果的数组,生成一个新的形状相同的数组
less(a,b)返回逐个元素的<比较结果的数组,生成一个新的形状相同的数组
less_equal(a,b)返回逐个元素的<=比较结果的数组,生成一个新的形状相同的数组
not_equal(a,b)返回逐个元素的!=比较结果的数组,生成一个新的形状相同的数组
equal(a,b)返回逐个元素的==比较结果的数组,生成一个新的形状相同的数组
import numpy as np
a = np.arange(9, dtype = np.float_).reshape(3,3)
#数组a
print(a)
#数组b
b = np.array([10,10,10])
print(b)
#数组加法运算
print(np.add(a,b))
#数组减法运算
print(np.subtract(a,b))
#数组乘法运算
print(np.multiply(a,b))
#数组除法运算
print(np.divide(a,b))

‘’’
a数组:
[[ 0. 1. 2.]
[ 3. 4. 5.]
[ 6. 7. 8.]]
b数组:
[10 10 10]
加:
[[ 10. 11. 12.]
[ 13. 14. 15.]
[ 16. 17. 18.]]
减:
[[-10. -9. -8.]
[ -7. -6. -5.]
[ -4. -3. -2.]]

乘:
[[ 0. 10. 20.]
[ 30. 40. 50.]
[ 60. 70. 80.]]
除:
[[ 0. 0.1 0.2]
[ 0.3 0.4 0.5]
[ 0.6 0.7 0.8]]
’‘’
import numpy as np 
arr = np.array([0, 30, 60, 90, 120, 150, 180]) 
#计算arr数组中给定角度的三角函数值
#通过乘以np.pi/180将其转换为弧度
print(np.sin(arr * np.pi/180)) 
print(np.cos(arr * np.pi/180)) 
print(np.tan(arr * np.pi/180))  

‘’’
sin()正弦值:
[0.00000000e+00 5.00000000e-01 8.66025404e-01 1.00000000e+00
8.66025404e-01 5.00000000e-01 1.22464680e-16]
cos()余弦值:
[ 1.00000000e+00  8.66025404e-01  5.00000000e-01  6.12323400e-17
-5.00000000e-01 -8.66025404e-01 -1.00000000e+00]
tan()正切值:
[ 0.00000000e+00  5.77350269e-01  1.73205081e+00  1.63312394e+16
-1.73205081e+00 -5.77350269e-01 -1.22464680e-16]
’‘’
import numpy as np 
arr = np.array([12.202, 90.23120, 123.020, 23.202]) 
print(arr) 
print("数组值四舍五入到小数点后两位",np.around(arr, 2)) 
print("数组值四舍五入到小数点后-1位",np.around(arr, -1))  

‘’'
原数组arr:[12.202 90.2312 123.02 23.202]
数组值四舍五入到小数点后两位[12.2 90.23 123.02 23.2]
数组值四舍五入到小数点后-1位[10. 90. 120. 20.]
‘''

位运算

函数名位运算符说明
np.bitwise_and(a,b)&逐个元素对应进行按位与运算,生成一个新的形状相同的数组
np.bitwise_or(a,b)|逐个元素对应进行按位或运算,生成一个新的形状相同的数组
np.invert(a)~逐个元素对应进行按位取反,生成一个新的形状相同的数组
np.left_shift(a,b)<<逐个元素对应进行按位左移,生成一个新的形状相同的数组
np.right_shift(a,b)>>逐个元素对应进行按位右移,生成一个新的形状相同的数组
import numpy as np

a = np.arange(12).reshape(3,4)
b = np.array([1,2,4,8])
c1 = np.bitwise_and(a,b)
print('按位与:\n', c1)

c2 = np.bitwise_or(a,b)
print('按位或:\n', c2)

c3 = np.invert(a)
print('按位取反:\n', c3)

c4 = np.left_shift(a, b)
print('按位左移:\n', c4)

c5 = np.right_shift(a, b)
print('按位左移:\n', c5)

‘’'
按位与:
 [[0 0 0 0]
 [0 0 4 0]
 [0 0 0 8]]
按位或:
 [[ 1  3  6 11]
 [ 5  7  6 15]
 [ 9 11 14 11]]
按位取反:
 [[ -1  -2  -3  -4]
 [ -5  -6  -7  -8]
 [ -9 -10 -11 -12]]
按位左移:
 [[   0    4   32  768]
 [   8   20   96 1792]
 [  16   36  160 2816]]
按位左移:
 [[0 0 0 0]
 [2 1 0 0]
 [4 2 0 0]]
‘''

字符串处理

函数名称描述
np.char.add(a,b)对两个数组相应位置的字符串做连接操作。
np.char.multiply(a,times) 返回多个字符串副本,比如将字符串“ hello”乘以3,则返回字符串“ hello hello hello”。
np.char.center(a)用于居中字符串,并将指定的字符,填充在原字符串的左右两侧。
np.char.capitalize(a)将字符串第一个字母转换为大写。
np.char.title(a)标题样式,将每个字符串的第一个字母转换为大写形式。
np.char.lower(a)将数组中所有的字符串的大写转换为小写。
np.char.upper(a) 将数组中所有的字符串的小写转换为大写。
np.char.split(a, sep) 通过指定分隔符对字符串sep进行分割,并返回一个数组序列,默认分隔符为空格。
np.char.splitlines(a) 以换行符作为分隔符来分割字符串,并返回数组序列。
np.char.strip(a)删除字符串开头和结尾处的空字符。
np.char.join(a,b) 返回一个新的字符串,该字符串是以指定分隔符来连接数组中的所有元素。
np.char.replace(a, old,new)用新的字符串替换原数组中指定的字符串。
np.char.decode(a, en) 用指定的编码格式对数组中元素依次执行解码操作。
np.char.encode(a,en)用指定的编码格式对数组中元素依次执行编码操作。
import numpy as np

a = np.array([['aaa', 'bbb', 'ccc'], ['AAA', 'BBB', 'CCC'], ['aaB', 'Abb', 'Bcc']])
b = np.array([['111', '222', '333'], ['A11', 'B11', 'C11'], ['a11', 'b11', 'c11']])

c1 = np.char.add(a,b)
print ('字符串add:\n', c1)

c2 = np.char.multiply(a, 3)
print ('字符串multiply 3:\n', c2)

c3 = np.char.join(a,b)
print ('字符串join -:\n', c3)

c4 = np.char.replace(a, 'aa', 'yy')
print ('字符串replace -:\n', c4)

c5 = np.char.encode(a, 'cp500')
print ('字符串encode -:\n', c5)

‘’'
字符串add:
 [['aaa111' 'bbb222' 'ccc333']
 ['AAAA11' 'BBBB11' 'CCCC11']
 ['aaBa11' 'Abbb11' 'Bccc11']]
字符串multiply 3:
 [['aaaaaaaaa' 'bbbbbbbbb' 'ccccccccc']
 ['AAAAAAAAA' 'BBBBBBBBB' 'CCCCCCCCC']
 ['aaBaaBaaB' 'AbbAbbAbb' 'BccBccBcc']]
字符串join -:
 [['1aaa1aaa1' '2bbb2bbb2' '3ccc3ccc3']
 ['AAAA1AAA1' 'BBBB1BBB1' 'CCCC1CCC1']
 ['aaaB1aaB1' 'bAbb1Abb1' 'cBcc1Bcc1']]
字符串replace -:
 [['yya' 'bbb' 'ccc']
 ['AAA' 'BBB' 'CCC']
 ['yyB' 'Abb' 'Bcc']]
字符串encode -:
 [[b'\x81\x81\x81' b'\x82\x82\x82' b'\x83\x83\x83']
 [b'\xc1\xc1\xc1' b'\xc2\xc2\xc2' b'\xc3\xc3\xc3']
 [b'\x81\x81\xc2' b'\xc1\x82\x82' b'\xc2\x83\x83']]
‘''

统计函数

函数名说明
np.amin(a,axis)计算数组中的元素沿指定轴的最小值
np.amax(a,axis)计算数组中的元素沿指定轴的最大值
np.argmax(a,axis)沿给定轴返回最大元素的索引
np.argmin(a,axis)沿给定轴返回最小元素的索引
np.ptp(a,axis)计算数组中元素最大值与最小值的差(最大值 - 最小值)
np.percentile(a,q,axis)计算数组中元素的百分位数
np.median(a,axis) 计算数组 a 中元素的中位数(中值)
np.mean(a,axis)返回数组中元素的算术平均值,如果提供了轴,则沿其计算。
np.average(a,axis,weights) 根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值。该函数可以接受一个轴参数。 如果没有指定轴,则数组会被展开。
np.var(a)方差
np.std(a)标准差
numpy.amin(a, axis=None, out=None, keepdims=<no value>, initial=<no value>, where=<no value>)
numpy.amax(a, axis=None, out=None, keepdims=<no value>, initial=<no value>, where=<no value>)
numpy.ptp(a, axis=None, out=None, keepdims=<no value>, initial=<no value>, where=<no value>)

几个函数参数相同,以amin()为例,参数说明:

  • a: 输入的数组,可以是一个NumPy数组或类似数组的对象。
  • axis: 可选参数,用于指定在哪个轴上计算最小值。如果不提供此参数,则返回整个数组的最小值。可以是一个整数表示轴的索引,也可以是一个元组表示多个轴。
  • out: 可选参数,用于指定结果的存储位置。
  • keepdims: 可选参数,如果为True,将保持结果数组的维度数目与输入数组相同。如果为False(默认值),则会去除计算后维度为1的轴。
  • initial: 可选参数,用于指定一个初始值,然后在数组的元素上计算最小值。
  • where: 可选参数,一个布尔数组,用于指定仅考虑满足条件的元素。
import numpy as np

a = np.array([[3, 7, 5], [8, 4, 3], [2, 4, 9]])
print('我们的数组是:\n', a)
print('调用 amin(a,1) 函数:\n', np.amin(a, 1))
print('调用 amin(a,0) 函数:\n', np.amin(a, 0))
print('调用 amax(a) 函数:\n', np.amax(a))
print('调用 amax(a, axis=0) 函数:\n', np.amax(a, axis=0))

‘’'
我们的数组是:
 [[3 7 5]
 [8 4 3]
 [2 4 9]]
调用 amin(a,1) 函数:
 [3 3 2]
调用 amin(a,0) 函数:
 [2 4 3]
调用 amax(a) 函数:
 9
调用 amax(a, axis=0) 函数:
 [8 7 9]
‘''

np.percentile(a, q, axis=None, out=None, overwrite_input=False, interpolation='linear', keepdims=False) 

返回小于这个值的观察值的百分比

numpy.median(a, axis=None, out=None, overwrite_input=False, keepdims=<no value>)

返回数组 a 中元素的中位数(中值)

numpy.mean(a, axis=None, dtype=None, out=None, keepdims=<no value>)

返回数组中元素的算术平均值,如果提供了轴,则沿其计算。

参数说明:

  • a: 输入数组
  • q: 要计算的百分位数,在 0 ~ 100 之间
  • axis: 沿着它计算百分位数的轴
  • out: 可选参数,用于指定结果的存储位置。
  • overwrite_input: 可选参数,如果为True,则允许在计算中使用输入数组的内存。这可能会在某些情况下提高性能,但可能会修改输入数组的内容。
  • keepdims: 可选参数,如果为True,将保持结果数组的维度数目与输入数组相同。如果为False(默认值),则会去除计算后维度为1的轴。
  • dtype: 可选参数,用于指定输出的数据类型。如果不提供,则根据输入数据的类型选择合适的数据类型。

首先明确百分位数:第 p 个百分位数是这样一个值,它使得至少有 p% 的数据项小于或等于这个值,且至少有 (100-p)% 的数据项大于或等于这个值。

举个例子:高等院校的入学考试成绩经常以百分位数的形式报告。比如,假设某个考生在入学考试中的语文部分的原始分数为 54 分。相对于参加同一考试的其他学生来说,他的成绩如何并不容易知道。但是如果原始分数54分恰好对应的是第70百分位数,我们就能知道大约70%的学生的考分比他低,而约30%的学生考分比他高。这里的 p = 70。

import numpy as np

a = np.array([[3, 7, 5], [8, 4, 3], [2, 4, 9]])
print('我们的数组是:\n', a)
# 50% 的分位数,就是 a 里排序之后的中位数
print ('np.percentile(a, 50):\n', np.percentile(a, 50))
print ('np.percentile(a, 50, axis=0):\n', np.percentile(a, 50, axis=0))
print ('np.percentile(a, 50, axis=1):\n', np.percentile(a, 50, axis=1))
print ('np.percentile(a, 50, axis=1, keepdims=True):\n', np.percentile(a, 50, axis=1, keepdims=True))

‘’'
我们的数组是:
 [[3 7 5]
 [8 4 3]
 [2 4 9]]
np.percentile(a, 50):
 4.0
np.percentile(a, 50, axis=0):
 [3. 4. 5.]
np.percentile(a, 50, axis=1):
 [5. 4. 4.]
np.percentile(a, 50, axis=1, keepdims=True):
 [[5.]
 [4.]
 [4.]]
‘''
numpy.average(a, axis=None, weights=None, returned=False)

根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值。

该函数可以接受一个轴参数。 如果没有指定轴,则数组会被展开。

加权平均值即将各数值乘以相应的权数,然后加总求和得到总体值,再除以总的单位数。

考虑数组[1,2,3,4]和相应的权重[4,3,2,1],通过将相应元素的乘积相加,并将和除以权重的和,来计算加权平均值。

加权平均值 = (1*4+2*3+3*2+4*1)/(4+3+2+1)

参数说明:

  • a: 输入的数组,可以是一个 NumPy 数组或类似数组的对象。
  • axis: 可选参数,用于指定在哪个轴上计算加权平均值。如果不提供此参数,则计算整个数组的加权平均值。可以是一个整数表示轴的索引,也可以是一个元组表示多个轴。
  • weights: 可选参数,用于指定对应数据点的权重。如果不提供权重数组,则默认为等权重。
  • returned: 可选参数,如果为True,将同时返回加权平均值和权重总和。

排序和搜索

排序

NumPy 提供了多种排序函数:

种类速度最坏复杂度工作空间稳定性
quicksort(快速排序)1 O(n^2)0不稳定
mergesort(归并排序)2O(n * log(n))~n/2稳定
heapsort(堆排序)3O(n * log(n))0不稳定

numpy.sort()

numpy.sort(a, axis, kind, order)

对输入数组执行排序,并返回一个数组副本

参数说明:

  • a:要排序的数组;
  • axis:沿着指定轴进行排序,如果没有指定 axis,默认在最后一个轴上排序,若 axis=0 表示按列排序,axis=1 表示按行排序;
  • kind:默认为 quicksort(快速排序);
  • order:若数组设置了字段,则 order 表示要排序的字段。
import numpy as np

a = np.array([[3, 7, 5], [8, 4, 3], [2, 4, 9]])
print('数组是:\n', a)
print('np.sort(a):\n', np.sort(a))
print('np.sort(a, axis=0):\n', np.sort(a, axis=0))
print('np.sort(a, axis=0):\n', np.sort(a, axis=1))

dt = np.dtype([('name',  'S10'),('age',  int)])
a = np.array([("Chen",11),("John",15),("Rose",13),  ("Ami",16)], dtype = dt)
print(a)
print('np.sort(a):\n', np.sort(a))
print('np.sort(a, order=age):\n', np.sort(a, order='age'))


‘’'
数组是:
 [[3 7 5]
 [8 4 3]
 [2 4 9]]
np.sort(a):
 [[3 5 7]
 [3 4 8]
 [2 4 9]]
np.sort(a, axis=0):
 [[2 4 3]
 [3 4 5]
 [8 7 9]]
np.sort(a, axis=0):
 [[3 5 7]
 [3 4 8]
 [2 4 9]]
[(b'Chen', 11) (b'John', 15) (b'Rose', 13) (b'Ami', 16)]
np.sort(a):
 [(b'Ami', 16) (b'Chen', 11) (b'John', 15) (b'Rose', 13)]
np.sort(a, order=age):
 [(b'Chen', 11) (b'Rose', 13) (b'John', 15) (b'Ami', 16)]
‘''

numpy.argsort()

返回的是数组值从小到大的索引值。

import numpy as np

a = np.array([[3, 7, 5], [8, 4, 3], [2, 4, 9]])
print('数组是:\n', a)
print('np.sort(a):\n', np.sort(a))
print('np.argsort(a):\n', np.argsort(a))

‘’'
数组是:
 [[3 7 5]
 [8 4 3]
 [2 4 9]]
np.sort(a):
 [[3 5 7]
 [3 4 8]
 [2 4 9]]
np.argsort(a):
 [[0 2 1]
 [2 1 0]
 [0 1 2]]
‘''

numpy.lexsort()

用于对多个序列进行排序。把它想象成对电子表格进行排序,每一列代表一个序列,排序时优先照顾靠后的列。是间接排序,lexsort不修改原数组,返回索引。

这里举一个应用场景:小升初考试,重点班录取学生按照总成绩录取。在总成绩相同时,数学成绩高的优先录取,在总成绩和数学成绩都相同时,按照英语成绩录取…… 这里,总成绩排在电子表格的最后一列,数学成绩在倒数第二列,英语成绩在倒数第三列。

numpy.lexsort(keys, axis=-1)

参数:

  • keys :序列或元组,要排序的不同的列;
  • axis :沿指定轴进行排序;

lexsort传入的是keys,需要和切片一起使用:

import numpy as np

a = np.array([["Chen",100,95,195],["John",100,100,200],["Rose",99,95,194],  ["Ami",99,96,195]])
print(np.lexsort((a[:,2], a[:,1], a[:,3])))


dt = np.dtype([('Name',  'S10'),('Math', int), ('English', int), ('Total',  int)])
da = np.array([("Chen",100,95,195),("John",100,100,200),("Rose",99,95,194),  ("Ami",99,96,195)], dtype=dt)
print(np.sort(da, order=('Total', 'Math', 'English')))

‘’'
[2 0 3 1]
[(b'Rose',  99,  95, 194) (b'Ami',  99,  96, 195) (b'Chen', 100,  95, 195)
 (b'John', 100, 100, 200)]
‘''

其他排序函数

函数描述
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 指定算法沿着指定轴对数组进行分区

搜索

搜索非0元素

numpy.nonzero(a) 

返回输入数组中非零元素的索引。

import numpy as np 
 
a = np.array([[30,40,0],[0,20,10],[50,0,60]])  
print ('我们的数组是:')
print (a)
print ('\n')
print ('调用 nonzero() 函数:')
print (np.nonzero (a))

‘’’
我们的数组是:
[[30 40  0]
 [ 0 20 10]
 [50  0 60]]

调用 nonzero() 函数:
(array([0, 0, 1, 1, 2, 2]), array([0, 1, 1, 2, 0, 2]))
’‘’

返回两个数组,第一个数组描述行,第二个数组描述列,例如上面的,可以对照成如下:

[0, 0, 1, 1, 2, 2]

[0, 1, 1, 2, 0, 2]

一共6个非0值,分别是(0,0)、(0,1)、(1,1)、(1,2)、(2,0)、(2,2)

如果是高纬度的数组,返回的数组数等于维度数:

import numpy as np

a = np.array([[[30, 40, 0], [0, 20, 10], [50, 0, 60]],[[0, 1, 1], [1, 0, 0], [50, 1, 0]]])
print('我们的数组是:')
print(a)
print('\n')
print('调用 nonzero() 函数:')
print(np.nonzero(a))

‘’’
我们的数组是:
[[[30 40  0]
  [ 0 20 10]
  [50  0 60]]

 [[ 0  1  1]
  [ 1  0  0]
  [50  1  0]]]


调用 nonzero() 函数:
(array([0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1]), array([0, 0, 1, 1, 2, 2, 0, 0, 1, 2, 2]), array([0, 1, 1, 2, 0, 2, 1, 2, 0, 0, 1]))
’‘’

条件筛选数据

np.where(condition,x,y)

满足条件(condition)输出x, 不满足则输出y

np.where(arr) 

输出arr中“真”值的坐标,简单理解为不为0的坐标

import numpy as np

a = np.array([[32, 42, 52], [60, 61, 62], [10, 100, 1000]])
print('where(>50):')
y = np.where(a > 50)
print(a[y])

a2 = np.where(a < 50, a, 50)
print(a2)

‘’'
where(>50):
[  52   60   61   62  100 1000]
[[32 42 50]
 [50 50 50]
 [10 50 50]]
‘''

extract(condition, arr)

其中参数:

  • condition : numpy数组,元素为布尔值
  • arr:与condition相同维数的numpy数组,被抽取的输入数组

函数返回值:返回一个1维numpy数组

import numpy as np

a = np.array([[32, 42, 52], [60, 61, 62], [10, 100, 1000]])
b = np.array([[0, 0, 1], [1, 1, 0], [0, 0, 0]])
y = np.extract(b, a)
print(y)

‘’'
[52 60 61]
‘''

视图和拷贝

视图

通过a.view()方法可以为a创建一个视图,View 不 copy 数据, 而是给源数据加一个窗(视图),从外面看窗户里的数据。具体来说,view 不会新建数据,而只是在源数据上建立索引部分。

ndarray.view(dtype=None, type=None)

参数:

  • dtype:返回视图的数据类型描述符,例如float32或int16。默认值为None(无),导致视图具有与a相同的数据类型。
  • type:Python类型,可选
import numpy as np

a = np.arange(12).reshape(3,4)
print('初试a:\n', a)
v = a.view()
print('view v:\n', v)
v += 1  #注意,不能写成v = v + 1,这是不同的两种结果,v = v + 1会重新给v赋值,v就不再是a的视图了
print('v+1, a:\n', a)

‘’’
初试a:
 [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
view v:
 [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
v+1, a:
 [[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
’‘’

拷贝

numpy.copy(a, order=‘K’)

返回给定数组的深拷贝

order    {‘C’, ‘F’, ‘A’, ‘K’},可选参数    控制拷贝数组在内存中的存储顺序。'C’表示C顺序,'F’表示F顺序,如果输入数组是连续值,那么’A’亦为F顺序,若输入数组不是连续值,那么’A’为C顺序。'K’表示拷贝数组和原始数组的存储顺序尽可能一致。(注意:这个函数和ndarray.copy的功能很相似,只是order的默认值不同)
 

import numpy as np

a = np.arange(12).reshape(3,4)
print('初试a:\n', a)
v = a.copy()
print('copy v:\n', v)
v += 1  
print('v+1, a:\n', a)

‘’'
初试a:
 [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
copy v:
 [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
v+1, a:
 [[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

‘''

线性代数

NumPy 提供了线性代数函数库 linalg,该库包含了线性代数所需的所有功能,可以看看下面的说明:

函数描述
np.dot(a,b)两个数组的点积,即元素对应相乘。
np.vdot(a,b)两个向量的点积
np.inner(a,b)两个数组的内积
np.matmul(a,b)两个数组的矩阵积
np.linalg.solve(a)求解线性矩阵方程
np.linalg.inv(a)计算矩阵的乘法逆矩阵
np.linalg.det(a) 计算输入矩阵的行列式
numpy.dot(a, b, out=None) 

参数说明:

  • a : ndarray 数组
  • b : ndarray 数组
  • out : ndarray, 可选,用来保存dot()的计算结果
import numpy as np

a = np.array([[1, 2], [3, 4]])
b = np.array([[11, 12], [13, 14]])
print(np.dot(a, b))

‘’'
[[37 40]
 [85 92]]
‘''

文件读写

Numpy 可以读写磁盘上的文本数据或二进制数据。

NumPy 为 ndarray 对象引入了一个简单的文件格式:npy。

npy 文件用于存储重建 ndarray 所需的数据、图形、dtype 和其他信息。

数组写入.npy文件

numpy.save(file, arr, allow_pickle=True, fix_imports=True)
numpy.load(file, mmap_mode=None, allow_pickle=True, fix_imports=True, encoding=’ASCII’)

将数组保存到以 .npy 为扩展名的文件中

参数说明:

  • file:要保存的文件,扩展名为 .npy,如果文件路径末尾没有扩展名 .npy,该扩展名会被自动加上。
  • arr: 要保存的数组
  • allow_pickle: 可选,布尔值,允许使用 Python pickles 保存对象数组,Python 中的 pickle 用于在保存到磁盘文件或从磁盘文件读取之前,对对象进行序列化和反序列化。
  • fix_imports: 可选,为了方便 Pyhton2 中读取 Python3 保存的数据。
  • mmap_mode :如果不为None,则使用给定模式memory-map文件
  • encoding :仅当在Python 3中加载Python 2生成的腌制文件时有用,该文件包含包含对象数组的npy /npz文件。
import numpy as np 
 
a = np.array([1,2,3,4,5]) 
 
# 保存到 outfile.npy 文件上
np.save('outfile.npy',a) 
 
# 保存到 outfile2.npy 文件上,如果文件路径末尾没有扩展名 .npy,该扩展名会被自动加上
np.save('outfile2',a)

查看文件内容:

$ cat outfile.npy
�NUMPYv{'descr': '<i8', 'fortran_order': False, 'shape': (5,), }  
numpy.savez(file, *args, **kwds)

将多个数组保存到以 npz 为扩展名的文件中。

参数说明:

  • file:要保存的文件,扩展名为 .npz,如果文件路径末尾没有扩展名 .npz,该扩展名会被自动加上。
  • args: 要保存的数组,可以使用关键字参数为数组起一个名字,非关键字参数传递的数组会自动起名为 arr_0arr_1, … 。
  • kwds: 要保存的数组使用关键字名称。
import numpy as np 
 
a = np.array([[1,2,3],[4,5,6]])
b = np.arange(0, 1.0, 0.1)
c = np.sin(b)
# c 使用了关键字参数 sin_array
np.savez("runoob.npz", a, b, sin_array = c)
r = np.load("runoob.npz")  
print(r.files) # 查看各个数组名称
print(r["arr_0"]) # 数组 a
print(r["arr_1"]) # 数组 b
print(r["sin_array"]) # 数组 c

数组写入文本文件

np.loadtxt(FILENAME, dtype=int, delimiter=' ')
np.savetxt(FILENAME, a, fmt="%d", delimiter=",")

参数 delimiter 可以指定各种分隔符、针对特定列的转换器函数、需要跳过的行数等。

import numpy as np 
 
 
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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值