Numpy库的主要使用方法

Zielorem

import numpy as np

数组属性

  • Numpy数组(即ndarray)的维度称为秩,一维数组的秩为 1,二维数组的秩为 2
  • 每个线性的数组称为轴(即维度),二维数组相当于两个一维数组,而第一个一维数组中的每个元素又为一个一维数组
  • 对于一维数组,ndarray.axis值仅为 0;对于二维数组,列轴(纵轴)的ndarray.axis值为 0,行轴(横轴)的ndarray.axis值为 1;对于三维数组,ndarray.axis的值为 0、1、2 时分别对应数组的第一维(第一层数组)、第二维(第二层数组)、第三维(第三层数组),第一层数组的元素是第二层数组,第二层数组的元素是第三层数组
    属性 说明
    ndarray.ndim 秩(维度或轴的数量)
    ndarray.shape 数组的维度(比如数组的n行m列)
    ndarray.size 数组元素总数
    ndarray.axis 数组的轴
    ndarray.dtype ndarray对象数据类型
    ndarray.itemsize ndarray对象元素大小(byte)
    ndarray.flags ndarray对象内存信息
    ndarray.real ndarray元素实部
    ndarray.imag ndarray元素虚部
    ndarray.data 实际数组元素缓冲区

dtype

numpy.dtype(<object>, <align>, <copy>)

  • <object>为要转换为的数据类型对象
  • <align>若为True则填充字段使其类似于C的结构体
  • <copy>决定复制dtype对象,若为False则为对内置数据类型对象的引用
  • 字节顺序通过对数据类型预先设定><决定,>即大端法(高字节存储在最前的低位地址),<即小端法 (低字节存储在最前的低位地址)
    名称 描述
    bool_ 布尔型数据类型(TrueFalse
    int_ 默认的整数类型(类似于C语言中的long,int32或int64)
    intc 与C语言中的int类型一致(一般是int32或int64)
    intp 用于索引的整数类型(类似于C语言中的ssize_t)
    int8 范围内的整数
    int16 范围内的整数
    int32 范围内的整数
    int64 范围内的整数
    uint8 范围内的无符号整数
    uint16 范围内的无符号整数
    uint32 范围内的无符号整数
    uint64 范围内的无符号整数
    float_ float64类型的简写
    float16 半精度浮点数(包括1个符号位,5个指数位,10个尾数位)
    float32 单精度浮点数(包括1个符号位,8个指数位,23个尾数位)
    float64 双精度浮点数(包括1个符号位,11个指数位,52个尾数位)
    complex_ complex128类型的简写(即128位复数)
    complex64 复数,表示双32位浮点数(实数部分和虚数部分)
    complex128 复数,表示双64位浮点数(实数部分和虚数部分)

每个内建类型都有一个唯一定义它的字符代码

字符 对应类型
b 布尔型
i 整型(有符号)
u 整型(无符号)
f 浮点型
c 复数浮点型
m timedelta(时间间隔)
M datetime(日期时间)
O Python对象
S, a 字符串(byte-)
U Unicode
V 原始数据(void)

比如int8、int16、int32、int64四种数据类型可使用字符’i1’、’i2’、’i4’、’i8’代替

1
2
data1 = np.dtype('i4')  # 相当于int32
data2 = np.dtype('<i2') # 标注小端法

或通过dtype定义结构化数据类型(结构体)

1
2
3
student = np.dtype([('name','S20'), ('age', 'i1'), ('grade', 'f4')]) 
data = np.array([('Alice', 21, 50),('Bob', 18, 75)], dtype = student)
print(data)

切换ndarray中每个元素字节的大端与小端
numpy.ndarray.byteswap(<inplace>)

  • <inplace>默认为False,若为True则就地交换字节
1
2
3
4
5
a = np.array([8, 256, 16], dtype=np.int16)

print(map(hex, a), end='\n\n') # <map object at 0x7fcad80b4dc0>
print(a.byteswap(True), end='\n\n') # [2048, 1, 4096]
print(map(hex, a)) # <map object at 0x7fcae81ce890>

创建数组

numpy.array(<object>, <dtype>, <copy>, <order>, <subok>, <ndmin>)

  • <object>为数组或嵌套的数列
  • <dtype>决定了数组元素的数据类型、数据大小、数据字节顺序等
  • <order>决定创建数组的样式,默认为 A(任意方向),同时 C 为行方向,F 为列方向
  • <subok>默认返回一个与基类类型一致的数组
  • <ndmin>指定生成数组的最小维度
    1
    2
    arr1 = np.array([1,2,3]) # 一维数组
    arr2 = np.array([1,2,3],[4,5,6],[7,8,9]) # 二维数组

从已存在的数组创建新数组
numpy.asarray(<object>, <dtype>, <order>)

  • <object>为任意形式的输入参数(列表、元组、多维数组等)
  • <dtype>决定返回数组的数据类型
  • <order>决定数据在计算机内存中存储元素的顺序,若为’C’则为行优先,为’F’则为列优先
    1
    2
    3
    x = [(1, 2, 3), (4, 5)]
    a = np.asarray(x, dtype = float)
    print(a)

接受buffer输入参数,以流的形式读入转化为ndarray对象,从而实现动态数组
numpy.frombuffer(<buffer>, <dtype>, <count>, <offset>)

  • <buffer>以流的形式读入,可以为任意对象
  • <dtype>决定返回数组的数据类型
  • <count>决定读取的数据数量,默认为 -1(读取所有数据)
  • <offset>决定读取的起始位置,默认为 0
  • <buffer>为字符串时,Python3默认str为Unicode类型,需转为bytestring(即在原str前加b)
    1
    2
    3
    s = b'Kemono' # 转换为bytestring
    a = np.frombuffer(s, dtype = 'S1')
    print(a)

从可迭代对象中建立ndarray对象,返回一维数组
numpy.fromiter(<iterable>, <dtype>, <count>)

  • <iterable>为可迭代对象
  • <dtype>决定返回数组的数据类型
  • <count>决定读取的数据数量,默认为 -1(读取所有数据)
    1
    2
    3
    4
    5
    list = range(5)
    it = iter(list) # 生成迭代器

    x = np.fromiter(it, dtype = float)
    print(x)

以指定数值范围创建数组
numpy.arange(<start>, <stop>, <step>, <dtype>)

  • <start>决定序列起始位(缺省为 0)
  • <stop>决定序列终止位(不包含该位)
  • <step>决定步长(缺省为 1)
  • <dtype>决定返回数组的数据类型
    1
    2
    3
    arr1 = np.arange(5, dtype = float) # [0. 1. 2. 3. 4.]
    arr2 = np.arange(10, 20, 2) # [10 12 14 16 18]
    print(arr1, arr2)

创建一维等差数组
np.linspace(<start>, <stop>, <num>, <endpoint>, <retstep>, <dtype>)

  • <start>决定序列起始位
  • <stop>决定序列终止位
  • <num>决定生成的等步长的样本数量(缺省为 50)
  • <endpoint>(默认)为True时,序列中包含<stop>值,反之不包含
  • <retstep>True时,生成的数组中将显示间距,反之不显示
  • <dtype>决定返回数组的数据类型
    1
    2
    3
    a = np.linspace(1, 1, 10)  # 十个1组成的序列
    b = np.linspace(10, 20, 5, endpoint = false, retstep = True)
    # [10., 12., 14., 16., 18.]

创建一维等比数组
np.logspace(<start>, <stop>, <num>, <endpoint>, <base>, <dtype>)

  • <start>决定序列起始位为base ** start
  • <stop>决定序列终止位为base ** stop
  • <num>决定生成的等步长的样本数量(缺省为 50)
  • <endpoint>(默认)为True时,序列中包含<stop>值,反之不包含
  • <base>决定序列底数(缺省为 10)
  • <dtype>决定返回数组的数据类型
    1
    2
    a = np.logspace(1, 4, num = 4)  # [10. 100. 1000. 10000.]
    b = np.logspace(0, 5, 5, endpoint = False, base = 2) # [1. 2. 4. 8. 16.]

创建一个指定形状与数据类型且未初始化的空数组
numpy.empty(<shape>, <dtype>, <order>)

  • <shape>为决定数组形状的整数或整数元组
  • <dtype>决定返回数组的数据类型
  • <order>决定数据在计算机内存中存储元素的顺序,若为’C’则为行优先,为’F’则为列优先
  • 数组元素未初始化,因此内容为内存中的随机值

创建指定大小的以 0 或 1 填充的数组
numpy.zeros(<shape>, <dtype>, <order>)
numpy.ones(<shape>, <dtype>, <order>)

  • <shape>为决定数组形状的整数或整数元组
  • <dtype>决定返回数组的数据类型,缺省为浮点数
  • <order>若为’C’则用于C的行数组,为’F’则用于FORTRAN的列数组
    1
    2
    3
    a = np.empty([3, 2], dtype = int)  # 三行两列空二维数组
    b = np.zeros(2, 2) # 两行两列全零二维数组
    c = np.ones(2, 2) # 两行两列全一二维数组

创建以1填充对角线元素的二维等长数组(类似单位矩阵)
np.eye(<column>, <row>, <index>, <dtype>)

  • <column>决定二维数组行数
  • <row>决定二维数组列数(默认与行数一致)
  • <index>决定对角线的索引
  • <dtype>决定数组返回元素的类型

创建对角数组
np.diag(<array_like>, <diagonal_position>)

  • <array_like>若为二维数组,则返回<diagonal_position>位置的对角线;若为一维数组,则返回一个<array_like>作为<diagonal_position>位置对角线的二维数组
  • <diagonal_position>决定对角线位置,若大于 0 则上移,反之下移
    1
    2
    3
    4
    5
    6
    x = np.eye(2)  # 以1填充对角元素的二维两行两列数组

    y = np.arange(9).reshape((3, 3))
    arr1 = np.diag(y) # [0, 4, 8]
    arr2 = np.diag(y, -1) # [3, 7]
    z = np.diag(np.diag(arr1)) # 以[0, 4, 8]为对角元素的三行三列对角矩阵

给定形状的以随机样本 中的随机元素填充的数组
np.random.rand(<size>)

给定形状的以服从标准正态分布的一个或一组元素填充的数组
np.random.randn(<size>)

给定形状的以给定范围内的随机整数填充的数组
np.random.randint(<low>, <high>, <size>, <dtype>)

  • <low>决定起始位
  • <high>决定终止位(不包含),未赋值时整数范围为
  • <size>决定整数数组形状
  • <dtype>决定整数类型

给定形状的以 范围内的随机浮点数填充的数组
np.random.random(<size>)

给定形状的以给定一维数组内的元素随机填充的数组
np.random.choice(<array>, <size>, <replace>, <p>)

  • <array>为给定的一维数组
  • <size>决定输出数组形状
  • <replace>决定一维数组中的元素可否被多次选中,默认为True
  • <p>决定一维数组中各元素被选中的概率,形状必须与<array>一致

以seed值标记特定随机数序列
np.random.seed(<seed>)

  • 在相同seed值下所生成的随机数序列为同一批
  • 调用其他方法生成随机数前,调用此方法可通过seed值标记特定随机数序列或采用已通过seed值标记的特定随机数序列

切片与索引

通过内置的slice函数从原数组中切割出新数组
slice(<start>, <stop>, <step>)

  • <start>决定切割起始位
  • <stop>决定切割终止位
  • <step>决定切割间隔数值
  • Python切片时复制数组并操作,而Numpy切片时直接操作原数组

或通过冒号分割切片参数start:stop:step进行切片操作

切片可以通过省略号使得所选元组的长度与数组的维度相同,若在行位置使用省略号,其将返回包含行中元素的ndarray

1
2
3
4
5
6
7
a = np.arange(10)
s1 = slice(2, 7, 2) # 从索引2开始至索引7终止,间隔为2
b = a[2:7:2] # a == b

c = np.array([[1, 2, 3], [3, 4, 5], [4, 5, 6]])
print(c[1,...]) # 第二行元素
print(c[...,1:]) # 第二列及剩下所有列元素

返回数组中(沿特定轴)的最大元素与最小元素的索引值
numpy.argmax(<array>, <axis>)
numpy.argmin(<array>, <axis>)

返回数组中非零元素的索引值
numpy.nonzero(<array>)

返回数组中满足给定条件的元素
numpy.extract(<condition>)

返回数组中满足给定条件的元素的索引值
numpy.where(<condition>)

1
2
3
4
5
6
a = np.array([[30, 40, 0], [0, 20, 10], [50, 0, 60]])

print(np.nonzero(a)) # (array([0, 0, 1, 1, 2, 2]), array([0, 1, 1, 2, 0, 2]))
print(np.where(a > 35)) # (array([0, 2, 2]), array([1, 0, 2]))
print(np.extract(np.mod(a, 3) == 0, a)) # [30, 0, 0, 0, 60]

整数数组索引

可以借助切片:...与索引数组组合

1
2
3
4
5
6
x = np.array([[1, 2, 3], [3, 4, 5], [5, 6, 7]])
y = x[[0, 1, 2], [0, 1, 0]] #[1, 4, 5]

a = x[1:3, 1:3] # [[4, 5], [6, 7]]
b = x[1:3, [1, 2]] # a == b
c = a[...,1:] # [[2, 3], [4, 5], [6, 7]]

布尔索引

通过一个布尔数组索引目标数组
布尔索引通过布尔运算获取符合指定条件的元素的数组

1
2
x = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])
print(x[x > 5]) # [6, 7, 8, 9, 10, 11]

使用~(取补运算符)过滤NaN

1
2
3
4
5
a = np.array([np.nan, 1, 2, np.nan, 3, 4, 5])
print(a[~np.isnan(a)]) # [1. 2. 3. 4. 5.]

b = np.array([1, 2+6j, 5, 3.5+5j])
print(a[np.iscomplex(a)]) # [2+6j, 3.5+5j]

存在多个条件时,将条件加以小括号或使用np.logical_andnp.all方法

1
2
3
4
5
x = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])

print(x[(x > 5) & (x < 7)]) # 条件加小括号分割
print(x[np.logical_and(x > 5, x < 7)]) # 使用np.logical方法
print(x[np.all([x > 5, x < 7], axis=0)]) # 使用np.all方法

花式索引

将整数数组的值作为目标数组的某轴下标进行索引
对于使用一维整型数组作为索引:

  • 若目标为一维数组,则索引结果为对应位置元素
  • 若目标为二维数组,则索引结果为对应下标的行
  • 将数据复制到新数组中
    1
    2
    3
    4
    5
    x = np.arange(1, 9)
    a = x[[0, 6]] # [1, 7]

    y = np.arange(9).reshape((3, 3))
    b = x[[1, 0]] # [[3, 4, 5], [0, 1, 2]]

传入多个索引数组需使用np.ix_,即输入两个数组产生笛卡尔积的映射关系

1
2
x = np.arange(9).reshape((3, 3))
print(x[np.ix_([2, 1], [0, 2])]) # [[6, 8], [3, 5]]

广播

对不同形状的数组进行数值计算的方式(即矩阵运算)
若两个数组 x 与 y 形状相同,即x.shape == y.shape,则 a 与 b 相乘的结果为 a 与 b 数组对位相乘(维数相同且各维度长度相同)

1
2
3
4
a = np.array([1, 2, 3, 4])
b = np.array([2, 3, 4, 5])
c = a * b
print(c) # [2, 6, 12, 20]

若两个数组 x 与 y 形状不同,即x.shape != y.shape,则将触发广播机制

1
2
3
a = np.array([[0, 0, 0], [10, 10, 10], [20, 20, 20], [30, 30, 30]])
b = np.array([0, 1, 2])
print(a + b) # [[0, 1, 2], [10, 11, 12], [20, 21, 22], [30, 31, 32]]

返回封装了一数组广播到另一数组的结果,并模仿广播对象
numpy.broadcast(<arr1>, <arr2>)

将数组广播到新形状,并在原数组上返回只读视图,通常不连续
numpy.broadcast_to(<array>, <shape>)

  • <array>为原数组
  • <shape>为新形状
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
x = np.arange(4, 7, 1, dtype=int)
y = np.array([[1], [3], [5]])

b = np.broadcast(x, y) # 返回广播对象
row, column = b.iters # 两个flatiter对象

# 广播的前两步对象
print(next(row), next(column)) # (4, 1)
print(next(row), next(column)) # (4, 3)
print('\n')

c = np.empty(b.shape) #3 *3大小的空数组
c.flat = [i + j for (i,j) in b] # [[5, 7, 9], [6, 8, 10], [7, 9, 11]]

print(np.broadcast_to(x, (2, 3))) # [[4, 5, 6], [4, 5, 6]]

迭代器

提供灵活访问一个或多个数组元素的方法,迭代选择顺序与数据内存布局一致,缺省行序优先
np.nditer(<array_like>, <flags>, <op_flags>, <order>)

  • <array_like>为需要迭代的序列
  • <flags>用于控制迭代器行为
    属性 说明
    buffered 在需要时启用缓冲
    c_index 跟踪C顺序索引
    f_index 跟踪Fortran顺序索引
    multi_index 跟踪多个索引或每次迭代跟踪一种索引(多维索引)
    external_loop 所给值为具有多个值的一维数组而非零维数组
  • <op_flags>指定每个操作的特征,缺省状态下待迭代数组状态为’read-only’,若在遍历迭代数组的同时修改数组元素则需指定为’readwrite’或’writeonly’
  • <order>用于控制迭代顺序,’C’为行序优先,’F’为列序优先
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    a = np.arange(6).reshape(2, 3)

    # 迭代输出数组元素
    for x in np.nditer(a):
    print(x, end = ', ')
    print('\n') # [0, 1, 2, 3, 4, 5,]

    # 迭代输出转置数组元素
    for y in np.nditer(a.T):
    print(y, end = ', ')
    print('\n') # [0, 1, 2, 3, 4, 5,]
    # y在转置后元素在内存中的存储顺序仍与x一致

    # 以行序优先模式迭代输出转置数组的元素
    for z in np.nditer(a.T, order = 'C'):
    print(z, end = ', ')
    print('\n') # [0, 3, 1, 4, 2, 5,]

    # 修改数组元素
    for x in np.nditer(a, op_flags='readwrite'):
    x[...] = 2*x
    print(x) # [0, 2, 4, 6, 8, 10,]

    # 添加索引
    it = np.nditer(x, flags=['multi_index'])
    while not it.finished:
    print("%d<%s>"%(it[0], it.multi_index)) #生成二维index
    it.iternext() # 进入下一次迭代

    # 添加外部循环(对应于每列并组合为一维数组)
    for x in np.nditer(x, flags=['external_loop'], order='F'):
    print(x, end=', ') #[[0, 2], [4, 6], [8, 10]]

nditer可同时迭代两个可广播数组

1
2
3
4
5
a = np.array([1, 2, 3, 4], dtype=int)
b = np.arange(0, 60, 5).reshape(3, 4)
for x,y in np.nditer([a,b]):
print('%d:%d' % (x,y), end=', ')
# 1:0, 2:5, 3:10, 4:15, 1:20, 2:25, 3:30, 4:35, 1:40, 2:45, 3:50, 4:55

数组操作

在不改变原始数据的情况下修改数组形状
numpy.reshape(<array>, <newshape>, <order>)

  • <array>为需要修改形状的数组
  • <newshape>为整数或整数数组(应兼容原数组形状)
  • <order>决定元素的排列顺序
    属性 说明
    ‘C’ 按行排列
    ‘F’ 按列排列
    ‘A’ 按数组原顺序排列
    ‘K’ 按元素在内存中的存储顺序排列

对数组中各元素进行处理(数组元素迭代器)
numpy.ndarray.flat()

返回一份展开的数组拷贝并独立于原数组
numpy.ndarray.flatten(<order>)

  • <order>决定元素的排列顺序(同reshape()
  • 对拷贝所进行的修改不会影响原数组

返回一份展开的数组视图
numpy.ravel(<array>, <order>)

  • <array>为需要进行操作的数组
  • <order>决定元素的排列顺序(同reshape()
  • 对视图进行的修改会影响原数组
    1
    2
    3
    4
    5
    6
    7
    8
    9
    a = np.arange(9).reshape(3, 3)
    for elements in a.flat:
    print(element) #依次输出数组中元素

    # 按列优先顺序展开数组
    print(a.flatten(order='F'), end=', ') # [0, 3, 6, 1, 4, 7, 2, 5, 8, ]

    # 以行优先顺序展开数组
    print(a.ravel(order='C'), end=', ') # [0, 1, 2, 3, 4, 5, 6, 7, 8, ]

对换数组维度(转置)
numpy.transpose(<array>, <axes>)

  • <array>为需要对换数组维度的数组
  • <axes>为对应维度的整数列表(通常对换所有维度)
  • 类似于numpy.ndarray.T

向后滚动特定数组坐标轴
numpy.rollaxis(<array>, <axis>, <start>)

  • <array>为需要对坐标轴执行向后滚动操作的数组
  • <axis>为需要向后滚动的轴
  • <start>表示需要滚动至的特定位置,缺省为 0(第 0 个轴)
  • 其他轴的相对位置不会改变

对换数组的两个坐标轴
numpy.swapaxes(<array>, <axis1>, <axis2>)

  • <array>为需要执行对换坐标轴操作的数组
  • <axis1><axis2>为对应两个轴的整数序号
1
2
3
a = np.arange(8).reshape(2, 2, 2)
b = np.rollaxis(a, 2, 0) # 轴2(宽度)滚动至轴0(深度)的位置
c = np.swapaxes(a, 2, 0) # 轴2(宽度)与轴0(深度)互换位置

在指定位置插入新轴以扩展数组
numpy.expand_dims(<array>, <axis>)

  • <array>为执行数组
  • <axis>为新轴所插入位置

在指定数组中删除值为1的维度
numpy.squeeze(<array>, <axis>)

  • <array>为执行数组
  • <axis>用于指定需要删除的维度(单维度),取值为Noneinttuple of ints,取值为空时删除所有值为 1 的维度(单维度)
1
2
3
4
5
6
7
8
x = np.arange(4, 7, 1, dtype=int)
y = np.array([[1], [3], [5]])

z = np.expand_dims(y, axis=1) # 在位置1插入新轴
print(z.shape) # (3, 1, 1)

z = np.squeeze(z,axis=(2,))
print(z.shape) # (3, 1)

沿指定轴连接相同形状的两个或多个数组
numpy.concatenate(<arrays>, <axis>)

  • <arrays>为同类型同形状的数组
  • <axis>指定连接数组的轴(缺省为 0,上下连接),若值为 1 则左右连接

沿新轴合并一系列数组
numpy.stack(<arrays>, <axis>)

  • <arrays>为同类型同形状的数组
  • <axis>指定数组序列的堆叠方向
    axis值 说明
    axis=0 在最外层括号执行堆叠
    axis=1 在次外层括号执行堆叠
    axis=2 (三维数组中)在最内层括号内执行堆叠
  • 堆叠后的数组比原数组多一个维度

通过水平堆叠生成数组
numpy.hstack(<arrays>)

  • <arrays>为同类型同形状的数组
  • 相当于numpy.concatenate()方法中<axis>值为 1

通过垂直堆叠生成数组
numpy.vstack(<arrays>)

  • <arrays>为同类型同形状的数组
  • 相当于numpy.concatenate()方法中<axis>值为 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
a = np.array([[1, 2], [3, 4]])
b = np.array([[4, 3], [2, 1]])

# 沿轴1连接数组a与数组b
print(np.concatenate((a, b), axis=1), end='\n\n')
print(np.hstack((a, b)), end='\n\n')
# [[1, 2, 4, 3], [3, 4, 2, 1]]

print(np.concatenate((a, b), axis=0), end='\n\n')
print(np.vstack((a, b)), end='\n\n')
# [[1, 2], [3, 4], [4, 3], [2, 1]]

c = np.stack((a, b), axis=0) # [[[1, 2], [3, 4]], [[4, 3], [2, 1]]]
print(np.stack((a, b), axis=1)) # [[[1, 2], [4, 3]], [[3, 4], [2, 1]]]
print(np.stack(c, axis=2)) # [[[1, 4], [2, 3]], [[3, 2], [4, 1]]]

沿特定轴分割数组
numpy.split(<array>, <indices_or_sections>, <axis>)

  • <arrays>为被分割的数组
  • <indices_or_sections>若为整数则将数组均分为该数等份,若为数组则决定沿轴分割位置
  • <axis>决定数组沿着何方向分割,缺省为 0(横向分割),为 1 时纵向分割

纵向分割数组
numpy.hsplit(<array>, <indices_or_sections>)

  • <arrays>为被分割的数组
  • <indices_or_sections>若为整数则将数组均分为该数等份,若为数组则决定沿轴分割位置
  • 相当于numpy.split()方法中<axis>值为 1

横向分割数组
numpy.vsplit(<array>, <indices_or_sections>)

  • <arrays>为被分割的数组
  • <indices_or_sections>若为整数则将数组均分为该数等份,若为数组则决定沿轴分割位置
  • 相当于numpy.split()方法中<axis>值为 0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    a = np.arange(6)

    b = np.split(a, 3)
    c = np.split(a, [2, 4])
    # [0, 1], [2, 3], [4, 5]

    x = np.arange(9).reshape(3, 3)

    y1 = np.split(x, 3, 1)
    y2 = np.hsplit(x, [1, 2])
    # [[0], [3], [6]], [[1], [4], [7]], [[2], [5], [8]]

返回指定大小的新数组
numpy.resize(<array>, <shape>)

  • <arrays>为需要修改大小的数组
  • <shape>为数组返回的新形状

分配整个数组并在数组的末尾追加值(扩展数组)
numpy.append(<array>, <values>, <axis>)

  • <arrays>为需要扩展的数组
  • <values>为需要向数组扩展的数组内容(与原数组形状相同)
  • <axis>指定数组扩展方向,默认为None并返回一维数组。若定义值为 0 则纵向扩展(列数需一致),定义值为 1 则横向扩展(行数需一致)

在指定索引前沿指定轴在数组中插入值
numpy.insert(<array>, <index>, <values>, <axis>)

  • <arrays>为需要插入值的数组
  • <index>为插入位置的索引
  • <values>为需要插入的值
  • <axis>为插入位置所沿的轴,默认展开原数组。若定义值为 0 则横向插入,定义值为 1 则纵向插入

在指定索引沿指定轴在数组中删除指定子数组
numpy.delete(<array>, <index>, <axis>)

  • <arrays>为需要删除值的数组
  • <index>为删除位置的索引
  • <axis>为删除位置所沿的轴,默认展开原数组。若定义值为 0 则横向删除,定义值为 1 则纵向删除

删除数组中重复元素
numpy.unique(<array>, <return_index>, <return_inverse>, <return_counts>)

  • <arrays>为需要去重的数组
  • <return_index>若为True,则返回去重后数组内元素在原数组中的索引位置(列表形式)
  • <return_inverse>若为True,则返回原数组内元素在去重后数组中的索引位置(列表形式)
  • <return_counts>若为True,则返回原数组内各元素出现次数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    a = np.array([[1, 2, 3], [4, 5, 6]])

    b1 = np.resize(a, (3, 2)) # [[1, 2], [3, 4], [5, 6]]
    b2 = np.resize(a, (3, 3)) # [[1, 2, 3], [4, 5, 6], [1, 2, 3]]

    c1 = np.insert(a, 3, [3, 4]) # [1, 2, 3, 3, 4, 4, 5, 6]
    c2 = np.insert(a, 2, [7, 8, 9], axis=0) # [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    c3 = np.insert(a, [1, 2], [9], axis=1) # [[1, 9, 2, 9, 3], [4, 9, 5, 9, 6]]

    d1 = np.delete(c3, [1, 3], axis=1) #[[1, 2, 3], [4, 5, 6]]
    d2 = np.delete(a, np.s_[::2]) #[2, 4, 6]

    e, indices = np.unique(c1, return_index=True)
    print(e) # [1, 2, 3, 4, 5, 6]
    print(indices) # [0, 1, 2, 4, 5, 6, 7]

位运算

对数组中整数元素的二进制形式执行位运算

运算方法 说明
numpy.bitwise_and(<numbers>) 位与运算
numpy.bitwise_or(<numbers>) 位或运算
numpy.invert(<number>) 取反运算

将数组中元素的二进制形式左移指定位置,右侧补上相应数量的 0
numpy.left_shift(<number>,<movement>)

  • <number>为数组中元素
  • <movement>为数组左移位数

将数组中元素的二进制形式右移指定位置,左侧补上相应数量的 0
numpy.right_shift(<number>,<movement>)

  • <number>为数组中元素
  • <movement>为数组右移位数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
print(np.bitwise_and(21, 25))
# 0b10101 + 0b11001 == 0b10001 (17)

print(np.bitwise_or(21, 25))
# 0b10101 + 0b11001 == 0b11101 (29)

print(np.invert(7))
# 原码转二进制 0b00000111
# 按位取反 0b11111000
# 首位为1表示负数,将除符号位外的其他位取反 0b10000111
# (末位加1)取补码 0b10001000
# 转回十进制 -8

print(np.left_shift(7, 3))
# 0b00000111 --> 0b00111000 (56)

print(np.right_shift(56, 3))
# 0b00111000 --> 0b00000111 (7)

字符串

方法 说明
numpy.char.add(<strings>) 连接两个字符串元素
numpy.char.multiply(<string>) 复制某个指定字符串元素并连接(多重连接)
numpy.char.center(<strings>, <length>, <fillchar>) 将字符串居中,并指定一个字符在左右两侧填充
numpy.char.capitalize(<strings>) 将字符串的首字母转换为大写
numpy.char.title(<strings>) 将字符串的每个单词的首字母均转换为大写
numpy.char.upper(<strings>) 将字符串的每个元素转换为大写
numpy.char.lower(<strings>) 将字符串的每个元素转换为小写
numpy.char.split([<strings>], [<seperates>]) 指定分隔符(默认空格)分割字符串,并返回数组
numpy.char.splitlines(<strings>) 将换行符作为分隔符以分割字符串,并返回数组
numpy.char.strip([<strings>], <char_to_delete>) 移除开头处与结尾处的某个指定字符
numpy.char.join([<fill_chars>], [<strings>]) 指定分隔符填充字符串中字符间的间隔
numpy.char.replace(<strings>, <string_to_replace>, <replacement>) 使用一个新字符串替换一个指定的原字符串中的所有子字符串
numpy.char.encode(<strings>, <encoder>) 对元素进行编码(默认编码为 uft-8
numpy.char.encode(<strings>, <decoder>) 对元素进行解码(默认解码为 uft-8

数学

方法 说明
numpy.add() 加法
numpy.subtract() 减法
numpy.multiply() 乘法
numpy.divide() 除法
numpy.reciprocal() 取倒数
numpy.power() 取幂
numpy.mod() 取余
numpy.dot() 数组点积
numpy.vdot() 向量点积
numpy.inner() 数组内积
numpy.matmul() 矩阵积
numpy.sin() 正弦函数
numpy.cos() 余弦函数
numpy.tan() 正切函数
numpy.arctan() 反正弦函数
numpy.arccos() 反余弦函数
numpy.arctan() 反正切函数
numpy.degrees() 弧度转角度
numpy.around(<number>, <decimals>) 四舍五入
numpy.floor() 向下取整
numpy.ceil() 向上取整
  • <decimals>指定舍入的小数位数,缺省为 0 ,若为负数则将整数四舍五入至小数点左侧
  • 执行运算前各运算元素须具有相同形状或符合数组广播规则

两个数组的点积
numpy.dot(<ndarrays>, <out>)

  • <ndarrays>若为一维数组,结果为两数组的内积;若为二维数组,结果为两数组的矩阵乘积;若为多维数组,结果为数组最后一维上所有元素与另一数组倒数第二维上所有元素的乘积之和
  • <out>存储计算结果

两个向量的点积
numpy.vdot(<ndarrays>)

  • <ndarrays>中第一个参数若为复数,则其共轭复数会被用于计算;若为多维数组,则会被展开

一维数组的向量内积
numpy.inner(<ndarrays>)

  • <ndarrays>若维度大于 1 ,则返回沿最后一个轴的矩阵乘积

两个数组的矩阵乘积
numpy.matmul(<ndarrays>)

  • <ndarrays>若为二维数组,则结果为矩阵乘法;若任意数组的维数大于 2 ,则将其视作存在于最后两个索引的矩阵的栈,并进行相应广播;若任意数组为一维数组,则将其维度加 1 变为矩阵,乘法结束后去除
1
2
3
4
5
6
7
8
9
10
11
x = np.array([[1, 2], [3, 4]])
y = np.array([[5, 6], [7, 8]])

print(np.dot(x, y)) # [[19, 22], [43, 50]](矩阵乘积)
print(np.vdot(x, y)) # 70(矩阵内积)
print(np.inner(x, y)) # [[17, 23], [39, 53]]

a = np.array([1+2j, 3+4j])
b = np.array([5+6j, 7+8j])
print(np.vdot(a, b)) # (70-8j)
print(np.vdot(b, a)) # (70+8j)

计算输入矩阵的行列式的值
numpy.linalg.det(<ndarrays>)

计算矩阵形式的线性方程的解
numpy.linalg.solve(<ndarray_formula>, <ndarray_result>)

  • <ndarray_formula>为线性方程未知数部分的参数
  • <ndarray_result>为线性方程组结果

计算矩阵的逆矩阵
numpy.linalg.inv(<ndarray>)

1
2
3
4
5
6
7
8
9
a = np.array([[4, 3], [2, 1]])
b = np.array([2, 4])
print(np.linalg.det(a)) # -2.0

#计算线性方程组 4x+3y=2, 2x+y=4 的结果
print(np.linalg.solve(a, b)) #[5, -6](x==5, y==-6)

c = np.linalg.inv(a) # [[-0.5, 1.5], [ 1., -2.]]
print(np.dot(a, c)) # [[1., 0.], [0., 1.]]

统计

方法 说明
numpy.amin(<array>, <axis>) 数组元素沿指定轴的最小值
numpy.amax(<array>, <axis>) 数组元素沿指定轴的最大值
numpy.ptp(<array>, <axis>) 数组沿指定轴的极差
numpy.percentile(<array>, <percentage>, <axis>) 数组指定百分位沿指定轴的分位数
numpy.median(<array>, <axis>) 数组沿指定轴的中位数
numpy.mean(<array>, <axis>) 数组沿指定轴的平均数
numpy.average(<array>, <weight>, <axis>) 根据另一数组中所给权重计算数组中元素的加权平均值
numpy.std(<array>, <axis>) 数组沿指定轴的标准差
numpy.var(<array>, <axis>) 数组沿指定轴的方差
  • numpy.average()方法在不给定<weight>时相当于numpy.mean()方法,
  • 在未指定<axis>时上述方法将展开数组

排序

返回数组排序后的副本
numpy.sort(<array>, <axis>, <sort_approach>, <order>)

  • <array>为需要排序的数组
  • <axis>指定排序所沿的轴
  • <kind>指定排序方法
    方法 说明
    'quicksort' 快速排序
    'mergesort' 归并排序
    'heapsort' 堆排序
  • <order>指定所排序的字段

返回数组内从小到大的数组值的索引值
numpy.argsort(<array>, <axis>)

同时对多个序列排序并返回排序结果中各元素在原数组中对应的索引值
numpy.lexsort(<arrays>)

沿列排序
numpy.msort(<array>)

  • 相当于np.sort()方法中<axis>值为 0

以先实部后虚部的顺序对复数排序
numpy.sort_complex(<array>)

1
2
3
4
5
6
7
8
9
10
11
12
13
data = np.dtype([('name', 'S10'), ('age', int)])
stu = np.array([('Dylan', 17), ('Alice', 16), ('Frank', 18)], dtype=data)

print(np.sort(stu, order='age')) #按age排序

x = np.array([5, 2, 7])
y = np.argsort(x)
print(x[y]) # 重构数组

name = [['Dylan'], ['Alice'], ['Frank']]
cls = [['A'], ['B'], ['A']]
print(np.lexsort((cls, name)), end='\n\n') #排序索引结果
print([name[i] + ',' + cls[i] for i in cls]) #排序结果

挑选指定数组中最小的几个元素置于数组最前端,并与其他元素分为两堆
numpy.partition(<array>, <kth>, <axis>)

  • 新数组中前<count>个元素为原数组中最小的<count>个元素
  • 仅将最小的<count>个元素置于数组最前端,不需要完整排序(类似快速排序过程)
  • 返回分区后的新数组

挑选指定数组中最小的几个元素置于数组最前端,并与其他元素分为两堆
numpy.argpartition(<array>, <kth>, <axis>)

  • numpy.partition()的主要功能相同
  • 返回分区后的新数组内元素在原数组中的索引号
1
2
3
4
5
6
7
8
9
10
11
12
arr = np.array([4, 5, 7, 1, 9, -4, -3, -6, -1])
print(np.partition(arr, kth=4)) # [-6, -4, -3, -1, 1, 4, 7, 5, 9]

# 返回数组中最小的3个数字
print(np.partition(arr, kth=3)[:3], end='\n\n')
print(arr[np.argpartition(arr, kth=3)[:3]])
# [-6, -4, -3]

# 返回数组中最大的5个数字
print(np.partition(arr, kth=-5)[-5:], end='\n\n')
print(arr[np.argpartition(arr, kth=-5)[-5:]])
# [1, 4, 7, 5, 9]

文件

将数组保存到以 .npy 为扩展名的文件中
numpy.save(<fname>, <array>, <allow_pickle>, <fix_imports>)

  • <fname>为需要保存的文件名
  • <array>为需要保存的数组
  • <allow_pickle>允许使用Python pickles保存对象数组,Python中的pickle用于在保存到磁盘文件或从磁盘文件读取之前,对对象进行序列化和反序列化,默认为False
  • <fix_imports>方便从Pyhton2中读取Python3中保存的数据,默认为True

读取 .npy 文件

numpy.load(<fname>, <allow_pickle>, <fix_imports>)

  • <fname>为需要保存的文件名
  • <allow_pickle>允许使用Python pickles读取对象数组,默认为False
  • <fix_imports>方便从Python2中读取Python3中保存的数据,默认为True

将多个数组保存到以 .npz 为扩展名的文件中
numpy.savez(<fname>, *args, **kwds)

  • <fname>为需要保存的文件名
  • *args为需要保存的数组,可以使用关键字参数为数组命名,否则数组会自动命名为 arr_0, arr_1, …
  • **kwds为需要保存的数组使用的关键字名称

以简单的文本文件格式存储数据
np.savetxt(<fname>, <array>, <fmt>, <delimiter>)

  • <fname>为需要保存的文件名
  • <array>为需要保存的数组
  • <fmt>指定存储数据类型,默认为’%.18e’
  • <delimiter>指定元素之间的分隔符,默认为空格

读取 .txt 文件
np.loadtxt(<fname>, <dtype>, <delimiter>)

  • <fname>为需要读取的文件名
  • <dtype>指定读取所返回的数据类型,默认为float
  • <delimiter>指定读取的分隔符,默认无分隔符

矩阵

自 1.19.0 版本后Numpy官方已不推荐引用numpy.matlib方法,同时不推荐通过矩阵类表示矩阵或处理线性代数问题(见 https://docs.scipy.org/doc/numpy/user/numpy-for-matlab-users ) ,建议使用常规Ndarray类。

  • Title: Numpy库的主要使用方法
  • Author: Zielorem
  • Created at : 2022-10-14 17:52:51
  • Updated at : 2023-07-14 01:07:05
  • Link: https://zielorem.github.io/2022/10/14/numpy/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments