文章目录

  • 1 NumPy介绍
  • 1.1 Ndarray对象
  • 2 NumPy 数组属性
  • 3 NumPy 创建数组
  • 3.1 numpy.empty
  • 3.2 numpy.zeros
  • 3.3 numpy.ones
  • 4 NumPy 从已有的数组创建数组
  • 5 Numpy基本运算
  • 5.1 一维矩阵运算
  • 5.2 多维矩阵运算
  • 5.3 基本计算
  • 6 Numpy索引与切片
  • 7 Numpy array合并
  • 7.1 数组合并
  • 7.2 数组转置为矩阵
  • 7.3 矩阵合并
  • 8.广播机制
  • 9.常用函数
  • 9.1 np.bincount()
  • 9.2 np.argmax()


1 NumPy介绍

NumPy(Numeric Python)提供了许多高级的数值编程工具,如:矩阵数据类型、矢量处理,以及精密的运算库。专为进行严格的数字处理而产生。多为很多大型金融公司使用,以及核心的科学计算组织如:Lawrence Livermore,NASA用其处理一些本来使用C++,Fortran或Matlab等所做的任务。

NumPy是一个用python实现的科学计算的扩展程序库,包括:

  • 1、一个强大的N维数组对象Array;
  • 2、比较成熟的(广播)函数库;
  • 3、用于整合C/C++和Fortran代码的工具包;
  • 4、实用的线性代数、傅里叶变换和随机数生成函数。numpy和稀疏矩阵运算包scipy配合使用更加方便。

1.1 Ndarray对象

NumPy 最重要的一个特点是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。

  • ndarray 对象是用于存放同类型元素的多维数组。
  • 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

指定生成数组的最小维度

import numpy as np
a = np.array([1,2,3])
a

多于一个维度:

a = np.array([[1,  2],  [3,  4]])  
a

2 NumPy 数组属性

NumPy 数组的维数称为秩(rank),秩就是轴的数量,即数组的维度,一维数组的秩为 1,二维数组的秩为 2,以此类推。
在 NumPy中,每一个线性的数组称为是一个轴(axis),也就是维度(dimensions)。比如说,二维数组相当于是两个一维数组,其中第一个一维数组中每个元素又是一个一维数组。所以一维数组就是 NumPy 中的轴(axis),第一个轴相当于是底层数组,第二个轴是底层数组里的数组。而轴的数量——秩,就是数组的维数。
很多时候可以声明 axis。axis=0,表示沿着第 0 轴进行操作,即对每一列进行操作;axis=1,表示沿着第1轴进行操作,即对每一行进行操作。

NumPy 的数组中比较重要 ndarray 对象属性有:

属性

说明

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

包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。

3 NumPy 创建数组

ndarray 数组除了可以使用底层 ndarray 构造器来创建外,也可以通过以下几种方式来创建。数据元素默认都是浮点型。

3.1 numpy.empty

numpy.empty 方法用来创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组:
numpy.empty(shape, dtype = float, order = ‘C’)
参数说明:

参数

描述

shape

数组形状

dtype

数据类型,可选

order

有"C"和"F"两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序。

x = np.empty([3,2], dtype = int) 
x

3.2 numpy.zeros

创建指定大小的数组,数组元素以 0 来填充:
numpy.zeros(shape, dtype = float, order = ‘C’)
参数说明:

参数

描述

shape

数组形状

dtype

数据类型,可选

order

‘C’ 用于 C 的行数组,或者 ‘F’ 用于 FORTRAN 的列数组

# 默认为浮点数
x = np.zeros(5) 
x
 
# 设置类型为整数
y = np.zeros((5,), dtype = np.int) 
y
 
# 自定义类型
z = np.zeros((2,2), dtype = [('x', 'i4'), ('y', 'i4')])  
z

3.3 numpy.ones

创建指定形状的数组,数组元素以 1 来填充:
numpy.ones(shape, dtype = None, order = ‘C’)
参数说明:

参数

描述

shape

数组形状

dtype

数据类型,可选

order

‘C’ 用于 C 的行数组,或者 ‘F’ 用于 FORTRAN 的列数组

# 默认为浮点数
x = np.ones(5) 
x 
# 自定义类型
x = np.ones([2,2], dtype = int)
x

4 NumPy 从已有的数组创建数组

numpy.asarray
numpy.asarray 类似 numpy.array,但 numpy.asarray 参数只有三个,比 numpy.array 少两个。
numpy.asarray(a, dtype = None, order = None)
参数说明:

参数

描述

a

任意形式的输入参数,可以是,列表, 列表的元组, 元组, 元组的元组, 元组的列表,多维数组

dtype

数据类型,可选

order

可选,有"C"和"F"两个选项,分别代表,行优先和列优先,在计算机内存中的存储元素的顺序。

实例
将列表转换为 ndarray:

x =  [1,2,3] 
a = np.asarray(x)  
a

将元组转换为 ndarray:

x =  (1,2,3) 
a = np.asarray(x)  
a

将元组列表转换为 ndarray:

x =  [(1,2,3),(4,5)] 
a = np.asarray(x)  
a

设置了 dtype 参数:

x =  [1,2,3] 
a = np.asarray(x, dtype =  float)  
a

5 Numpy基本运算

5.1 一维矩阵运算

# 一维矩阵运算
a = np.array([10,20,30,40])
b = np.arange(4)
print(a,b)

运行结果:
[10 20 30 40] [0 1 2 3]

c = a - b
print(c)

运行结果:
[10 19 28 37]

print(a*b) # 若用a.dot(b),则为各维之和

运行结果:
[ 0 20 60 120]

# 在Numpy中,想要求出矩阵中各个元素的乘方需要依赖双星符号 **,以二次方举例,即:
c = b**2
print(c)

运行结果:
[0 1 4 9]

print(b<2)

运行结果:
[ True True False False]

a = np.array([1,1,4,3])
b = np.arange(4)
print(a==b)

运行结果:
[False True False True]

# Numpy中具有很多的数学函数工具
c = np.sin(a)
print(c)

运行结果:
[-0.54402111 0.91294525 -0.98803162 0.74511316]

5.2 多维矩阵运算

a = np.array([[1,0],[1,1]])
b = np.arange(4).reshape((2,2))
print(a)
print(b)

运行结果:
[[1 0]
[1 1]]
[[0 1]
[2 3]]

# 多维度矩阵乘法
# 第一种乘法方式:
c = a.dot(b)
print(c)

运行结果:
[[0 1]
[2 4]]

# 第二种乘法:
c = np.dot(a,b)
print(c)

运行结果:
[[0 1]
[2 4]]

# 多维矩阵乘法不能直接使用'*'号
c = a*b
print(c)

运行结果:
[[0 0]
[2 3]]

# 在numpy中可以使用@修饰符进行矩阵乘法
c = a@b
print(c)

运行结果:
[[0 1]
[2 4]]

a = np.random.random((2,4))
print(a)
print(np.sum(a))

[[0.2966233 0.86804229 0.22447738 0.57609487]
[0.49534622 0.09487038 0.01254559 0.33490257]]
2.902902603234563

print(np.min(a))
print(np.max(a))

运行结果:
0.012545589390995704
0.8680422877687684

#如果你需要对行或者列进行查找运算,
就需要在上述代码中为 axis 进行赋值。
当axis的值为0的时候,将会以列作为查找单元,
当axis的值为1的时候,将会以行作为查找单元。
print("sum=",np.sum(a,axis=1))
print("min=",np.min(a,axis=0))
print("max=",np.max(a,axis=1))

运行结果:
sum= [1.96523784 0.93766476]
min= [0.2966233 0.09487038 0.01254559 0.33490257]
max= [0.86804229 0.49534622]

5.3 基本计算

A = np.arange(0,12).reshape((3,4))
print(A)

运行结果:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]

# 最小元素索引
print(np.argmin(A)) # 0
# 最大元素索引
print(np.argmax(A)) # 11

运行结果:
0
11

# 求整个矩阵的均值
print(np.mean(A)) # 5.5
print(np.average(A)) # 5.5
print(A.mean()) # 5.5

运行结果:
5.5
5.5
5.5

# 矩阵转置
print(A.T)

运行结果:
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]

6 Numpy索引与切片

A = np.arange(0,12)
print(A)

运行结果:
[ 0 1 2 3 4 5 6 7 8 9 10 11]

print(A[3])

运行结果:
3

B = A.reshape(3,4)
print(B)

运行结果:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]

print(B[2])

运行结果:
[ 8 9 10 11]

print(B[0][2])

运行结果:
2

print(B[0,2])

运行结果:
2

# list切片操作
print(B[1,1:3]) # [5 6] 1:3表示1-2不包含3

运行结果:
[5 6]

for row in B:
    print(row)

运行结果:
[0 1 2 3]
[4 5 6 7]
[ 8 9 10 11]

# 如果要打印列,则进行转置即可
for column in B.T:
    print(column)

运行结果:
[0 4 8]
[1 5 9]
[ 2 6 10]
[ 3 7 11]

# 多维转一维
A = np.arange(3,15).reshape((3,4))
# print(A)
print(A.flatten())
# flat是一个迭代器,本身是一个object属性

运行结果:
[ 0 1 2 3 4 5 6 7 8 9 10 11]

for item in A.flat:
    print(item)

运行结果:
0
1
2
3
4
5
6
7
8
9
10
11

7 Numpy array合并

7.1 数组合并

A = np.array([1,1,1])
B = np.array([2,2,2])
print(np.vstack((A,B)))
# vertical stack 上下合并,对括号的两个整体操作。

运行结果:
[[1 1 1]
[2 2 2]]

C = np.vstack((A,B))
print(C)

运行结果:
[[1 1 1]
[2 2 2]]

# horizontal stack左右合并
D = np.hstack((A,B))
print(D)

运行结果:
[1 1 1 2 2 2]

print(A.shape,B.shape,D.shape)
# (3,) (3,) (6,)
# 对于A,B这种,为数组或数列,无法进行转置,需要借助其他函数进行转置

运行结果:
(3,) (3,) (6,)

7.2 数组转置为矩阵

print(A[np.newaxis,:]) # [1 1 1]变为[[1 1 1]]

运行结果:
[[1 1 1]]

print(A[np.newaxis,:].shape) # (3,)变为(1, 3)

运行结果:
(1, 3)

print(A[:,np.newaxis])

运行结果:
[[1]
[1]
[1]]

7.3 矩阵合并

# concatenate函数合并矩阵
A = A[:,np.newaxis] # 数组转为矩阵
B = B[:,np.newaxis] # 数组转为矩阵
# axis=0纵向合并
C = np.concatenate((A,B,B,A),axis=0)
print(C)

运行结果:
[[1]
[1]
[1]
[2]
[2]
[2]
[2]
[2]
[2]
[1]
[1]
[1]]

# axis=1横向合并
C = np.concatenate((A,B),axis=1)
print(C)

运行结果:
[[1 2]
[1 2]
[1 2]]

8.广播机制

广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行。
如果两个数组 a 和 b 形状相同,即满足 a.shape == b.shape,那么 a*b 的结果就是 a 与 b 数组对应位相乘。这要求维数相同,且各维度的长度相同。

a = np.array([1,2,3,4]) 
b = np.array([10,20,30,40]) 
c = a * b 
print (c)

运行结果:
[ 10 40 90 160]

当运算中的 2 个数组的形状不同时,numpy 将自动触发广播机制。如:

a = np.array([[ 0, 0, 0],
           [10,10,10],
           [20,20,20],
           [30,30,30]])
b = np.array([1,2,3])
print(a + b)

运行结果:
[[ 1 2 3]
[11 12 13]
[21 22 23]
[31 32 33]]

9.常用函数

9.1 np.bincount()

# 统计索引出现次数
x = np.array([1, 2, 3, 3, 0, 1, 4])
np.bincount(x)

运行结果:
array([1, 2, 1, 2, 1], dtype=int64)
# 索引0出现1次,1出现2次,2出现1次,3出现2次,4出现1次

# 加上weights参数设置权重
w = np.array([0.3,0.5,0.7,0.6,0.1,-0.9,1])
np.bincount(x,weights=w)

运行结果:
array([ 0.1, -0.6, 0.5, 1.3, 1. ])
# 索引 0 出现在x中index=4位置,那么在w中访问index=4的位置即可,w[4]=0.1

9.2 np.argmax()

numpy.argmax(a, axis=None, out=None)
函数表示返回沿轴axis最大值的索引。

x = [[1,3,3],
     [7,5,2]]
print(np.argmax(x))

运行结果:
3

# axis=0表示按列操作
x = [[1,3,3],
     [7,5,2]]
print(np.argmax(x,axis=0))

运行结果:
[1 1 0]

# axis=1表示按行操作
x = [[1,3,3],
     [7,5,2]]
print(np.argmax(x,axis=1))

运行结果:
[1 0]

x = np.array([1, 3, 2, 3, 0, 1, 0])
print(x.argmax())

运行结果:
1
# 碰到重复最大元素返回第一个最大值索引