python-数据分析-Numpy-3、数组的运算

news/2024/10/8 22:55:07

数组的运算

使用 NumPy 最为方便的是当需要对数组元素进行运算时,不用编写循环代码遍历每个元素,所有的运算都会自动的矢量化。简单的说就是,NumPy 中的数学运算和数学函数会自动作用于数组中的每个成员。

# -*- coding: utf-8 -*-
#数组的运算
#使用 NumPy 最为方便的是当需要对数组元素进行运算时,不用编写循环代码遍历每个元素,所有的运算都会自动的矢量化。简单的说就是,NumPy 中的数学运算和数学函数会自动作用于数组中的每个成员。import numpy# 1、数组跟标量的运算
#NumPy 的数组可以跟一个数值进行加、减、乘、除、求模、求幂等运算,对应的运算会作用到数组的每一个元素上
array1 = numpy.arange(1, 10)
print(array1)   #[1 2 3 4 5 6 7 8 9]print(array1 + 10)  #[11 12 13 14 15 16 17 18 19]
print(array1 * 10)  #[10 20 30 40 50 60 70 80 90]#除了上述的运算,关系运算也是没有问题的,之前讲布尔索引的时候已经遇到过了
print(array1 > 5)   #[False False False False False  True  True  True  True]
print(array1 % 2 == 0)  #[False  True False  True False  True False  True False]print('-----------------------------------------------------')# 2、数组跟数组的运算
#NumPy 的数组跟数组也可以执行算术运算和关系运算,运算会作用于两个数组对应的元素上,这就要求两个数组的形状(shape属性)要相同
array2 = numpy.array([1, 1, 1, 2, 2, 2, 3, 3, 3])
print(array1 + array2)  #[ 2  3  4  6  7  8 10 11 12]
print(array1 * array2)  #[ 1  2  3  8 10 12 21 24 27]
print(array1 ** array2) #[  1   2   3  16  25  36 343 512 729]print(array1 > array2)  #[False  True  True  True  True  True  True  True  True]
print(array1 % array2 == 0) #[ True  True  True  True False  True False False  True]print('-----------------------------------------------------')# 3、通用一元函数
#NumPy 中通用一元函数的参数是一个数组对象,函数会对数组进行元素级的处理
# 例如:sqrt函数会对数组中的每个元素计算平方根,而log2函数会对数组中的每个元素计算以2为底的对数
print(numpy.sqrt(array1))
print(numpy.log2(array1))
'''
[1.         1.41421356 1.73205081 2.         2.23606798 2.449489742.64575131 2.82842712 3.        ][0.         1.         1.5849625  2.         2.32192809 2.58496252.80735492 3.         3.169925  ]
'''

通用一元函数表:                                                                                                                                                        

函数 说明
abs / fabs 求绝对值的函数
sqrt 求平方根的函数,相当于array ** 0.5
square 求平方的函数,相当于array ** 2
exp 计算$e^x$的函数
log / log10 / log2 对数函数(e为底 / 10为底 / 2为底)
sign 符号函数(1 - 正数;0 - 零;-1 - 负数)
ceil / floor 上取整 / 下取整
isnan 返回布尔数组,NaN对应True,非NaN对应False
isfinite / isinf 判断数值是否为无穷大的函数
cos / cosh / sin 三角函数
sinh / tan / tanh 三角函数
arccos / arccosh / arcsin 反三角函数
arcsinh / arctan / arctanh 反三角函数
rint / round 四舍五入函数

 

# 4、通用二元函数
#NumPy 中通用二元函数的参数是两个数组对象,函数会对两个数组中的对应元素进行运算
# 例如:maximum函数会对两个数组中对应的元素找最大值,而power函数会对两个数组中对应的元素进行求幂操作
array3 = numpy.array([[4, 5, 6], [7, 8, 9]])
array4 = numpy.array([[1, 2, 3], [3, 2, 1]])
print(numpy.maximum(array3, array4))
print(numpy.power(array3, array4))
'''
[[4 5 6][7 8 9]][[  4  25 216][343  64   9]]
'''

通用二元函数:表

函数 说明
add(x, y) / substract(x, y) 加法函数 / 减法函数
multiply(x, y) / divide(x, y) 乘法函数 / 除法函数
floor_divide(x, y) / mod(x, y) 整除函数 / 求模函数
allclose(x, y) 检查数组xy元素是否几乎相等
power(x, y) 数组$x$的元素$x_i$和数组$y$的元素$y_i$,计算$x_i^{y_i}$
maximum(x, y) / fmax(x, y) 两两比较元素获取最大值 / 获取最大值(忽略NaN)
minimum(x, y) / fmin(x, y) 两两比较元素获取最小值 / 获取最小值(忽略NaN)
dot(x, y) 点积运算(数量积,通常记为$\cdot$,用于欧几里得空间(Euclidean space))
inner(x, y) 内积运算(内积的含义要高于点积,点积相当于是内积在欧几里得空间$\mathbb{R}^n$的特例,而内积可以推广到赋范向量空间,只要它满足平行四边形法则即可)
cross(x, y) 叉积运算(向量积,通常记为$\times$,运算结果是一个向量)
outer(x, y) 外积运算(张量积,通常记为$\bigotimes$,运算结果通常是一个矩阵)
intersect1d(x, y) 计算xy的交集,返回这些元素构成的有序数组
union1d(x, y) 计算xy的并集,返回这些元素构成的有序数组
in1d(x, y) 返回由判断x 的元素是否在y中得到的布尔值构成的数组
setdiff1d(x, y) 计算xy的差集,返回这些元素构成的数组
setxor1d(x, y) 计算xy的对称差,返回这些元素构成的数组

 

广播机制

上面数组运算的例子中,两个数组的形状(shape属性)是完全相同的,我们再来研究一下,两个形状不同的数组是否可以直接做二元运算或使用通用二元函数进行运算

#广播机制
#广播机制是 NumPy 中最令人困惑的特性,它允许 NumPy 的数组运算在数组形状不同的情况下也能正常进行。array5 = numpy.array([[0, 0, 0], [1, 1, 1], [2, 2, 2], [3, 3, 3]])
array6 = numpy.array([1, 2, 3])
print(array5 + array6)
'''
[[1 2 3][2 3 4][3 4 5][4 5 6]]
'''array7 = numpy.array([[1], [2], [3], [4]])
print(array5 + array7)
'''
[[1 1 1][3 3 3][5 5 5][7 7 7]]
'''

通过上面的例子,我们发现形状不同的数组仍然有机会进行二元运算,但这不代表任意形状的数组都可以进行二元运算。

简单的说,只有两个数组后缘维度相同或者后缘维度不同但其中一个数组后缘维度为1时,广播机制才会被触发。

通过广播机制,NumPy 将两个原本形状不相同的数组变成形状相同,才能进行二元运算。所谓后缘维度,指的是数组形状(shape属性)从后往前看对应的部分,我们举例说明。

下图中,一个数组的形状是(4, 3),另一个数组的形状是(3, ),从后往前看对应的部分都是3,属于后缘维度相同,可以应用广播机制,第二个数组会沿着缺失元素那个轴的方向去广播自己,最终让两个数组形状达成一致。

下图中,一个数组的形状是(3, 4, 2),另一个数组的形状是(4, 2),从后往前看对应的部分都是(4, 2),属于后缘维度相同,可以应用广播机制,第二个数组会沿着缺失元素那个轴的方向去广播自己,最终让两个数组形状达成一致。

下图中,一个数组的形状是(4, 3),另一个数组的形状是(4, 1),这是后缘维度不相同的情况,但是第二个数组跟第一个数组不同的地方为1,第二个数组可以沿着为1 的那个轴广播自己,最终让两个数组形状达成一致

 

其它常用函数

除了上面讲到的函数外,NumPy 中还提供了很多用于处理数组的函数,ndarray对象的很多方法也可以通过调用函数来实现,下表给出了一些常用的函数。
表:NumPy其他常用函数

函数 说明
unique 去除数组重复元素,返回唯一元素构成的有序数组
copy 返回拷贝数组得到的数组
sort 返回数组元素排序后的拷贝
split / hsplit / vsplit 将数组拆成若干个子数组
stack / hstack / vstack 将多个数组堆叠成新数组
concatenate 沿着指定的轴连接多个数组构成新数组
append / insert 向数组末尾追加元素 / 在数组指定位置插入元素
argwhere 找出数组中非0元素的位置
extract / select / where 按照指定的条件从数组中抽取或处理数组元素
flip 沿指定的轴翻转数组中的元素
fromregex 通过读取文件和正则表达式解析获取数据创建数组对象
repeat / tile 通过对元素的重复来创建新数组
roll 沿指定轴对数组元素进行移位
resize 重新调整数组的大小
place / put 将数组中满足条件的元素/指定的元素替换为指定的值
partition 用选定的元素对数组进行一次划分并返回划分后的数组
#常用函数
#去重(重复元素值保留一项)
print(numpy.unique(array5)) #[0 1 2 3]#堆叠和拼接
array8 = numpy.array([[1, 1, 1], [2, 2, 2], [3, 3, 3]])
array9 = numpy.array([[4, 4, 4], [5, 5, 5], [6, 6, 6]])
print(numpy.hstack((array8, array9)))   #用于水平(按列)堆叠数组,相当于沿着轴 1 进行数组的拼接。
'''
[[1 1 1 4 4 4][2 2 2 5 5 5][3 3 3 6 6 6]]
'''print(numpy.vstack((array8, array9)))   #用于垂直(按行)堆叠数组,相当于沿着轴 0 进行数组的拼接。
'''
[[1 1 1][2 2 2][3 3 3][4 4 4][5 5 5][6 6 6]]
'''
#axis:指定连接的轴。默认值为 0=行,即在第一个轴上进行连接。 1=列
print(numpy.concatenate((array8, array9), axis=1))  #用于沿指定轴连接一系列数组。它可以在任意维度上进行拼接。
'''
[[1 1 1 4 4 4][2 2 2 5 5 5][3 3 3 6 6 6]]
'''
#numpy.concatenate() 是一个通用的拼接函数,可以指定沿哪个轴拼接数组。
#numpy.vstack() 是专门用于垂直堆叠的函数,相当于沿轴 0 拼接。
#numpy.hstack() 是专门用于水平堆叠的函数,相当于沿轴 1 拼接。print('-----------------------------------------------------')#追加和插入元素。
print(numpy.append(array1, [10, 100]))  #追加元素 追加 10 和 100   [  1   2   3   4   5   6   7   8   9  10 100]print(numpy.insert(array1, 1, [98, 99, 100]))   #插入元素 插入 98 99 100 到 1 位置  [  1  98  99 100   2   3   4   5   6   7   8   9]print('-----------------------------------------------------')#抽取和处理元素。
#说明:extract函数的操作相当于我们之前讲的布尔索引。
print(numpy.extract(array1 % 2 !=0, array1))    #抽取元素 抽取出 array1 中所有元素值不为偶数的元素  [1 3 5 7 9]#处理元素 处理 array1 中所有元素值小于等于 3 的元素,将其乘以 10;处理 array1 中所有元素值大于等于 7 的元素,将其平方。
#select函数的第一个参数设置了两个条件,满足第一个条件的元素执行了乘以10的操作,满足第二个条件的元素执行了求平方的操作,两个条件都不能满足的数组元素会被处理为0。
print(numpy.select([array1 <= 3, array1 >= 7], [array1 * 10, array1 ** 2]))     #[10 20 30  0  0  0 49 64 81]#where函数的第一个参数给出了条件,满足条件的元素执行了乘以10的操作,不能满足条件的元素执行了求平方的操作。
print(numpy.where(array1 <= 5, array1 * 10, array1 ** 2))   #[10 20 30 40 50 36 49 64 81]print('-------------------------------------------------------------')
#重复数组元素创建新数组
#repeat函数的第一个参数是数组,第二个参数是重复次数。
print(numpy.repeat(array1, 3))  #[1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7 8 8 8 9 9 9]#tile函数的第一个参数是数组,第二个参数是重复次数。
print(numpy.tile(array1, 2))    #[1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9]#repeat和tile函数的区别在于,repeat对数组中的每个元素进行重复。,tile函数对整个数组进行重复。print('-------------------------------------------------------------')#调整数组的大小
#resize函数的第一个参数是数组,第二个参数是调整后的大小。
#提示:array1原本是一个有9个元素的一维数组,通过resize函数调整成为5行3列共15个元素的二维数组,缺少的元素通过复用原数组中的元素来补充。
print(numpy.resize(array1, (5, 3))) #(5, 3) 表示5行3列
'''
[[1 2 3][4 5 6][7 8 9][1 2 3][4 5 6]]
'''print('-------------------------------------------------------------')#替换数组元素
#replace函数的第一个参数是数组,第二个参数是待替换的元素的索引位置,第三个参数是替换的新元素。
print(array1)
#put函的第二个参数给出了要被替换的元素的索引,但是用来作为替换值的元素只有100和200,所以这两个值会被循环使用
# 因此索引为0、1、-1、3、5的元素被依次替换成了100、200、100、200、100
numpy.put(array1, [0, 1, -1, 3, 5], [100, 200])
print(array1)   #[100 200   3 200   5 100   7   8 100]#place函数的第一个参数是数组,第二个参数是条件,第三个参数是替换的新元素。
numpy.place(array1, array1 > 5, [1, 2, 3])
print(array1)   #[1 2 3 3 5 1 2 3 1]#注意:put函数和place函数都没有返回新的数组对象,而是在原来的数组上直接进行替换。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hjln.cn/news/42493.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

Java4-6次大作业题目集总结性Blog

Java4~6次大作业题目集的总结性Blog前言知识点无疑就是要学会熟练使用LinkedLsit、ArrayList、HashMap等存储数据的数据集合,并且能够合理处理输入的数据然后使用,在类设计中也要考虑好类之间的关系,学会使用继承多态可以很好处理数据 题量不大,在于能否处理好题目,方便写…

oop前三次作业总结oop前三次作业总结

<# oop前三次作业总结oop前三次作业总结 ## 一、前言 本次的大作业是关于家庭电路设计的,总体难度较大,需要对各种类以及多态的运用熟练,在做题过程中也是遇到了诸多问题,查阅了很多资料,对面向对象的概念有了很大的提升。在这三次题目集中,7-1题目通常作为每个题目集…

彻底搞懂网络地址、广播地址、主机地址、网关、子网掩码、网络号、主机号

1 网络地址、广播地址、主机地址名词解释 1.1 网络地址网络地址是指仅包含网络号而不包含主机号的IP地址。它用于唯一标识一个网络。在网络通信中,网络地址用于路由和寻址。例如,一个IP地址为192.168.0.0,IP掩码为255.255.255.0,那么它的网络地址就是192.168.0.0。 它是指一…

PTA第二阶段三次作业总结

前言 第二阶段的三次大作业明显对设计的要求进一步提高了。我三次作业一共得到了196分,答题判断程序-4有两个测试点未通过,其他两次作业均通过所有测试点,但程序仍有许多不足,下面开始逐题分析。 7-1 答题判题程序-4 答题判断程序-4增加的多选题,填空题,本质是考察了字符…

HarmonyOS ArkTS组件 | Flex 以弹性方式布局子组件的容器组件 学习记录

HarmonyOS ArkTS组件 | Flex 以弹性方式布局子组件的容器组件 学习记录 前言:最近需要用到弹性布局,记录一下。(忽略图片水印QAQ) 说明:Flex组件在渲染时存在二次布局过程,因此在对性能有严格要求的场景下建议使用Column、Row代替。 Flex组件主轴默认不设置时撑满父容器,…

2024计算机组成原理复习——第一章

计算机组成原理复习——第一章一、计算机系统概括 本笔记不用于商业用途,内容参考《2025年计算机组成原理——考研复习指导》以及其对应的b站免费视频课(图文信息主要来自于此) (一)计算机系统结构层次 1. 计算机系统的基本组成硬件:有形的物理设备,计算机系统中实际物理…

[转帖]Linux Kernel 6.6 确认成为 LTS 版本

https://www.kernel.org/category/releases.html Greg Kroah-Hartman 已经宣布 Linux Kernel 6.6 版本为长期支持 (LTS) 版本;支持期限到 2026 年 12 月。 Linux Kernel 6.6 于 10 月 29 日正式发布,是一次包含了新功能、硬件支持、安全增强和性能改进的重大更新。具体包括有…