• 参考:《利用python进行数据分析》第4章
  • 注意,由于本文是jupyter文档转换来的,代码不一定可以直接运行,有些注释是jupyter给出的交互结果,而非运行结果!!

1. 引言

1.1 关于NumPy

  • Python中的数组计算防暑要追溯到1995年,虽然有许多编程社区开始利用python进行数组编程,但相关类库的生态一直是碎片化的,python自己的内置array模块也不是很流行。2005年,NumPy 基于当时的 Numeric 和 Numarray 项目诞生,从此将社区整合到一个框架下。
  • NumPy是python数值计算中最重要的基础库,大多数数值计算库都提供了基于NumPy的科学函数功能,NumPy某种程度上成为了各个库之间数据交换的通用语

1.2 NumPy的特点

  1. 提供了高效多维数组 ndarray,以及基于它的算数操作和广播功能,灵活简便
  2. 允许用户进行快速的矩阵运算,而无需编写循环程序
  3. 允许用户对硬盘中的数据进行读写,并对内存映射文件进行操作
  4. 提供了线性代数计算、随机数生成、傅里叶变换等功能
  5. 提供了一套非常易用的C语言API,允许用户使用Python对存量C/C++/Fortran代码库进行封装,并为其提供动态易用的接口

1.3 NumPy的主要用途

  1. 在数据处理、清洗、构造子集、过滤、变换及其他计算中进行快速向量化运算
  2. 常见的数组算法,比如sortuniqueset操作等
  3. 数据处理时高效地统计、概述数据
  4. 进行数据排列及相关的数据操作,比如对异构数据进行 mergejoin
  5. 使用数组方式来表明条件逻辑,代替 if-elif-else 条件分支的循环
  6. 一组数据进行操作(如聚合、变换、函数式操作等)

1.4 说明

  1. 虽然NumPy提供了一些基础的数值处理方法,但人们通常使用pandas库作为数据统计和分析的基石,NumPy通常被用作一个数据容器,就好像python中的列表或元组一样。
  2. NumPy的流行主要是因为以下几个原因
    1. NumPy的设计对于含有大量数组的数据非常有效
    2. NumPy内部的数据被存储在连续的内存块上,这与python中的其他内建数据结构不同
    3. NumPy库使用C语言编写,在操作数据内存时,不需要任何数据检查或其他管理操作
    4. Numpy可以针对全量数组进行复杂计算而避免编写Python循环语句

2. ndarray

  • ndarray 是NumPy提供的n维数组对象,是快速、灵活的大型数据容器,允许用户使用类似标量的操作语法在整块数据上进行数学计算
  • ndarray是通用的多维同类数据容器,它包含的所有元素都是相同类型的,每个ndarray对象都有以下两个属性
    1. .shape:描述数组每一维度的数量
    2. dtype:描述数组的数据类型

2.1 生成ndarray

2.1.1 array方法

  • .array方法接受任意的序列型对象(列表、元组、其他ndarray…),生成一个新的包含传递数据的ndarray对象
  • .array方法有以下特点
    1. 对于等长嵌套序列,将自动转换为多维数组,否则报警告
    2. 除非显示地指定,否则自动推断生成数组的数据类型
  • 示例
    1. 自动推断类型
      import numpy as np
      arr = np.array([1,2,3])
      print(arr)			# [1,2,3]					
      print(arr.dtype) 	# int32
      
    2. 手动设定类型导致类型转换
      import numpy as np
      arr = np.array([1,2,3],dtype = np.float64)  # 手动设定类型导致类型转换
      print(arr)			# [1. 2. 3.]
      print(arr.dtype)	# float64
      
      arr = np.array([1.1,2.2,3.3],dtype = np.int) # 手动设定类型导致类型转换
      print(arr)			# [1 2 3]
      print(arr.dtype)	# int32
      
    3. 转多维数组
      arr = np.array([[1,2,3],[4,5,6]])
      print(arr.shape)	# (2, 3)
      print(arr.ndim)		# 2 这个是维度数量,就是.shape中的元素数量
      print(arr)			
      '''
      [[1 2 3]
       [4 5 6]]
      '''
      

2.1.2 生成方法概览

  • 数组生成方法
    方法名描述
    array将输入数据(列表、元组、数组及其他序列)转换为ndarray如不显式指明数据类型,将自动推断;默认复制所有输入数据
    asarray将输入转换为ndarray,但若输入已经是ndarray则不再复制
    arangepython内置range函数的ndarray版本,返回一个ndarray
    ones根据给定形状和数据类型生成全1数组
    ones_like根据给定的数组生成一个形状一样的全1数组
    zeros根据给定形状和数据类型生成全0数组
    zeros_like根据给定的数组生成一个形状一样的全0数组
    empty根据给定形状生成一个没有初始化数值的空数组(通常是0,但也可能是一些未初始化的垃圾数值
    empty_like根据给定的数组生成一个形状一样但没有初始化数值的空数组
    full根据给定形状和数据类型生成指定数值的数组
    full_like根据给定的数组生成一个形状一样但内容是指定数值的数组
    eye,identity生成一个 NxN 特征矩阵(对角线位置都是1,其余位置为0)
  • 除了.array方法可能自动推断类型外,其他方法生成的数组,除非显示指定,否则默认为float64类型
  • 示例
    In: 	np.zeros(10)
    Out:	array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
    
    In:		np.zeros((3,6))
    Out:	array([[0., 0., 0., 0., 0., 0.],
    		       [0., 0., 0., 0., 0., 0.],
    		       [0., 0., 0., 0., 0., 0.]])
    
    In:		np.ones_like(np.zeros((3,6)))
    Out:	array([[1., 1., 1., 1., 1., 1.],
    		       [1., 1., 1., 1., 1., 1.],
    		       [1., 1., 1., 1., 1., 1.]])
    		       
    In:		np.empty((1,2))
    Out:	array([[-2.95125736e-193,  8.97478633e-100]])
    
    In:		np.full((2,2,2),5)
    Out:	array([[[5, 5],
    		        [5, 5]],
    		
    		       [[5, 5],
    		        [5, 5]]])
    		        
    In:		np.arange(10)
    Out:	array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    

2.2 ndarray的数据类型

2.2.1 数据类型一览

  • NumPy的数据类型和C语言基本是对应的,这方便了其与C/C++/Fortran等语言进行数据互通
    在这里插入图片描述

2.2.2 说明

  1. 数据类型(即dtype)是一个特殊的对象,包含了ndarray需要为某种类型数据所申明的内存块信息。这是一种“元数据”,即表示数据的数据
  2. dtype是ndarray可以和其他系统数据灵活交互的原因
  3. 可以使用astype方法显式地转换ndarray的数据类型
    1. 浮点类型转为整型会截断小数点后部分
    2. 类型转换失败时抛出ValueError(比如string_float64时)
    3. astype方法总是生成一个新数组,即使传入的dtype与之前一样
  4. 示例
    In:	# 浮点型转整型
    	float_arr = np.array([1.1,2.2,3.3])
    	print(float_arr.dtype)					
    	int_arr = float_arr.astype(np.int)
    	print(int_arr.dtype)		
    	print(int_arr)	# 小数部分发生截断
    Out:float64
    	int32
    	[1,2,3]
    
    In: # astype方法返回新数组,内存地址改变
    	print(id(float_arr))
    	print(id(int_arr))
    Out:1736769459424
    	1736769459184
    
    In:	# 整型转浮点型
        int_arr = np.arange(10)        # int
    	calibers = np.array([1.1,2.2]) # float64
    	int_arr.astype(calibers.dtype) # 显式转换类型
    Out:array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
    

2.3 NumPy 数组算数

  • 数组之所以重要是因为它允许你进行批量操作而无需任何for循环,NumPy称这种特性为 向量化
  • 任意两个等尺寸数组之间的算数操作都应用了逐元素操作的方式
  • 示例
    In: arr = np.array([[1,2,3],[4,5,6]],dtype = np.float64)
    	arr
    Out:array([[1., 2., 3.],
      			[4., 5., 6.]])
    
    In:	arr * arr
    Out:array([[ 1.,  4.,  9.],
    	     	[16., 25., 36.]])
    
    In:	arr - arr
    Out:array([[0., 0., 0.],
           		[0., 0., 0.]])
    
    In:	1 / arr
    Out:array([[1.        , 0.5       , 0.33333333],
    	       [0.25      , 0.2       , 0.16666667]])
    
    In:	arr**0.5
    Out:array([[1.        , 1.41421356, 1.73205081],
           		[2.        , 2.23606798, 2.44948974]])
    
    In:	arr2 = np.array([[4,5,6],[1,2,3]],dtype = np.float64)
    	arr > arr2
    Out:array([[False, False, False],
           		[ True,  True,  True]])
    

2.4 NumPy 索引与切片

  • NumPy中主要有三种索引方式:基础索引、布尔索引、神奇索引(花式索引)
  • 对切片赋值等价于对切片中所有元素赋值

2.4.1 基础索引

  • 数组的基础索引是原数组的 “视图”切片中的数据并不是原数据的副本,任何对切片的操作都会作用于原数组。这是因为NumPy被设计成适合处理超大数组,如果都是复制数据的话容易引起内存问题
  • 如果明确需要数据的拷贝而不是视图,就必须使用.copy()方法显式地复制
2.4.1.1 一维数据
  • 一维数组的基础索引方法和python列表很类似

在这里插入图片描述

  • 示例
    # 一维数组的索引/切片和python列表很类似
    arr = np.arange(10)
    print(arr)		# [0 1 2 3 4 5 6 7 8 9]
    print(arr[5])	# 5
    print(arr[5:8])	# [5 6 7]
    print(arr[5:])	# [5 6 7 8 9]
    print(arr[:5])	# [0 1 2 3 4]
    print(arr[:])	# [0 1 2 3 4 5 6 7 8 9]
    
    # 任何对切片的操作都会作用于原数组
    arr_slice = arr[5:8]
    arr_slice[1] = 12
    print(arr)			# [ 0  1  2  3  4  5 12  7  8  9]
    
    arr_slice[:] = 13
    print(arr)			# [ 0  1  2  3  4 13 13 13  8  9]
    
    # 使用.copy()方法获得副本
    print(id(arr))			# 1288501881232
    print(id(arr.copy()))	# 1288501882672
    
    # 对切片赋值等价于对切片中所有元素赋值
    arr[:] = 0
    print(arr) # [0 0 0 0 0 0 0 0 0 0]
    
    # 注意区分切片和ndarray数组
    arr = 0
    print(arr) # 0
    
2.4.1.2 多维数组
  • n维数组中每个索引对应一个(n-1)维数组

  • 要获取某个元素,可以使用递归索引,也可使用索引列表
    在这里插入图片描述

  • 示例

    In:	# 二维数组中每个索引对应一个一维数组
    	arr2d = np.array([[1,2,3],
    	                  [4,5,6],
    	                  [7,8,9]])
    	print(arr2d[1])
    Out:array([4, 5, 6])
    
    In:# 三维数组中每个索引对应一个二维数组
    	arr2d = np.array([[[1,2,3],
    	                   [4,5,6]],
    	                  [[7,8,9],
    	                   [10,11,12]]])
    	arr2d[1]
    Out:array([[ 7,  8,  9],
           		[10, 11, 12]])
    
    In:	# 使用递归索引或索引列表获取某个元素
    	print(arr2d[1][1])
    	print(arr2d[1,1])
    Out:[10 11 12]
    	[10 11 12]
    
    # 进行多组切片
    In:	arr = np.array([[1,2,3],[4,5,6],[7,8,9]])
    	print(arr,'\n')
    Out:[[1 2 3]
    	 [4 5 6]
    	 [7 8 9]] 
    
    In:print(arr[:2],'\n')
    Out:[[1 2 3]
    	[4 5 6]] 
    
    In: print(arr[:2,1:],'\n')
    Out:[[2 3]
    	 [5 6]]
    
    In:	print(arr[1,:2],'\n')
    Out:[4,5]
    
    In: print(arr[:,:1],'\n')
    Out:[[1]
    	 [4]
    	 [7]] 
    	 
    In: # 对切片赋值等价于对切片中所有元素赋值
    	arr[:,:1] = 0
    	print(arr,'\n')
    Out:[[0 2 3]
    	 [0 5 6]
    	 [0 8 9]] 
    
2.4.1.3 批量索引
  • 有时我们想从数组中选出某些元素并组成特定的形状,可以用以下方法操作。

  • 本质上属于下面 2.4.3 节的神奇索引

    pairs = np.array([0,3,2])
    dist = np.array([1,2,3,4,5])
    print(dist[pairs])
    '''
    [1 4 3]
    '''
    
    pairs = np.array([[[0,0],[0,1],[0,2]],
                      [[1,0],[1,1],[1,2]]])
    dist=np.array([[0, 0.1, 0.2, 0.3, 0.4],
                   [0, 0.4, 0.3, 0.2, 0.1],
                   [0, 0.4, 0.3, 0.2, 0.1]])
    values = dist[pairs[:,:,0], pairs[:,:,1]]
    print(values)
    
    '''
    [[0.  0.1 0.2]
     [0.  0.4 0.3]]
    '''
    

2.4.2 布尔索引

  • 布尔索引是使用一个布尔ndarray作为另一个ndarray的索引值,常用于选出符合条件的元素,要求作为索引的布尔值数组长度必须和数组轴索引长度一致

  • 通常使用条件语句生成布尔索引

    1. 使用 !=~ 运算符实现反选
    2. 对多个布尔值条件进行联合时,不能使用python语法andor,要使用按位与&和按位或|
  • 布尔索引返回的切片是数据拷贝,操作不会作用于原ndarray数。需要注意的是,虽然修改布尔索引返回的数据拷贝不会影响原始数据,但是如果不用一个变量指向切片,或修改切片的切片,而是直接修改切片整体,就会影响原始数据,这一点我还不清楚为什么,求告知!

  • 示例

    names = np.array(['Bob','Tom','Alice'])
    score = np.array([[100,90,90],
                      [85,85,85],
                      [90,80,70]])
    
    print('布尔索引是使用一个布尔ndarray作为另一个ndarray的索引值')
    print(names == 'Bob','\n')
    print(score[names == 'Bob'],'\n')
    print(score[[True,True,False]],'\n')
    
    #print('作为索引的布尔值数组长度必须和数组轴索引长度一致')
    #print(score[[True,True]])
    
    print('布尔索引得到的切片可以继续进行切片')
    print(score[names == 'Bob',:2],'\n')
    
    print('反选')
    print(score[names != 'Bob'])
    print(score[~(names == 'Bob')],'\n')
    
    print('多条件联合选择')
    mask = (names == 'Bob') | (names == 'Alice')
    print(score[mask],'\n')	
    '''
    布尔索引是使用一个布尔ndarray作为另一个ndarray的索引值
    [ True False False] 
    
    [[100  90  90]] 
    
    [[100  90  90]
     [ 85  85  85]] 
    
    布尔索引得到的切片可以继续进行切片
    [[100  90]] 
    
    反选
    [[85 85 85]
     [90 80 70]]
    [[85 85 85]
     [90 80 70]] 
    
    多条件联合选择
    [[100  90  90]
     [ 90  80  70]] 
    '''
    
    # 布尔索引返回的是数据拷贝
    arr = np.arange(3)
    print(arr)					# [0 1 2]
    mask = [True,False,True]
    
    # 用一个变量指向切片,修改变量,不影响原始数据
    arr1 = arr[mask]
    arr1 = 10
    print(arr)					# [0 1 2]
    
    # 修改切片的切片,不影响原始数据
    arr[mask][:] = 10			
    print(arr)					# [0 1 2]
    
    # 直接修改切片整体,影响原始数据(不知道为什么???)
    arr[mask] = 10			
    print(arr)					# [10 1 10]
    

2.4.3 神奇索引

  • 神奇索引是NumPy的术语,用于描述使用整数列表或数组进行数据索引,常用于选出符合特定顺序的子集
  • 传递多个索引数组时,会按顺序递归选择(注意使,分隔),类似基础索引,使用负数索引将从尾部开始选择
  • 神奇索引返回的切片是数据拷贝,操作不会作用于原ndarray数组
  • 需要注意的是,和布尔索引一样,虽然修改神奇索引返回的数据拷贝不会影响原始数据,但是如果不用一个变量指向切片,或修改切片的切片,而直接修改切片整体,就会影响原始数据,这一点我还不清楚为什么,求告知!
  • 示例
    arr = np.empty((8,4))
    for i in range(8):
        arr[i] = i 
    print('原数组') 
    print(arr,'\n')
    
    print('使用一个整数列表或数组选出特定顺序子集')
    print(arr[[4,3,0,6]],'\n')
    
    print('使用负数索引从尾部开始选择')
    print(arr[[-1,-5]],'\n')
    
    print('索引返回拷贝数据')
    arr[[-1,-5]][:] = 0
    print(arr)
    
    '''
    原数组
    [[0. 0. 0. 0.]
     [1. 1. 1. 1.]
     [2. 2. 2. 2.]
     [3. 3. 3. 3.]
     [4. 4. 4. 4.]
     [5. 5. 5. 5.]
     [6. 6. 6. 6.]
     [7. 7. 7. 7.]] 
    
    使用一个整数列表或数组选出特定顺序子集
    [[4. 4. 4. 4.]
     [3. 3. 3. 3.]
     [0. 0. 0. 0.]
     [6. 6. 6. 6.]] 
    
    使用负数索引从尾部开始选择
    [[7. 7. 7. 7.]
     [3. 3. 3. 3.]] 
    
    索引返回拷贝数据
    [[0. 0. 0. 0.]
     [1. 1. 1. 1.]
     [2. 2. 2. 2.]
     [3. 3. 3. 3.]
     [4. 4. 4. 4.]
     [5. 5. 5. 5.]
     [6. 6. 6. 6.]
     [7. 7. 7. 7.]] 
    '''
    
    # 传递多个索引数组时,会按顺序递归选择
    arr= np.arange(32).reshape(8,4)
    print('原数组')
    print(arr,'\n')
    print('中间数组')
    print(arr[[1,7,5,2]],'\n')           
    print('递归选择')
    print(arr[[1,7,5,2],[0,0,0,0]],'\n') # 这样选出了中间数组每个元素中第0号
    
    '''
    原数组
    [[ 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]] 
    
    中间数组
    [[ 4  5  6  7]
     [28 29 30 31]
     [20 21 22 23]
     [ 8  9 10 11]] 
    
    递归选择
    [ 4 28 20  8] 
    '''
    
    # 通常使用以下方法选出行列子集形成的矩形区域
    print('先选出目标行')
    print(arr[[1,7,5,2]],'\n')
    
    print('再调整列顺序')
    print(arr[[1,7,5,2]][:,[0,3,1,2]],'\n') 
    
    '''
    先选出目标行
    [[ 4  5  6  7]
     [28 29 30 31]
     [20 21 22 23]
     [ 8  9 10 11]] 
    
    再调整列顺序
    [[ 4  7  5  6]
     [28 31 29 30]
     [20 23 21 22]
     [ 8 11  9 10]] 
    '''
    

2.4.4 数组转置和换轴

  • 转置是一种特殊的数据重组形式,可以返回底层数据的视图而不需要复制任何内容

  • 数组.T属性是一个原数组转置后的视图

  • 数组.transpose(*axes)方法可以按要求对原数组换轴并返回视图

    1. 对于1维数组,无作用
    2. 对于2维数组,合法参数只有.transpose((1,0)),和.transpose((0,1))前者返回转置视图(和.T相同),后者无变化(原先第0轴变为第0轴,原先第1轴变为第1轴)。转置是换轴的一个特例
    3. 对于n维数组,如果指定了轴参数,则其顺序指示如何排列轴;如果未提给出轴参数,则对于a.shape =(i[0],i[1],...,i[n-1])a.transpose().shape =(i[n-1],i[n-2],...,i[0])
  • 数组.swapaxes(axis1, axis2) 方法交换指定的两个轴,返回新视图

  • 示例

    import numpy as np
    arr = np.arange(15).reshape((5,3))
    print('原矩阵')
    print(arr,'\n')
    
    print('转置矩阵')
    print(arr.T,'\n')
    print(arr.swapaxes(0,1),'\n')
    
    print('内积')
    print(np.dot(arr.T,arr))
    
    '''
    原矩阵
    [[ 0  1  2]
     [ 3  4  5]
     [ 6  7  8]
     [ 9 10 11]
     [12 13 14]] 
    
    转置矩阵
    [[ 0  3  6  9 12]
     [ 1  4  7 10 13]
     [ 2  5  8 11 14]] 
    
    [[ 0  3  6  9 12]
     [ 1  4  7 10 13]
     [ 2  5  8 11 14]] 
    
    内积
    [[270 300 330]
     [300 335 370]
     [330 370 410]]
    '''
    
  • 二维情况下的换轴就是转置,很好理解,但对于多维情况,就不是那么直观了。不妨把数组索引看作排列组合,换轴前后相同组合的索引对应的数组值相同,即
    在这里插入图片描述

    arr = np.arange(8).reshape((2,2,2))
    
    print('原数组')
    print(arr,'\n')
    
    print('第0个和第1个轴互换,使用transpose方法')
    print(arr.transpose((1,0,2)),'\n')
    
    print('第0个和第1个轴互换,使用swapaxes方法')
    print(arr.swapaxes(0,1),'\n')
    
    print('测试')
    print(arr[0,1,1],arr.swapaxes(0,1)[1,0,1])
    '''
    原数组
    [[[0 1]
      [2 3]]
    
     [[4 5]
      [6 7]]] 
    
    第0个和第1个轴互换,使用transpose方法
    [[[0 1]
      [4 5]]
    
     [[2 3]
      [6 7]]] 
    
    第0个和第1个轴互换,使用swapaxes方法
    [[[0 1]
      [4 5]]
    
     [[2 3]
      [6 7]]] 
    
    测试
    3 3
    '''
    

3. 通用函数:快速的逐元素数组函数

  • 通用函数,也称为ufunc,是一种在ndarray数组中进行逐元素操作的函数。某些简单函数接受一个或多个标量数值,产生一个或多个标量结果。通用函数就是对这些简单函数的向量化封装
  • 通用函数分为两类
    1. 一元通用函数:进行简单的逐元素转换
    2. 二元通用函数:接受两个数组并返回一个数组作为结果

3.1 一元通用函数

  • 总结表

    函数名描述
    abs、fabs逐元素计算整数、浮点数或复数的绝对值
    sqrt计算每个元素的平方根(与arr**0.5相等)
    square计算每个元素的平方(与arr**2相等)
    exp计算每个元素的自然指数值 e x e^x ex
    log、log10、log2、log1p分别对应:自然底数、对数10为底、对数2为底、log(1+x)
    sign计算每个元素的符号,整数1;负数-1;0
    ceil每个元素向上取整
    floor每个元素向下取整
    rint元素保留到整数位,并保存dtype
    modf分别将数组的小数和整数部分以数组形式返回
    isnan返回数组中的元素是否是NaN,形式为布尔数组
    isfinite、isinf分别返回数组中元素是否有限(非inf,非NaN)、是否是无限的,形式为布尔数组
    cos、cosh、sin、sinh、tan、tanh常规的双曲三角函数
    arccos、arccosh、arcsin、arcsinh、arctan、arctanh反三角函数
    logical_not对数组的元素按位取反(与~arr效果一致)
  • 部分测试

    import numpy as np
    arr = np.arange(10)
    
    print(arr,'\n')
    print(np.sqrt(arr),'\n')
    print(np.exp(arr),'\n')
    print(np.sign(arr),'\n')
    print(np.cos(arr),'\n')
    print(np.logical_not(arr),'\n')
    print(np.modf(arr),'\n')
    
    '''
    [0 1 2 3 4 5 6 7 8 9] 
    
    [0.         1.         1.41421356 1.73205081 2.         2.23606798
     2.44948974 2.64575131 2.82842712 3.        ] 
    
    [1.00000000e+00 2.71828183e+00 7.38905610e+00 2.00855369e+01
     5.45981500e+01 1.48413159e+02 4.03428793e+02 1.09663316e+03
     2.98095799e+03 8.10308393e+03] 
    
    [0 1 1 1 1 1 1 1 1 1] 
    
    [ 1.          0.54030231 -0.41614684 -0.9899925  -0.65364362  0.28366219
      0.96017029  0.75390225 -0.14550003 -0.91113026] 
    
    [ True False False False False False False False False False] 
    
    (array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]), array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.]))
    '''
    

3.2 二元通用函数

  • 总结表
    函数名描述
    add将数组相应元素相加
    subtract将数组相应元素相减
    multiply将数组对应元素相乘
    divide、floor_divide除或整除(舍弃余数)
    power将第二个数组元素作为第一个数组对应元素的幂次方
    maximum、fmax逐个元素比较,选取其中最大值,fmax忽略NaN
    minimum、fmin逐个元素比较,选取其中最小值,fmin忽略NaN
    mod按元素的求模计算(即求除法的余数)
    copysign第一个数组的符号值改为第二个数组的符号值
    greater、greater_equal、less、less_equal、equal、not_equal逐个元素比较,返回布尔数组
    logical_and、logical_or、logical_xor逐元素进行逻辑运算
  • 部分测试
    import numpy as np
    arr = np.arange(10)
    
    x = np.arange(10)
    y = np.arange(9,-1,-1)
    print(x)
    print(y,'\n')
    
    print('add:',np.add(x,y),'\n')
    print('substract:',np.subtract(x,y),'\n')
    print('multiply:',np.multiply(x,y),'\n')
    print('divide:',np.divide(x,y),'\n')
    print('floor_divide:',np.floor_divide(x,y),'\n')
    print('maximum:',np.maximum(x,y),'\n')
    print('minimum:',np.minimum(x,y),'\n')
    print('mod:',np.mod(x,y),'\n')
    print('greater:',np.greater(x,y),'\n')
    print('logical_and:',np.logical_and(x,y),'\n')
    
    '''
    [0 1 2 3 4 5 6 7 8 9]
    [9 8 7 6 5 4 3 2 1 0] 
    
    add: [9 9 9 9 9 9 9 9 9 9] 
    
    substract: [-9 -7 -5 -3 -1  1  3  5  7  9] 
    
    multiply: [ 0  8 14 18 20 20 18 14  8  0] 
    
    divide: [0.         0.125      0.28571429 0.5        0.8        1.25
     2.         3.5        8.                inf] 
    
    floor_divide: [0 0 0 0 0 1 2 3 8 0] 
    
    maximum: [9 8 7 6 5 5 6 7 8 9] 
    
    minimum: [0 1 2 3 4 4 3 2 1 0] 
    
    mod: [0 1 2 3 4 1 0 1 0 0] 
    
    greater: [False False False False False  True  True  True  True  True] 
    
    logical_and: [False  True  True  True  True  True  True  True  True False] 
    '''
    
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐