建议先阅读我之前的Python数据处理以及Python专栏中的博客,掌握一定的Python前置知识后再阅读本文,链接如下:
带你从入门到精通——Python数据处理(一. 环境介绍与NumPy入门)-CSDN博客
带你从入门到精通——Python数据处理(二. NumPy中数组的基本操作)-CSDN博客
目录
三. NumPy中数组的运算
3.1 逻辑运算
3.1.1 基本逻辑运算
对于数组来说,可以直接使用<、>、>=、<=等逻辑运算符进行逻辑运算,进行逻辑运算时会对数组中的每个元素进行逻辑判断,满足逻辑判断条件的元素位置将会标记为True,反之则标记为False,并将结果作为一个新数组返回,具体示例如下:
# 生成10名同学,5门功课的数据,行表示每位同学,列表示每位同学的功课成绩
score = np.random.randint(40, 100, (10, 5))
# 取出最后4名同学的成绩,用于逻辑判断
test_score = score[6:, 0:5]
print(test_score)
# 进行逻辑运算, 如果成绩大于60就标记为True,否则为False
print((test_score > 60))
# # 布尔赋值:将所有满足条件的位置(即布尔值为True的位置)设置为指定的值
test_score[test_score > 60] = 1
print(test_score)
结果如下:
3.1.2 np.all函数和np.any函数
np.all()函数以及np.any()函数常配合基本逻辑运算一起使用。
np.all()函数可以判断数组中的所有元素是否都满足条件,如果所有元素都满足条件,则返回True,否则返回False,注意:与Python的内置all函数一样,如果对一个空数组或者空列表、空元组使用该方法,则会返回True。
np.any()函数可以判断检查数组中是否至少有一个元素满足条件,如果有一个元素满足条件,返回 True,否则返回False,注意:与Python的内置any函数一样,如果对一个空数组或者空列表、空元组使用该方法,则会返回Fasle。
使用3.1.1节生成的test_score数组,具体示例如下:
# 判断前两名同学的成绩是否全及格
np.all(test_score[0:2, :] > 60)
# 输出False
# 判断前两名同学的成绩是否有大于80分的
np.any(test_score[0:2, :] > 80)
# 输出False
3.1.3 np.where函数
np.where()函数类似Python中的三元运算符,其基本格式如下:
np.where(条件, 满足条件时输出的值, 不满足条件时输出的值)
np.where()函数通常结合逻辑与函数:np.logical_and()以及逻辑或函数:np.logical_or()一起使用,来完成较为复杂的复合逻辑。
使用3.1.1节生成的test_score数组,具体示例如下:
# test_score数组中大于60且小于90的换为1,否则为0
np.where(np.logical_and(test_score > 60, test_score < 90), 1, 0)
# test_score数组中大于90或小于60的换为1,否则为0
np.where(np.logical_or(test_score > 90, test_score < 60), 1, 0)
注意:当np.where()函数只传入第一个参数即条件时,它会返回满足该条件的元素的索引元组,对于一维数组,返回一个包含满足条件的元素索引的一维数组构成的元组;对于多维数组,返回一个包含每个维度上满足条件的元素索引的一维数组构成的元组,示例如下:
import numpy as np
if __name__ == '__main__':
arr1 = np.array([1, 2, 3, 4, 5])
arr2 = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
print(np.where(arr1 > 3))
# (array([3, 4], dtype=int64),)
print(np.where(arr2 > 3))
# (array([0, 0, 1, 1, 1, 1, 1], dtype=int64), array([3, 4, 0, 1, 2, 3, 4], dtype=int64))
print(np.where(arr2 > 3, 66, -66))
# [[-66 -66 -66 66 66]
# [ 66 66 66 66 66]]
3.2 统计运算
常用的统计运算函数如下:
np.max(a, axis),返回指定轴(维度)上数组的最大值。
np.min(a, axis),返回指定轴(维度)上数组的最小值。
np.median(a, axis),返回指定轴(维度)上数组的中位数,中位数是指在一个有序序列中位于中间位置的那个数,如果序列长度是偶数,则中位数是中间两个数的平均值。
np.mean(a, axis),计算并返回指定轴(维度)上数组的平均数。
np.std(a, axis),计算并返回指定轴(维度)上数组的标准差,标准差是衡量数据点离平均值的平均偏差程度。值越小,数据越集中;值越大,数据越分散,是方差的算术平方根。
np.var(a, axis),计算并返回指定轴(维度)上数组的方差,方差是衡量数据点离平均值的平方偏差程度。方差的值总是非负的,方差越大,数据越分散,是标准差的平方。
np.argmax(a, axis),返回指定轴(维度)上数组的最大值所对应的下标。
np.argmin(a, axis),返回指定轴(维度)上数组的最小值所对应的下标。
注意:上述函数中,a表示任意非空数组、列表或元组,axis参数用于指定轴,axis=0表示沿第0轴即行计算,可以理解为其他轴的长度不变,将第0轴的长度压缩为1;axis=0表示沿第1轴即列计算,可以理解为其他轴的长度不变,将第1轴的长度压缩为1。
注意:上述函数中,如果不指定axis参数,则默认求所有元素的对应统计值,且argmax函数和argmin函数返回的是数组展平后的下标。
3.3 数组与数的运算
数组与数的算术运算都是逐元素运算,即数组中的每个元素都与该数进行算术运算,具体示例如下:
arr = np.array([[1, 2, 3, 2, 1, 4], [5, 6, 1, 2, 3, 1]])
print(arr + 1)
'''
输出结果如下:
[[2 3 4 3 2 5]
[6 7 2 3 4 2]]
'''
print(arr * 2)
'''
输出结果如下:
[[ 2 4 6 4 2 8]
[10 12 2 4 6 2]]
'''
注意:数组与数的算术运算会得到一个新数组。
3.4 数组与数组的运算
3.4.1 形状相等的数组间的运算
当数组与数组进行算术运算时,如果两个数组的形状相等,可以直接进行逐元素运算,即两个数组对应位置的元素之间进行算术运算,示例如下:
arr1 = np.array([[1, 2, 3], [2, 3, 1]])
arr2 = np.array([[1, 100, 4], [5, 6, 1]])
print(arr1 + arr2)
'''
输出如下:
[[ 2 102 7]
[ 7 9 2]]
'''
注意:数组与数的算术运算也会得到一个新数组。
3.4.2 形状不相等的数组间的运算
当形状不相等的两个数组进行算术运算的时候,就会出现广播机制,该机制会对数组进行扩展,使两个数组的shape属性即形状一样,之后数组之间就可以进行逐元素运算了,示例如下:
arr1 = np.array([[0],[1],[2],[3]]) # 4 x 1
arr1.shape
# (4, 1)
arr2 = np.array([1,2,3]) # 1 x 3
arr2.shape
# (3,)
print(arr1+arr2)
'''
输出如下:
[[1, 2, 3],
[2, 3, 4],
[3, 4, 5],
[4, 5, 6]]
'''
上述运算的广播机制图解如下:
但是广播机制也不是万能的,数组间要进行广播需要满足以下的规则:
规则1:如果数组的维度数不同,那么将维度数较少的数组在前面补充1,使其维度数与维度数较多的数组一致。
规则 2:从最后一个维度开始比较,如果两个数组在该维度上的长度相同,或其中一个数组在该维度的长度为1,那么它们在该维度上是兼容的,可以进行运算。
规则 3:如果在任何一个维度上,两个数组的长度既不同又都不为 1,则它们无法进行广播运算。
3.4.3 矩阵乘法
矩阵乘法在线性代数中通常是指两个二维矩阵的相乘运算(不是逐元素相乘,而是相应行元素与相应列元素的乘积之和),在NumPy中可以使用numpy.matmul函数得到矩阵乘积,具体示例如下:
import numpy as np
a = np.array([[1, 0], [0, 1]])
b = np.array([[4, 1], [2, 2]])
print(np.matmul(a, b))
'''
输出结果如下:
[[4 1]
[2 2]]
'''
注意:一维矩阵会被视为一个第一维度的长度为一的二维矩阵。