【NumPy】官方文档详解(二)NumPy快速入门:基础知识

这部分是NumPy数组的快速概述,演示了 n 维 (n>=2) 数组是如何表示和操作的,介绍了如何将常用函数应用于 n 维数组(不使用 for 循环),以及n 维数组的轴和形状属性。

目录

一、基本属性

NumPy的主要对象是同构多维数组。它是一个元素(通常是数字)表,所有元素(通常是数字)都具有相同的类型,由非负整数元组索引。在NumPy中,维度称为轴。

数组对象的基本属性

属性 解释
ndarray.ndim 数组的轴数(维数)
ndarray.shape 数组的尺寸。返回一个整数元组,元组的长度是轴数,元组中的元素指示每个维度中数组的大小。
ndarray.size 数组的元素总数。这等于shape元组中所有元素的乘积。
ndarray.dtype 描述数组中元素类型的对象。可以使用标准Python类型创建或指定dtype。此外,NumPy还提供了自己的类型,如numpy.int32、numpy.int16 、numpy.float64
ndarray.itemsize 数组中每个元素的大小(以字节为单位)
ndarray.data 包含数组实际元素的缓冲区。通常,我们不需要使用此属性,因为我们将使用索引工具访问数组中的元素。
a=np.arange(15).reshape(3,5)
print(a)
print(type(a))
print(a.ndim)
print(a.shape)
print(a.size)
print(a.dtype.name)
print(a.itemsize)
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]           # a
<class 'numpy.ndarray'>      # type(a)
2             # a.ndim 维数
(3, 5)        # a.shape 
15            # a.size   3*5=15
int32         # a.dtype
4             # a.itemsize

二、创建数组

1. 从常规Python列表或元组出发创建数组

  • 注意参数必须是单个序列,而不能直接输入序列中的各个值
  • 可以将序列的序列转化为二维数组,将序列的序列序列转化为三维数组
  • 可以在创建时显式制定数组元素的类型
a=np.array([1,2,3,4,5],dtype=float)  # 列表转换为一维数组
b=np.array([(1,2,3,4),(5,6,7,8)])    # 元组的列表转换为二维数组
c=np.array([[( 1, 2, 3, 4),( 5, 6, 7, 8)],
            [( 9,10,11,12),(13,14,15,16)],
            [(17,18,19,20),(21,22,23,24)]])
[1. 2. 3. 4. 5.]   ------- a   

[[1 2 3 4]
 [5 6 7 8]]        ------- b    

[[[ 1  2  3  4]    
  [ 5  6  7  8]]

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

 [[17 18 19 20]
  [21 22 23 24]]]  ------- c

2. 创建具有初始占位符内容的数组

通常,最初数组的元素是未知的,但其大小是已知的。因此,NumPy提供了几个函数来创建具有初始占位符内容的数组,这最大限度地减少了数组动态增长的必要性。

a=np.zeros((2,3))     # 创建一个充满0的数组,参数是表明数组形状的元组
b=np.ones((2,3))      # 创建一个充满1的数组,参数是表明数组形状的元组
c=np.empty((2,3,4))   # 创建一个数组,其初始内容是随机的
[[0. 0. 0.]
 [0. 0. 0.]]
 
[[1. 1. 1.]
 [1. 1. 1.]]
 
[[[1.06018346e-311 8.26448246e-315 8.26448183e-315 8.26448198e-315]
  [1.06018346e-311 1.06018346e-311 8.26448752e-315 1.06018346e-311]
  [8.26448325e-315 1.06018346e-311 8.26448183e-315 1.06018346e-311]]
 [[8.26448752e-315 1.06018346e-311 8.26448198e-315 1.06018346e-311]
  [8.26448183e-315 8.26448183e-315 1.06018346e-311 8.26448214e-315]
  [1.06018346e-311 8.26448183e-315 1.06018346e-311 8.26449953e-315]]]

3. 创建数字序列

np.arange(x,y,z):创建一个 [ x , y ) [x,y) [x,y) 内以z为步长的数组
np.linspace(x,y,z):创建一个 [ x , y ] [x,y] [x,y] 内步长相同有z个值的数组(平均分成z-1份)

a=np.arange(10,30,5)
b=np.arange(0,2,0.3)
c=np.linspace(0,2,9)

x = np.linspace(0, 2 * math.pi, 10) #在0~2π之间取10个点
y = np.sin(x)                       #用以绘制y=sin(x)函数图
[10 15 20 25]                   # a -步长为5,包括10,不包括30
[0.  0.3 0.6 0.9 1.2 1.5 1.8]   # b
[0.   0.25 0.5  0.75 1.   1.25 1.5  1.75 2.  ]  # c

绘制出x-y关系图,可以看到当点取得够多,就可以绘制出非常平滑的图,因此np.linspace经常被用来生成序列绘制函数图像。

【NumPy】官方文档详解(二)NumPy快速入门:基础知识

三、打印数组

打印数组时,NumPy 以类似于嵌套列表的方式显示它,但具有以下布局:

  • 最后一个轴从左到右打印
  • 倒数第二个从上到下打印
  • 其余部分也从上到下打印,每个切片与下一个切片之间用空行隔开

然后将一维数组打印为行,将二维数组打印为矩阵,将三维数组打印为矩阵列表。

我尝试了一个四维数组:a=np.arange(120).reshape((2,3,4,5))

[[[[  0   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  33  34]
   [ 35  36  37  38  39]]

  [[ 40  41  42  43  44]
   [ 45  46  47  48  49]
   [ 50  51  52  53  54]
   [ 55  56  57  58  59]]]


 [[[ 60  61  62  63  64]
   [ 65  66  67  68  69]
   [ 70  71  72  73  74]
   [ 75  76  77  78  79]]

  [[ 80  81  82  83  84]
   [ 85  86  87  88  89]
   [ 90  91  92  93  94]
   [ 95  96  97  98  99]]

  [[100 101 102 103 104]
   [105 106 107 108 109]
   [110 111 112 113 114]
   [115 116 117 118 119]]]]

对于 n p . a r a n g e ( X ) . r e s h a p e ( ( x 1 , x 2 , . . . , x n − 1 , x n ) ) np.arange(X).reshape\big((x_1,x_2,...,x_{n-1},x_n)\big) np.arange(X).reshape((x1​,x2​,...,xn−1​,xn​)),满足:

  • X = ∏ i = 1 n x i X=\prod\limits_{i=1}^nx_i X=i=1∏n​xi​
  • python显示的结果看起来是一个个矩阵, x n − 1 x_{n-1} xn−1​行 x n x_n xn​ 列

.
如果数组太大而无法打印,NumPy 会自动跳过数组的中心部分,只打印角,要禁用此行为并强制 NumPy 打印整个数组,可以使用 np.set_printoptions(threshold=sys.maxsize)


四、基本运算

1.数组上的算术运算符将逐个计算对应元素 ,并创建一个新数组进行结果填充

注意区别对应元素相乘矩阵相乘,前者a*b 或np.multiply,后者用a@b或a.dot(b)

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

print(a*b)
print(np.multiply(a,b))
print(a@b)
print(a.dot(b))
[[ 9 18]
 [27 36]]               # a-b
 
[[ 100  400]
 [ 900 1600]]           # a^2
 
[[ True  True]
 [False False]]         # a>25
 
[[ 10  40]
 [ 90 160]]             # a*b
 
[[ 10  40]
 [ 90 160]]             # np.multiply(a,b)
 
[[ 70 100]
 [150 220]]             # a@b
 
[[ 70 100]
 [150 220]]             # a.dot(b)

2.某些操作(如 +=)会就地修改现有数组,而不是创建新数组

3.当处理不同类型的数组时,生成的数组的类型对应于更通用或更精确的数组类型(这种行为称为 upcasting)

4.许多一元运算(如计算数组中所有元素的总和)都是作为类的方法实现的,作用于整个数组,就好像它是一个数字列表一样,无论其形状如何。通过axis参数也可以沿数组的指定轴应用操作

a=np.array([(10,20),(30,40)])
print(a.sum())   # 求所有元素和   100
print(a.max())   # 求所有元素中的最大值  40
print(a.min())   # 求所有元素中的最小值  10
a=np.array([(10,20),(30,40)])
print(a.sum(axis=0))   # 每一列元素和  [40 60]
print(a.max(axis=0))   # 每一列最大值  [30 40]
print(a.min(axis=1))   # 每一行最小值  [10 30]

五、通用函数

这里列举了一些常用的函数,它们大部分都有着较为丰富的扩展功能以满足各种需求,比如很多计算可以针对整个数组,也可以针对某一个轴进行,且有的操作会改变原数组,而有的操作不改变,这里先不详述,只表达一种最简单的使用情况。

函数 解释
np.exp(A) 计算指数
np.sqrt(A) 计算平方根
np.add(A,B) 计算数组A,B对应元素相加,即A+B
np.average(A) 计算平均值,可以计算加权平均值
np.mean(A) 计算平均值,无法计算加权平均
np.maximum(A,B) 取对应位置较大的元素形成新的数组
np.minimum(A,B) 取对应位置较小的元素形成新的数组
np.median(A) 计算所有元素的中位数
np.prod(A) 计算所有元素相乘的结果
np.sort(A) 返回一个排序后的副本,A本身不变
np.std(A) 计算标准差
np.var(A) 计算方差

六、索引 切片和迭代

以为数组的索引、切片、迭代和标准Python序列(如列表)类似。而对于多维的数组:

  • 每个轴都可以有一个索引,通过以逗号分隔的元组进行设置。
  • 切片时,冒号表示切片范围,逗号隔开不同的轴,…(点号) 表示生成完整索引元组所需的任意数量的冒号
  • 迭代多维数组是相对于第一个轴进行的。但是,如果要对数组中的每个元素执行操作,则可以使用属性flat,该属性是数组中所有元素的迭代器.

这里打算另外写一篇详细探讨

上一篇:Python深度学习基于PyTorch:第1章 NumPy基础


下一篇:[云炬python学习笔记]Numpy中内置函数min(),max(),sum()与Python中内置函数min(),max(),sum()性能对比分析