首页 > 其他分享 >NumPy库的基本使用

NumPy库的基本使用

时间:2024-10-18 23:42:50浏览次数:1  
标签:基本 10 arr arr1 np 数组 使用 print NumPy

1. NumPy基础

全称:Numeric Python

  • NumPy是Python的科学计算基础库
  • NumPy底层是C语言编写的,可以对数组进行高效的数学运算
  • NumPy的ndarray对象可以用来构建多维数组
  • NumPy能够执行傅里叶变换与重塑多维数组形状
  • NumPy提供了线性代数,以及随机数生成的内置函数

1.1 为什么需要使用NumPy库?

Python里并没有数组变量类型,常用的list列表类型可以存储不同数据类型的值,这就导致我们需要为每一个元素都单独存储它的数据类型,造成了内存的浪费,当我们需要管理相同类型的值且需要对这些值进行更细节的操作时,Python的列表类型远远达不到我们的要求,且Python的计算速度也太慢。

而NumPy库为Python加上了关键的数组变量类型,每一个数组的所有元素必须是相同的数据类型,且提供了全方面的细节操作,底层用C语言编写,计算速度也很快。

1.2 NumPy ndarray对象

我们在导入NumPy时,通常给其一个别名:np,即import numpy as np

NumPy中的数组对象称为ndarray。
可以使用array()函数创建一个NumPy ndarray对象。

注意:数组输出[ ]中没有逗号,列表有逗号,注意区分

import numpy as np

arr = np.array([1, 2, 3, 4, 5])
print(arr)	# [1 2 3 4 5]
print(type(arr))	# <class 'numpy.ndarray'>

可以将列表、元组或任意类型数组的对象传递给array()方法,然后它将会被转化为ndarray。

arr = np.array((1, 2, 3, 4, 5))
print(arr)  # [1 2 3 4 5]

1.3 数据类型

理论上来说,数组有好多数据类型,但这里我们只讲解最常用的两种数据类型:整数型数组和浮点型数组,其余类型相同用法。

arr1 = np.array([1, 2, 3])	# 元素都是整数,则为整数型数组
print(arr1.dtype)   # int64
print(arr1) # [1 2 3]
arr2 = np.array([1.0, 2, 3])	# 元素存在浮点数,则为浮点型数组
print(arr2.dtype)   # float64
print(arr2) # [1. 2. 3.]

1.3.1 数据类型同化原理(个人无法改变集体)

注意:

  • 当整数型数组已经创建完毕,往里插入/修改为浮点数,该浮点数会自动同化为整数(数据截断)
  • 当浮点型数组已经创建完毕,往里插入/修改为整数,该整数会自动同化为浮点数(数据升级)
arr1 = np.array([1, 2, 3])	# 元素都是整数,则为整数型数组
arr1[1] = 4.1
print(arr1) # [1 4 3]
arr2 = np.array([1.0, 2, 3])	# 元素存在浮点数,则为浮点型数组
arr2[2] = 4
print(arr2) # [1. 2. 4.]

1.3.2 数据类型转化(共同改变定理)

将整个数组的数据类型共同改变,规范化的方式是使用ndarray.astype(想改成的数据类型)

arr1 = np.array([1, 2, 3])	# 元素都是整数,则为整数型数组
print(arr1) # [1 2 3]
print(arr1.astype(float))   # [1. 2. 3.]
arr2 = np.array([1.0, 2, 3])	# 元素存在浮点数,则为浮点型数组
print(arr2) # [1. 2. 3.]
print(arr2.astype(int))   # [1 2 3]

只要符合共同改变定理,即可以全部转化成功,所以可以使用数组的共同计算来改变数据类型,最常见的是整数型数组在运算过程中升级为浮点型数组。

浮点型数组在运算过程中一般是不会降级的,所以这里重点考虑整数型数组的升级即可

arr1 = np.array([1, 2, 3])	# 元素都是整数,则为整数型数组
print(arr1) # [1 2 3]
# 整数型数组和浮点数做运算(+  -  *)
print(arr1 + 1.0)   # [2. 3. 4.]
# 整数型数组遇到除法运算,即便是除以整数也会变为浮点数(/)
print(arr1 / 1) # [1. 2. 3.]
# 整数型数组和浮点型数组做运算(+  -  *  /)
arr2 = np.array([1.0, 2.0, 3.0])
print(arr1 + arr2)  # [2. 4. 6.]

1.4 数组维度

维度数 = 中括号层数

不同维度的数组之间,从外形上的本质区别是几维数组就有几层中括号。

1.4.1 形状:shape

不同数组有不同的形状表示:

  • 一维数组(向量):x(x,)
    • 如:[1, 2, 3].shape = (3,)
  • 二维数组(矩阵):(x, y)
    • 如:[[1 2 3]].shape = (1, 3)
  • 三维数组:(x, y, z)
    • 如:[[[1 2 3]]].shape = (1, 1, 3)

查询数组形状语法:ndarray.shape

1.4.2 维度转换:reshape

数组的重塑语法:ndarray.reshape(shape)(shape是重塑后的形状参数)

用于调整数组形状,重塑后并不会产生新的数组,只是产生新的视图(类似指针)。

该方法在填写形状值时,给定了其它维度的值,剩下一个维度可以填-1,让它自己去计算。

当把多维数组降为一维数组时,直接reshape(-1)即可

arr1 = np.arange(10)	# 创建包含0到10的数组,不包括10
print(arr1) # [0 1 2 3 4 5 6 7 8 9]
# 升维
arr2 = arr1.reshape(2, -1)  # 自动计算成(2,5)
print(arr2)
'''
[[0 1 2 3 4]
 [5 6 7 8 9]]
'''
# 降维
arr3 = arr2.reshape(-1)
print(arr3)     # [0 1 2 3 4 5 6 7 8 9]

1.5 NumPy其它属性操作

  • ndarray.dtype:返回数组的数据类型。

  • ndarray.itemsize:返回数组中每个元素的大小(即每个元素占用的字节数)。

  • ndarray.shape:返回数组的形状。

    • shape属性的返回值是一个由数组维度构成的元组,如:2行3列的二维数组返回(2,3),该属性也可以用来调整数组维度大小。
  • ndarray.size:同np.size(ndarray),返回数组中的所有底层标量元素的个数。

  • ndarray.ndim:返回数组的维数,如二维数组返回2。

  • ndarray.flags:返回数组的内存信息,如:ndarray数组的存储方式,以及是否是其它数组的副本等。

  • ndarray.fill(?):把某数填充到数组中

import numpy as np

arr = np.array([[1, 2, 3, 4, 5],[6, 7, 8, 9, 10]])
print(arr.dtype)        # int64
print(arr.itemsize)     # 8
print(arr.size)         # 10
print(arr.ndim)         # 2
print(arr.shape)        # (2, 5)
print(arr.flags)
'''
  C_CONTIGUOUS : True
  F_CONTIGUOUS : False
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  WRITEBACKIFCOPY : False

'''
arr.fill(0)
print(arr)
'''
[[0 0 0 0 0]
 [0 0 0 0 0]]
'''

2. 数组初始化

2.1 创建指定数组

一般来说,当明确知道数组每一个元素的具体数值时,可以使用np.array()函数创建一个NumPy ndarray对象。

向量是最节省内存的数组结构,列矩阵是最消耗内存的数组结构。

# 创建一维数组——向量
arr1 = np.array([1, 2, 3])
print(arr1)     # [1 2 3]
# 创建二维数组——行矩阵
arr2 = np.array([[1, 2, 3]])
print(arr2)     # [[1 2 3]]
# 创建二维数组——列矩阵
arr3 = np.array([[1], [2], [3]])
print(arr3)
'''
[[1]
 [2]
 [3]]
'''
# 创建二维数组——矩阵
arr4 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr4)
'''
[[1 2 3]
 [4 5 6]]
'''

2.2 创建同值数组

语法:np.zeros(shape)

语法:np.ones(shape)

这两个函数一般用来创建元素均为0或1的数组,同时还可以指定数组形状,需要注意的是,两个函数里的数据类型默认为浮点型,并不是整数,这是为了避免用户后期插入进去的浮点数被截断导致数据损失

arr = np.zeros(3)
print(arr)  # [0. 0. 0.]

arr = np.zeros((3,2))
print(arr)
'''
[[0. 0.]
 [0. 0.]
 [0. 0.]]
'''
brr = np.ones((4,3))
print(brr)
'''
[[1.+0.j 1.+0.j 1.+0.j]
 [1.+0.j 1.+0.j 1.+0.j]
 [1.+0.j 1.+0.j 1.+0.j]
 [1.+0.j 1.+0.j 1.+0.j]]
'''

除了创建元素0或1的数组外,该方法还可以用来创建其它同值数组,只需要满足共同改变定理。

arr = 12 * np.ones(3)
print(arr)  # [12. 12. 12.]

2.3 创建随机数组

使用np.random系列函数可以创建随机数组。

  • 0-1均匀分布的浮点型随机数组:np.random.random(shape)
arr = np.random.random(5)
print(arr)  # [0.34733891 0.57971267 0.80269101 0.76184404 0.21501071]

该方法很灵活,若想创建50到100范围内均匀分布的3*3随机数组:(100-50) * np.random.random((3,3)) + 50

即:波动值 * np.random.random((3,3)) + 下限

  • 整数型随机数组:np.random.randint(start, end, shape)
# 创建10到100之间形状为(1,15)的随机矩阵
A = np.random.randint(10, 100, (1, 15))
print(A)    # [[23 96 59 86 92 71 64 19 19 22 18 76 10 63 12]]
  • 服从正态分布的随机数组:np.random.normal(均值, 标准差, (形状))

还有种更简单的写法:np.random.randn(shape)

A = np.random.normal(0, 1, (2,3))
print(A)    
'''
[[-1.02794824 -1.00740807  0.57600102]
 [ 0.90604223  0.72598196 -0.3247751 ]]
'''

A = np.random.randn(2,3)
print(A)
'''
[[-0.85803819  1.55360033 -0.95891918]
 [-0.2942526  -0.28620573 -0.56165943]]
'''

2.4 创建区间数组:arange

可以使用arange()来创建给定数值范围的数组,也叫递增数组。

语法:np.arange(start, end, step)

  • start:起始值,默认为0(可不写)
  • end:终止值,不包含该值
  • step:步长,默认为1(可不写)

数据类型默认为整数,需要浮点型的可以使用np.arange(7.0)1.0 * np.arange(7)来进行创建,或定义dtype = float

arr = np.arange(7)
print(arr)  # [0 1 2 3 4 5 6]

arr = np.arange(1, 9, 2, dtype=float)
print(arr)  # [1. 3. 5. 7.]

2.5 创建等差数组:linspace

表示在指定的数值区间内,返回均匀间隔的一维等差数列,默认均分50份。

语法:np.linspace(start, end, num=50, endpoint=True)

  • num:表示均分多少份(可不写)
  • endpoint:若为True,则数列包含end,反之不包含(可不写)
arr = np.linspace(1, 10, 5)
print(arr)  # [ 1.    3.25  5.5   7.75 10.  ]

2.6 创建等比数组:logspace

语法:np.logspace(start, end, num=50, endpoint=True)

arr = np.logspace(0, 1, 5)
print(arr)  # [ 1.          1.77827941  3.16227766  5.62341325 10.        ]

2.7 创建未初始化的数组

对于未初始化的数组,会给他随便赋一个值。

语法:np.empty(shape, dtype)

  • shape:指定数组的形状
  • dtype:数组元素的数据类型,默认为float(可不写)
arr = np.empty((3,2), dtype=int)
print(arr)
'''
[[-9223369491628071134      806051871720660]
 [       2545226692878        2545226692886]
 [                   3                   29]]
'''

3. 索引与切片

在NumPy中,如果想要访问或修改数组中的元素,可以采用索引或切片的方式,这与Python的list列表是相同的。

3.1 普通索引

访问数组元素需要使用数组索引。

NumPy数组中的索引以0开头,与Java等数组不同的是,其索引可以使用负数。

第一个元素索引号:0,最后一个元素索引号可以表示为:-1(正着数从0开始,倒着数从-1开始)

arr = np.array([1, 2, 3, 4])
# 获取第一个元素
print(arr[0])
# 获取最后一个元素
print(arr[-1])
# 将第二个和第三个元素相加
print(arr[1] + arr[2])
'''
1
4
5
'''

arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
# 获取第一维中的第二个元素
print(arr[0, 1])
# 获取第二维中的第4个元素
print(arr[1, 3])
# 用负索引
print(arr[1, -1])
'''
2
8
8
'''

访问矩阵也是一样的道理,注意使用普通索引时,索引外面只套一层中括号

[
    [1,2,3],
    [4,5,6],
    [7,8,9]
]
取5:arr[1,1]	# 5
取第二行所有值:arr[1]	# [4,5,6]
取第二列所有制:arr[:,1]	# [2,5,8]		:表示所有
取第一行的前两个值:arr[0,0:2]	# [1,2]		里面可以写切片格式

3.2 花式索引

普通索引用一层中括号,而花式索引用两层中括号

花式索引更加高效。

# 向量的花式索引
arr1 = np.arange(0, 100, 10)
print(arr1)     # [ 0 10 20 30 40 50 60 70 80 90]
# 花式索引:取第0个和第2个位置的元素,并将其组成向量输出
print(arr1[[0, 2]]) # [ 0 20]

# 矩阵的花式索引
arr2 = np.arange(0, 100, 10).reshape(2, -1)
print(arr2)
'''
[[ 0 10 20 30 40]
 [50 60 70 80 90]]
'''
# 花式索引1:表示先取出第0索引行和第1索引行,再取出第0索引行第1索引列和第1索引行第3索引列的元素
print(arr2[[0, 1], [1, 3]])     # [10 80]
# 花式索引2:
print(arr2[[0, 1, 0], [1, 2, 3]])   # [10 70 30]

怎么理解:","前的向量表示行元素,后的向量表示列元素,所以两个向量相同位置为一组坐标,按位置找出元素组成新的向量输出打印。

3.3 基本切片

切片方式返回的是数组视图(浅拷贝,类似指针)

NumPy中有两种切片方式。

一种是使用NumPy的内置函数slice()来创建切片对象,将其传入数组中(不推荐)ndarray[slice(start, end, step)]

arr = np.array(range(10))
print(arr)      # [0 1 2 3 4 5 6 7 8 9]
print(arr[slice(1, 6, 2)])  # [1 3 5]

一种是直接在ndarray对象上进行冒号切片(推荐)ndarray[start : end : step](注意是冒号)

arr = np.array(range(10))
print(arr)      # [0 1 2 3 4 5 6 7 8 9]
print(arr[1:6:2])  # [1 3 5]

对冒号切片的简单说明:

  • 如果仅输入一个参数,则会返回与索引相对应的元素,如:[3]返回3
  • 如果写这种形式:[:9],则会返回0-8之间的所有数字(左闭右开)
  • 如果是:[2:],则会返回从2到最后的所有数字
  • 如果在两个参数之间:[2:9],则是对两个索引之间进行切片

4. 副本和视图

4.1 副本和视图的区别

副本和数组视图之间的主要区别在于副本是一个新的数组,而视图表示的还是原始数组

副本拥有数据,对副本所作的任何更改都不会影响原始数组,对原始数组所作的任何更改也不会影响副本。

视图不拥有数据,(类似指针),对视图所作的任何更改都会影响原始数组,对原始数组所作的任何更改也会影响视图。

4.2 副本

副本:arr.copy()

arr = np.array([1, 2, 3, 4, 5])
x = arr.copy()
arr[0] = 8
x[-1] = 88
print(arr)  # [8 2 3 4 5]
print(x)    # [ 1  2  3  4 88]

4.3 视图

视图:arr.view()

arr = np.array([1, 2, 3, 4, 5])
x = arr.view()
arr[0] = 8
x[-1] = 88
print(arr)  # [ 8  2  3  4 88]
print(x)    # [ 8  2  3  4 88]

4.4 判断数组是数组还是视图

副本拥有数据,而视图不拥有数据。

每个NumPy数组都有一个属性:base,若该数组有数据,则这个base属性返回None

否则,base属性将引用原始对象。

arr = np.array([1, 2, 3, 4, 5])
x = arr.copy()
y = arr.view()
print(x.base)   # None
print(y.base)   # [1 2 3 4 5]
print(arr.base) # None

5. 数组的变形

5.1 转置

数组的转置方法.T,只对矩阵有效,因此遇到向量(一维数组)需要先将其转为矩阵。

# 向量的转置
arr1 = np.arange(3)
print(arr1)     # [0 1 2]
arr2 = arr1.reshape(1,-1)
print(arr2)     # [[0 1 2]]
print(arr2.T)
'''
[[0]
 [1]
 [2]]
'''

# 矩阵的转置
arr3 = np.arange(10).reshape(2, 5)
print(arr3)
'''
[[0 1 2 3 4]
 [5 6 7 8 9]]
'''
print(arr3.T)
'''
[[0 5]
 [1 6]
 [2 7]
 [3 8]
 [4 9]]
'''

5.2 翻转

数组的反转方法有两个:

  • np.flipud(ndarray):表示up-down,上下翻转;
  • np.fliplr(ndarray):表示left-right,左右翻转。

注意:向量只能上下翻转,因为向量并不是横着排的,在数学中,它是竖着排的

# 向量的翻转
arr1 = np.arange(10)
print(arr1)         # [0 1 2 3 4 5 6 7 8 9]
arr1_ud = np.flipud(arr1)
print(arr1_ud)      # [9 8 7 6 5 4 3 2 1 0]

# 矩阵的翻转
arr2 = np.arange(1,21).reshape(4,5)
print(arr2)
'''
[[ 1  2  3  4  5]
 [ 6  7  8  9 10]
 [11 12 13 14 15]
 [16 17 18 19 20]]
'''
arr2_lr = np.fliplr(arr2)	# 左右翻转
print(arr2_lr)
'''
[[ 5  4  3  2  1]
 [10  9  8  7  6]
 [15 14 13 12 11]
 [20 19 18 17 16]]
'''
arr2_ud = np.flipud(arr2)	# 上下翻转
print(arr2_ud)
'''
[[16 17 18 19 20]
 [11 12 13 14 15]
 [ 6  7  8  9 10]
 [ 1  2  3  4  5]]
'''

5.3 重塑

重塑函数:ndarray.reshape(),可以调整数组形状,重塑后并不会产生新的数组,只是产生新的视图(类似指针)。

# 1. 向量的重塑
arr1 = np.arange(1, 10)
print(arr1)     # [1 2 3 4 5 6 7 8 9]
# 将向量变形为矩阵
arr2 = arr1.reshape(3, 3)
print(arr2)
'''
[[1 2 3]
 [4 5 6]
 [7 8 9]]
'''

# 2. 矩阵的重塑
arr3 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr3)
'''
[[1 2 3]
 [4 5 6]]
'''
# 将矩阵变形为向量
arr4 = arr3.reshape(6)
print(arr4)     # [1 2 3 4 5 6]
# 将矩阵变形为其它形状矩阵
arr5 = arr3.reshape(1, 6)
print(arr5)     # [[1 2 3 4 5 6]]

5.4 拼接

两个数组之间可以进行拼接形成一个新的数组。

语法:np.concatenate([ndarray1, ndarray2], axis=0)

  • axis:表示按什么方向拼接,默认0表示行方向,1表示列方向

5.4.1 向量的拼接

两个向量的拼接,将得到一个加长版的向量。

a1 = np.array([1,2,3])
a2 = np.array([4,5,6])
a3 = np.concatenate([a1, a2])
print(a3)       # [1 2 3 4 5 6]

5.4.2 矩阵的拼接

两个矩阵可以按照不同的维度进行拼接,但是一定注意:拼接时两个矩阵的维度必须吻合

向量和矩阵无法拼接,必须先把向量升级为矩阵

a1 = np.array([[1,2,3], [4,5,6]])
a2 = np.array([[7,8,9], [10,11,12]])
# 按第一个维度(行)拼接
a3 = np.concatenate([a1, a2])   # axis = 0(默认)
print(a3)
'''
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]
'''

# 按第二个维度(列)拼接
a4 = np.concatenate([a1, a2], axis=1)
print(a4)
'''
[[ 1  2  3  7  8  9]
 [ 4  5  6 10 11 12]]
'''

5.5 数组的分割

语法:np.split(ndarray, [start, end])

5.5.1 向量的分割

a1 = np.arange(10, 100, 10)
print(a1)   # [10 20 30 40 50 60 70 80 90]
# 分割数组
a2, a3, a4 = np.split(a1, [2, 5])
print(a2)   # [10 20]
print(a3)   # [30 40 50]
print(a4)   # [60 70 80 90]

5.5.2 矩阵的分割

矩阵的分割可以根据参数axis按照不同的维度进行,分割出来的子元素都是矩阵。

a1 = np.arange(1, 9).reshape(2, 4)
print(a1)
'''
[[1 2 3 4]
 [5 6 7 8]]
'''
# 按照第一个维度(行)分割
a2, a3 = np.split(a1, [1])
print(a2)       # [[1 2 3 4]]
print(a3)       # [[5 6 7 8]]
# 按照第二个维度(列)分割
a4, a5, a6 = np.split(a1, [1, 3], axis=1)
print(a4)
'''
[[1]
 [5]]
'''
print(a5)
'''
[[2 3]
 [6 7]]
'''
print(a6)
'''
[[4]
 [8]]
'''

6. 数组的运算

6.1 数组与系数的运算

NumPy的运算符与Python相同:+、-、*、/、**、//、%、()

arr = np.arange(1, 9).reshape(2, 4)
print(arr)
'''
[[1 2 3 4]
 [5 6 7 8]]
'''
# 加法
print(arr + 10)
'''
[[11 12 13 14]
 [15 16 17 18]]
'''
# 减法
print(arr - 10)
'''
[[-9 -8 -7 -6]
 [-5 -4 -3 -2]]
'''
# 乘法
print(arr * 10)
'''
[[10 20 30 40]
 [50 60 70 80]]
'''
# 除法
print(arr / 10)
'''
[[0.1 0.2 0.3 0.4]
 [0.5 0.6 0.7 0.8]]
'''
# 平方
print(arr ** 2)
'''
[[ 1  4  9 16]
 [25 36 49 64]]
'''
# 取整
print(arr // 6)
'''
[[0 0 0 0]
 [0 1 1 1]]
'''
# 取余
print(arr % 6)
'''
[[1 2 3 4]
 [5 0 1 2]]
'''

6.2 数组与数组的运算

相同维度数组之间的运算即对应元素之间的运算。

遵循逐元素计算。

arr1 = np.arange(-1, -9, -1).reshape(2, 4)
print(arr1)
'''
[[-1 -2 -3 -4]
 [-5 -6 -7 -8]]
'''
arr2 = -arr1
print(arr2)
'''
[[ 1  2  3  4]
 [ 5  6  7  8]]
'''
# 加法
print(arr1 + arr2)
'''
[[ 0  0  0  0]
 [ 0  0  0  0]]
'''
# 减法
print(arr1 - arr2)
'''
[[ -2  -4  -6  -8]
 [-10 -12 -14 -16]]
'''
# 乘法
print(arr1 * arr2)
'''
[[ -1  -4  -9 -16]
 [-25 -36 -49 -64]]
'''
# 除法
print(arr1 / arr2)
'''
[[ 1.  1.  1.  1.]
 [ 1.  1.  1.  1.]]
'''
# 幂方
print(arr1 ** arr2)
'''
[[      -1        4      -27      256]
 [   -3125    46656  -823543 16777216]]
'''

7. 数组的广播

数组可以进行运算。

b = np.array([10,20,30,40])
c = b + 1
print(c)        # [11 21 31 41]

如果进行运算的两个数组形状完全相同,它们可以直接做相应的运算。

a = np.array([0.1,0.2,0.3,0.4])
b = np.array([10,20,30,40])
c = a * b
print(c)        # [ 1.  4.  9. 16.]
b = np.array([10,20,30,40])
c = b + 1
print(c)        # [11 21 31 41]

但如果两个形状不同的数组呢?它们之间就不能做算术运算了吗?当然不是!为了保持数组形状相同,NumPy 设计了一种广播机制,这种机制的核心是对形状较小的数组,在横向或纵向上进行一定次数的重复,使其与形状较大的数组拥有相同的维度。

a = np.array([[ 0, 0, 0],
               [10,10,10],
               [20,20,20],
               [30,30,30]])
#b数组与a数组形状不同
b = np.array([1,2,3])
print(a + b)	# 其实就是b数组在纵向上向下拓展了3次(即将第一行重复3次)
'''
[[ 1  2  3]
 [11 12 13]
 [21 22 23]
 [31 32 33]]
'''

8. 数组的遍历

8.1 for循环遍历

当我们在NumPy中处理数组时,可以使用python的基本for循环来完成此操作。

arr = np.array([1, 2, 3])
for i in arr:
    print(i)
'''
1
2
3
'''

但当我们遍历多维数组时,需要嵌套多个for循环,十分不方便。

8.2 nditer迭代数组

NumPy提供了一个nditer迭代器对象,它可以配合for循环完成对数组元素的遍历。

a = np.arange(0,5)
#使用nditer迭代器,并使用for进行遍历
for x in np.nditer(a):
   print(x)
   '''
   0
   1
   2
   3
   4
   '''

也可以使用flat模块来迭代,见后文。

8.3 遍历中修改元素值

nditer对象提供了一个可选参数op_flags,表示能否在遍历数组时对元素进行修改。

  • read-only:只读。遍历时不可以修改
  • read-write:读写。遍历时可以修改
  • write-only:只写。遍历时可以修改
a = np.arange(0,60,5)
a = a.reshape(3,4)
print ("原数组是:",a)
for x in np.nditer(a, op_flags=['readwrite']):
    x[...]=2*x
print ('修改后的数组是:',a)
'''
原数组是: [[ 0  5 10 15]
         [20 25 30 35]
         [40 45 50 55]]
修改后的数组是: [[  0  10  20  30]
                 [ 40  50  60  70]
                 [ 80  90 100 110]]
'''

9. 数组函数

9.1 数学函数

NumPy设计了很多数学函数,这里列举其中最重要的几个。

  • 绝对值函数:np.abs(ndarray)
arr1 = np.arange(-1, -9, -1).reshape(2, 4)
print(arr1)
'''
[[-1 -2 -3 -4]
 [-5 -6 -7 -8]]
'''
arr2 = np.abs(arr1)
print(arr2)
'''
[[1 2 3 4]
 [5 6 7 8]]
'''
  • 三角函数:np.sin/tan/cos(ndarray)
arr1 = np.arange(3) * np.pi /2
print(arr1)
'''
[0.         1.57079633 3.14159265]
'''
sin_v = np.sin(arr1)
cos_v = np.cos(arr1)
tan_v = np.tan(arr1)
print(sin_v)    # [0.0000000e+00 1.0000000e+00 1.2246468e-16]
print(cos_v)    # [ 1.000000e+00  6.123234e-17 -1.000000e+00]
print(tan_v)    # [ 0.00000000e+00  1.63312394e+16 -1.22464680e-16]
  • 指数函数:np.exp(ndarray)
x = np.arange(1,4)
print('x=', x)      # x= [1 2 3]
print('e^x=', np.exp(x))        # e^x= [ 2.71828183  7.3890561  20.08553692]
print('2^x=', 2**x)     # 2^x= [2 4 8]
print('10^x=', 10**x)       # 10^x= [  10  100 1000]
  • 对数函数:np.log(ndarray)
x = np.array([1, 10, 100, 1000])
print('x=', x)      # x= [   1   10  100 1000]
print('ln(x)=', np.log(x))        # ln(x)= [0.         2.30258509 4.60517019 6.90775528]
print('log2(x)=', np.log(x)/np.log(2))     # log2(x)= [0.         3.32192809 6.64385619 9.96578428]
print('log10(x)=', np.log(x)/np.log(10))       # log10(x)= [0. 1. 2. 3.]

9.2 聚合函数

向量的聚合函数没有axis参数,矩阵有。

  • 最大值函数:np.max()
  • 最小值函数:np.min()
x = np.random.random((2,3))
print(x)      
'''
[[0.81851887 0.71184876 0.89578074]
 [0.81572543 0.77135001 0.29211341]]
'''
print('按维度一求最大值(列)', np.max(x, axis=0))        # 按维度一求最大值(列) [0.81851887 0.77135001 0.89578074]
print('按维度二求最大值(行)', np.max(x, axis=1))     # 按维度二求最大值(行) [0.89578074 0.81572543]
print('整体求最大值', np.max(x))       # 整体求最大值 0.8957807420711369
  • 求和函数:np.sum()
  • 求积函数:np.prod()
x = np.arange(10).reshape(2, 5)
print(x)
'''
[[0 1 2 3 4]
 [5 6 7 8 9]]
'''
print('按维度一求和(列)', np.sum(x, axis=0))        # 按维度一求和(列) [ 5  7  9 11 13]
print('按维度二求和(行)', np.sum(x, axis=1))     # 按维度二求和(行) [10 35]
print('整体求和', np.sum(x))       # 整体求和 45
  • 均值函数:np.mean()
  • 标准差函数:np.std()
x = np.arange(10).reshape(2, 5)
print(x)
'''
[[0 1 2 3 4]
 [5 6 7 8 9]]
'''
print('按维度一求平均(列)', np.mean(x, axis=0))        # 按维度一求平均(列) [2.5 3.5 4.5 5.5 6.5]
print('按维度二求平均(行)', np.mean(x, axis=1))     # 按维度二求平均(行) [2. 7.]
print('整体求平均', np.mean(x))       # 整体求平均 4.5

注意:

  • axis=0时,最终结果与每一行的元素个数一致。
  • axis=1时,最终结果与每一列的元素个数一致。

大型数组经常会出现缺失值,为了防止聚合函数报错,可以使用安全函数:所有聚合函数前面+nan。

如:np.nansum()、np.nanprod()

10. 布尔型数组

除了整数型数组和浮点型数组外,还有一种常见多用的数组叫布尔型数组。

10.1 创建布尔型数组

由于NumPy的主要数据类型是整数型数组和浮点型数组,因此布尔型数组的产生需要以下关系符:>、>=、==、!=、<、<=

arr = np.arange(1, 7).reshape(2, 3)
print(arr)
'''
[[1 2 3]
 [4 5 6]]
'''
# 数组与数字作比较
print(arr > 4)
'''
[[False False False]
 [False  True  True]]
'''
arr1 = np.arange(1, 6)
arr2 = np.flipud(arr1)
print(arr1)     # [1 2 3 4 5]
print(arr2)     # [5 4 3 2 1]
# 同维度数组作比较
print(arr1 > arr2)
'''
[False False False  True  True]
'''

在Python中,逻辑运算符与、或、非是and、or、not,而在NumPy中使用的是&、|、~

arr = np.arange(1, 10)
print(arr)      # [1 2 3 4 5 6 7 8 9]
# 多个条件
print((arr < 4) | (arr > 6))        # [ True  True  True False False False  True  True  True]

10.2 布尔型数组中与True数量有关的函数

  • np.sum():统计布尔型数组里True的个数
# 创建一个形状为10000的标准正态分布数组
data = np.random.randn(10000)
print(data)
'''
[-2.70125719  0.95444865 -1.84783368 ... -2.06167971 -1.49754748
 -1.90110155]
'''
# 统计该分布中绝对值小于1的元素个数
print(np.sum(np.abs(data) < 1))     # 6846(概率近似0.6827,符合统计学的3σ准则)
  • np.any():只要布尔型数组里含有一个及以上的True,即返回True
arr = np.arange(1, 10)
arr2 = np.flipud(arr)
print(arr)      # [1 2 3 4 5 6 7 8 9]
print(arr2)     # [9 8 7 6 5 4 3 2 1]
# 统计这两个数组里是否有共同元素
print(np.any(arr == arr2))      # True
  • np.all():当布尔型数组里全是True时,才返回True。
# 模拟英语六级成绩,创建10000个样本
arr = np.random.normal(500, 70, size=10000)
print(arr)
'''
[433.68180743 475.226045   529.23949592 ... 670.69732863 462.28717108
 574.00076847]
'''
# 判断是否所有考生都及格了(>425)
print(np.all(arr > 425))        # False

10.3 掩码

掩码,即筛选条件。

若一个普通数组和一个布尔型数组的维度相同,可以将布尔型数组作为普通数组的掩码,以达到筛选普通数组元素的目的。

mask = np.array([0, 1, 1, 1, 0, 0, 1, 0, 0, 1], dtype=bool)
print(mask)     # [False  True  True  True False False  True False False  True]
arr = np.arange(0, 100, 10)
print(arr)      # [ 0 10 20 30 40 50 60 70 80 90]
# 切片
print(arr[mask])    # [10 20 30 60 90] (只保留True对应位置的元素)

10.4 定位

语法:np.where()

where函数用于在很长的一个数组中定位满足某个条件的元素的索引位置。

# 模拟英语六级成绩,创建1000个样本
arr = np.random.normal(500, 70, size=1000)
# 找出六级成绩超过 650 的元素所在位置
print(np.where(arr > 650))
'''
(array([ 48,  54, 202, 212, 290, 489, 570, 626, 687, 689, 735]),)
'''
# 找出六级成绩最高分的元素所在位置
print(np.where(arr == np.max(arr)))     # (array([687]),)

由实例可看出,np.where()函数输出的是一个元组,第一个值是位置信息,第二个值是数据类型,若只想获得位置信息,可以使用np.where()[0]

print(np.where(arr == np.max(arr))[0])     # [687]

标签:基本,10,arr,arr1,np,数组,使用,print,NumPy
From: https://www.cnblogs.com/-ula/p/18475241

相关文章

  • 专题二:操作系统基本原理
    1.操作系统概述操作系统:管理系统的硬件、软件、数据资源控制程序运行人机之间的接口应用软件与硬件之间的接口进程管理存储管理文件管理作业管理设备管理2.进程管理2.1.进程状态(三态模型、五态模型)2.2.★★★信号量与PV操作★★★2.2.1.前趋图2.2.2.进程......
  • C++使用共享内存实现进程间通信
    C++使用共享内存实现进程间通信文件映射是一种实现进程间单向或双向通信的机制。它允许两个或多个本地进程间相互通信。为了共享文件或内存,所有的进程必须使用相同的文件映射的名字或是句柄。为了实现共享文件,第一个进程先调用CreateFile方法。接下来调用CreateFileMappin......
  • 使用飞浆ai训练yolov5
    使用飞浆ai训练yolov5飞浆ai创建项目安装环境数据集训练在yolov5目录下创建一个data.yaml,可改名因为包安装不在python的路径下,需要在py文件中添加如下命令可以导入包的位置然后可以再终端中执行训练命令参数:训练结束预测数据参数最简单的检测命令创新、修改飞浆ai......
  • Sqlmap命令使用方法总结----适合网络安全小白
    在网上找了很多教程,都是零零散散的,找到了两位位前辈的博客,应该是翻译的官方文档,感谢前辈们做出的贡献.希望能够帮助刚学网络安全的小白们本文参考:漏洞人生和sqlmap用户手册中文版目录Sqlmap使用方法总结sqlmap简介常用语句sqlmap详细命令用法选项目标请求优化注入......
  • IoT平台软件:Google Cloud IoT二次开发_JavaSDK使用指南
    JavaSDK使用指南1.环境准备在开始使用GoogleCloudIoT的JavaSDK之前,需要确保您的开发环境已经配置好相关的依赖和工具。以下是环境准备的步骤:1.1安装Java确保您的系统中安装了最新版本的Java开发工具包(JDK)。您可以通过以下命令检查Java版本:java-vers......
  • IoT平台软件:Google Cloud IoT二次开发_Node.jsSDK使用指南
    Node.jsSDK使用指南在本节中,我们将详细介绍如何使用GoogleCloudIoTNode.jsSDK进行二次开发。GoogleCloudIoT提供了丰富的API和SDK,使得开发者可以轻松地与IoT设备进行交互,实现设备管理、数据传输、消息处理等功能。Node.jsSDK是其中一种常用的开发工具,特......
  • IoT平台软件:Google Cloud IoT二次开发_PythonSDK使用指南
    PythonSDK使用指南1.安装GoogleCloudIoTPythonSDK在开始使用GoogleCloudIoTPythonSDK之前,需要先安装相关的依赖库。GoogleCloudIoTCore提供了官方的Python客户端库,这将帮助我们更方便地与GoogleCloudIoTCore进行交互。以下是安装步骤:1.1安装......
  • 使用常用组件构建页面
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(MaoistLearning)➤博客园地址:为敢技术(https://www.cnblogs.com/strengthen/ )➤GitHub地址:https://github.com/strengthen➤原文地址:https://www.cnblogs.com/strengthen/......
  • uni-app小程序(快手、抖音)getCurrentPages使用坑位记录2
    前情uni-app是我比较喜欢的跨平台框架,它能开发小程序/H5/APP(安卓/iOS),重要的是对前端开发友好,自带的IDE让开发体验也挺棒的,现公司项目就是主推uni-app,我主要负责抖音和快手端小程序。坑位公司历史原因项目有APP端小程序端,但并不使用uni-app的一端发布所有平台,各端都有它的开发......
  • 如何高效彻底卸载Windows下的Office套件:使用o15-ctrremove软件
    在处理Windows系统中的Office套件时,我们可能会遇到一些棘手的问题,尤其是当卸载或重装过程中出现错误,导致无法继续进行下一步操作时。幸运的是,有一个名为o15-ctrremove的软件可以帮助我们解决这些问题。卸载Office套件的步骤首先,你需要进入Windows的控制面板,找到“程序和功......