vevoly 2020-05-04
1. numpy(numerical python)是科学计算基础库,提供大量科学计算相关功能,比如数据统计,随机数生成等. 2. 其提供最核心类型为多维数组(ndarray),支持大量的维度数组与矩阵运算,numpy支持向量处理ndarray对象,提高程序运算速度. 3. numpy底层由C实现,执行效率很高. 4. numpy中最最最核心的就是数组对象 => ndarray
使用pip安装numpy
pip install numpy
# code01_arange测试安装环境.py import numpy as np # np.arange()可以类比 range(), 前者生成一个ndarray对象,后者生成range()对象 a = np.arange(10) # 创建一个数组 print(a)
# code02_列表向量运算.py # numpy最经典就是向量处理ndarray # 一个简答的例子就是对一个数组每个元素进行开方计算 import random import math import numpy as np a = [random.random() * 100 for i in range(10)] # 1. 普通列表处理 b = [math.sqrt(x) for x in a] print(b) # 2. ndarray向量处理 c = np.sqrt(np.array(a)) print(c)
np.array创建ndarray对象
# code03_array创建数组.py import numpy as np # 使用array创建一维数组 a = np.array([1, 2, 3, 4]) # 传入列表,元组都行 print([1, 2, 3, 4]) # [1, 2, 3, 4] 列表之间是有逗号分隔的 print(type(a)) # <class ‘numpy.ndarray‘> print(a) # [1 2 3 4] 是没有逗号的 print("数组的维度", a.shape) # 使用array创建二维数组 b = np.array([(1, 2, 3), (4, 5, 6), ]) print(b) print("数组的维度", b.shape) # 使用array创建三维,四维..... # array()中dtype的使用 => 指定数组的类型 # 这里使用的是python内置的数据类型, 其实numpy还有非常多额外的数据类型 c = np.array([3, 4, 5], dtype=float) d = np.array([3, 4, 5], dtype=str) print(c) print(d) # array函数中ndim的使用 => 秩(维度的数量) e = np.array([3, 4, 5], dtype=float, ndmin=3) print(e) print("数组的维度", e.shape)
np.arange创建ndarray对象
# code04_arange创建数组.py import numpy as np # np.arange(start,end,step,dtype) <=> range(start,end,step) # 生成一个0-5的数组 a = np.arange(0, 6, dtype=int) print(a) b = np.arange(10, 20, 2, dtype=float) print(b)
随机数创建ndarray对象
1. np.random.random(size=None) 该方法返回[0.0,1.0)范围的随机数 2. np.random.randint(low, high=None, size=None, dtype=int) (1) 如果只给low传值,那么就是默认 [0,low) 3. numpy.random.randn(d0,d1,…,dn) randn()返回一个或一组样本,具有标准正态分布(期望为0,方差为1) (1) dn表是每个维度 (2) 返回值为指定为维度的ndarray 4. np.random.normal() 指定期望和方差的正态分布
# code05_随机数创建数组_random.py import numpy as np # np.random.random(size) 返回一个[0.0,1.0) # 创建一维随机数组 a = np.random.random(size=5) print(type(a)) print(a) # 创建二维随机数组 b = np.random.random(size=(3, 4)) # 3行4列 print(b) # 创建三维,四维随机数组...
# code06_随机数创建数组_randint.py import numpy as np # 随机整数 # np.random.randint(low, high=None, size=None, dtype=int) [low,high) # 生成0-5的随机整数 一维 a = np.random.randint(0, 5 + 1, size=10) print(a) # 生成5-10的随机整数 二维 b = np.random.randint(5, 10 + 1, size=(4, 3)) print(b) print("dtype的默认值", b.dtype)
# code07_随机数创建数组_randn.py import numpy as np # np.random.randn(d0,d1,d2....) 返回一个或一组样本,具有标准正态分布 # 创建一个一维的标准正态分布数组 a = np.random.randn(5) print(a) # 创建一个二维的标准正态分布数组 b = np.random.randn(3,5) print(b) # 创建一个三维,四维...
# code08_随机数创建数组_normol.py import numpy as np # np.random.normal(loc=0.0, scale=1.0, size=None) a = np.random.normal(size=5) # 默认期望loc=0.0 方差scale=1.0 print(a) # 指定期望和方差 b = np.random.normal(loc=2, scale=3, size=(3, 4)) print(b)
ndarray对象
常用的 (1) ndim (2) shape (3) size (3) itemsize (4) dtype
# code09_ndarray对象的属性.py import numpy as np # 使用np.random() 创建随机数的一维二维数组都很方便 # 创建一维数组 a = np.array(range(1, 5)) print(a) # 创建二维数组 (使用随机数创建) b = np.random.randint(4, 10, size=(2, 3)) print(b) # 创建三维数组 (标准正态分布) c = np.random.randn(2, 3, 4) print(c) # ndim属性 => 数组的维度的数目 print("ndim:",a.ndim,b.ndim,c.ndim) # shape属性 => 数组的shape print("shape:",a.shape,b.shape,c.shape) # dtype属性 print("dtype:",a.dtype,b.dtype,c.dtype) # size属性 => 元素的总个数 print("size:",a.size,b.size,c.size) # itemsize属性 => 数组中每个元素的字节大小 print("itemsize:",a.itemsize,b.itemsize,c.itemsize)
其他方式创建
ndarray数组除了可以使用底层ndarray构造器来创建外,也可以通过一下计中方式来创建.
1. np.zeros(shape, dtype = float, order = ‘C‘) 创建指定大小的数组,数组元素以0来填充 2. np.ones(shape,dtype=None,order=‘C‘) 创建指定形状的数组,数组元素以1来填充 3. np.empty(shape, dtype = float, order = ‘C‘) 创建一个未初始化的数组,里面的元素的值是之前内存的值 4. 参数说明: (1) shape: 数组形状 (2) dtype: 数据类型,可选 (3) order: 有"C"和"F"两个选项,分别代表 行优先和列优先, 在计算机内存中存储元素的顺序 5. np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None) 用于创建一个一维数组,数组是一个等差数列构成 (1) start: 序列的起始值 (2) stop: 序列的终止值,如果endpoint为True,该值包含于数列中 (3) num: 要生成的等步长样本数量,默认为50 (4) endpoint: 该值为True,数列中包含stop值,默认为True (5) retstep: 如果为True,生成的数组中会显示间距 (6) dtype: ndarray的数据类型 6. np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None) 用于创建一个等比数列,一维数组 (1) base: 对数log的底数
# code10_其他方式创建数组.py import numpy as np # 1. np.zeros(shape, dtype=float, order=‘C‘) # shape : int or tuple of ints a = np.zeros(5) print(a) a = np.zeros((5,), dtype=int) # 指定数据类型 print(a) a = np.zeros((3, 4)) # 创建二维数组 print(a) # 2. np.ones(shape, dtype=float, order=‘C‘) b = np.ones(5) print(b) b = np.ones((5,), dtype=int) # 指定数据类型 print(b) b = np.ones((3, 4)) # 创建二维数组 print(b) """ ones Return an array of ones with shape and type of input. empty Return a new uninitialized array. zeros Return a new array setting values to zero. full Return a new array of given shape filled with value. """ # 3. np.empty() # 4. np.full(shape,fill_value, dtype=float, order=‘C‘) c = np.full((3, 4), 3) print(c) # 5. np.linspace() <=> np.arange() 其实功能一致,就是创建等差数数组 # np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0) d = np.linspace(1, 10, 10) print(d) # 6. np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None,axis=0) e = np.logspace(0, 9, 10, base=2) # 公比选择2 print(e)
一维数组的索引与切片
numpy一维数组的索引和切片基本与python的索引与切片一致
1. ndarray对象的内容可以通过索引或切片来访问和修改, 与Python中list的切片操作一样. 2. ndarray数组可以基于0~n的下标进行索引,并设置start,stop以及step参数进行,从原数组切割除一个新数组.
# code11_一维数组的索引和切片.py import numpy as np x = np.arange(10) y = x[2:7:2] z = x[2:] print(y) print(z) # 切片中的"-step" print(x[::-1]) print(x[9:5:-1]) # 负索引的起点是可以反着的 # 测试切片后是不是同一个对象 print("x和x[2:7:2]是不是同一个对象", x is y) # False => 但是确实修改了会一起修改 => 元素存储的是索引而已 # 索引范围 print("索引0处元素", x[0]) print("索引5处元素", x[5]) print("访问最后一个元素", x[-1]) print("访问倒数第三个元素", x[-3])
二维数组的索引与切片
numpy的多维数组索引和切片与python多维数组的索引切片有些不同了
1. 多维数组获得单个元素(二维数组为例子) (1) Python L[x][y] (2) numpy L[x,y] 2. 在第一点的基础上,可以实现行和列的分别切片 (1) 所有列索引1元素 L[:,1] (2) 所有行索引2元素 L[2,:] 3. 花式(数组)索引 (1) 主要就是序列(列表,元组) 作为一个索引 L[(x1,x2,...),(y1,y2,....)] (2) 如果只有一个数组索引的话,那么就是行索引 L[[0,2]] # 选中行索引0和2 两整行 (3) 如果有两个数组索引的话,前者为行索引,后者为列索引,二者一一对应 L[(1,3),(1,2)] # 同时选中(1,1) (3,2)的值 4. 布尔索引 (1) 布尔型索引指的是将一个布尔数组作为数组索引,返回的数据是布尔数组中True对应位置的值. (2) 布尔型索引获取值的时候,使用与C一致的布尔运算值 ==,!=,>,<,....
# code12_二维数组的索引与切片.py import numpy as np a = np.linspace(1, 12, 12 - 1 + 1, dtype=int) print(a) # 重新修改数组的形状 # (1) 通过属性shape修改 => 原数组对象 # (2) 通过np.reshape(a, newshape, order=‘C‘)修改 => 新的数组对象 a.shape = (4, 3) b = np.reshape(a, (4, 3)) print(a) print(b) print("a和b是不是同一个对象:", a is b) print(a[2]) # 获取第三行 print(a[1][2]) # 获取第二行 第三列 # 二维数组的切片 # 语法: [行切片/索引,列切片/索引] print(b[:, :]) # 获取所有行所有列 print(b[:, 1]) # 获取所有行第2列 print(b[:, :2]) # 获取所有行第1,2列 print(b[::2, :]) # 获取奇数行所有列 print(b[2, 1]) # 获取第三行第2列 # 花式索引 => 数组作为索引值 # [(x1,x2,...)[,(y1,y2,...)]] print(a[1, 2], a[2, 0]) # 这是获取两个不同位置的值(普通写法) print(a[(1, 2), (2, 0)]) # 两个不同位置的值(花式索引) # 布尔索引 => 布尔数组作为数组索引,返回的数据是布尔数组中True对应位置的值 student_name = np.array(["Tom", "Lily", "Jack", "Rose"]) # 存储学生姓名的数组 student_score = np.array([[79, 88, 80], [89, 90, 92], [83, 78, 85], [78, 76, 80]]) # 存储学生成绩的数组 # 对student_name和字符串"Jack"通过一个运算符产生一个布尔类型的数组 print(student_name == "Jack") # [False False True False] # 将布尔数组作为索引,返回是True对应的选择 print(student_score[student_name == "Jack", :])
numpy数组的复制
numpy的切片是浅拷贝,修改新数组会跟着影响原数组
np.copy() 进行的深拷贝
# code13_数组的复制.py import numpy as np # 创建一个二维的数组 a = np.arange(1, 13).reshape((3, 4)) print(a) # 对a数组进行切片,获得第1,2行,第1,2列 sub_a = a[0:2, 0:2] # 这里相当于只是一个浅拷贝 print(sub_a) print("a和sub_a是不是一个对象", a is sub_a) # 对sub_a中第一行第一列的值进行修改 sub_a[0][0] = 100 print(sub_a) print(a) # 可以使用numpy中的copy方法实现深拷贝 sub_aa = np.copy(a[-1,-1]) print(sub_aa) sub_aa = -240 print(sub_aa) print(a)
1. 处理数组的一项重要工作就是改变数组的维度,包含提高数组的维度和降低数组的维度,还包括数组的转置. 2. numpy提供大量API可以很轻松地完成这些数组的操作.例如: (1) 通过np.reshape() 将一维数组变成二维,三维或者多维数组 (2) 通过ravel()或者flatten()将多维数组变成一维数组 (3) 通过设置shape属性(元组类型),或者resize()也可以改变数组的维度
# code14_修改数组的维度.py import numpy as np # 创建一维数组 a = np.arange(24) print(a) print("数组a的维度", a.shape) print("-" * 30) # 使用np.reshape(a, newshape, order=‘C‘)将一维数组变成三维数组 # newshape: Union[int, Iterable, tuple[int] b = a.reshape((2, 3, 4)) print(b) print("数组b的维度", b.shape) print("-" * 30) # 将多维数组转为一维数组 # (1) np.reshape(-1) => 直接多维变一维 c = np.reshape(b, -1) # np.reshape(a,-1) a.reshape(-1) 类方法 <=> 实例方法 print(c) print("数组c的维度", c.shape) # (2)使用np.ravel()将三维的b变成一维数组 d = np.ravel(a) print(d) print("数组d的维度", d.shape) # (3) 使用np.flatten() 函数,效果于ravel()一致 e = a.flatten() print(e) print("数组e的维度", e.shape)
# code15_数组的拼接.py import numpy as np a = np.arange(1, 7).reshape((2, 3)) b = np.arange(11, 17).reshape((2, 3)) print(a) print(b) # 使用hstack(tup: Iterable)进行水平拼接 r = np.hstack((a, b)) # 把要拼接的列表存入一个列表中 print(r) # 使用vstack(tup) 进行垂直拼接 r = np.vstack((a, b)) print(r) # 使用concatenate的使用 # axis=0(默认情况) 按第一维拼接 => 相当于vstack r = np.concatenate((a, b)) print(r) # axis=1 => 按照第二维度进行拼接 r = np.concatenate((a,b),axis=1) print(r)
np.split()分隔
1. numpy.split()函数沿特定的轴将数组分割成子数组,格式如下: numppy.split(ary,indices_or_sections,axis) 2. 参数说明 (1) ary: 被分割的数组 (2) indices_or_sections: 如果是一个整数,就用该数平均切分,如果是一个数组,为沿轴切分的位置(传入数组相当于隔板) (3) axis:沿着那个维度进行切向,默认为0,横向切向. 为1时,纵向切分
# code16_数组的分隔.py import numpy as np # 创建一维数组 a = np.arange(1, 13) # 调用np.split(ary, indices_or_sections, axis=0)进行分隔 # r = np.split(a,5) # 如果不能被整分就会抛出异常 # (1) 传递整数平均分隔 r = np.split(a, 4) # [array([1, 2, 3]), array([4, 5, 6]), array([7, 8, 9]), array([10, 11, 12])] print(r) # (2) 传递数组 => 按数组进行分隔 r = np.split(a, (4, 6)) # 4,6是每个分隔部分的起点,这里分为三份 索引 [0,3] [4,5] [6:] print(r) # 二维数组进行分隔 => 需要指定axis a = np.arange(1, 17).reshape((4, 4)) # 序列解包 只有r的话r就是一个序列, 现在r,w 想到于序列解包 r, w = np.split(a, 2, axis=0) # 这是按axis把数组分为了两部分 print(r) print(w) r = np.split(a, [1, ], axis=1) # 按axis=1把数组按1分开 print(r) # 依照如此还有三个函数 # hsplit() => split(axis=0) # vsplit() => split(axis=1) # dsplit() => split(axis=2)
数组转置有两种方法
(1) 属性T
(2) np.transpose()
# code17_数组的转置.py import numpy as np # 创建二维数组 a = np.arange(1, 25).reshape(8, 3) print(a) # np.transpose(a, axes=None)进行数组转置 a[i][j] => a[j][i] b = np.transpose(a) print(b) # 通过属性T进行转置(也是产生新的数组) => 对于简单的二维数组的转置(行列调换) c = a.T print("a和c是不是一个对象", a is c) print(c) # 多维数组进行转置 a.shape = (2, 3, 4) print(a, a.shape) # axes => 传入一个转置的维度,否则默认就是axis=0 和 axis=2 进行交换 b = a.transpose() print(b, b.shape) # (4, 3, 2) 默认transpose就是第一维和最后一维进行交换 c = a.transpose((1, 2, 0)) # (1,2,0) 是传入自己预想的装置后的维度 print(c, c.shape)
(1)矢量化运算 (2) 广播机制
1. numpy数组不需要循环遍历,即可对每个元素执行批量的算术运算操作,这个过程叫做矢量化(向量)运算. 2. 如果两个数组的大小(ndarray.shape)不同,则它们进行算术运算时会出现广播机制.
# code02_列表向量运算_数组广播.py # numpy最经典就是向量处理ndarray # 一个简答的例子就是对一个数组每个元素进行开方计算 import random import math import numpy as np a = [random.random() * 100 for i in range(10)] # 1. 普通列表处理 b = [math.sqrt(x) for x in a] print(b) # 2. ndarray向量处理 c = np.sqrt(np.array(a)) print(c) # 数组广播 arr1 = np.array(range(4)).reshape((4, 1)) print(arr1, arr1.shape) # (4, 1) arr2 = np.array([1, 2, 3]) print(arr2, arr2.shape) # (3,) arr3 = arr1 + arr2 print(arr3, arr3.shape) # (4, 3)
1. 如果参与运算的两个对象都是ndarray,并且形状相同,那么会对批次之间进行(+ - * / %)运算. (1) add() => + (2) subtract() => - (3) multiply() => * (4) divide() => / (5) mod() => %
# code18_算术函数.py import numpy as np a = np.arange(9).reshape((3, 3)) b = np.array([10, 10, 10]) # 加法 print(np.add(a, b)) print(a + b) print("-" * 30) # 减法 print(np.subtract(a, b)) print(a - b) print("-" * 30) # 乘法 print(np.multiply(a, b)) print(a * b) print("-" * 30) # 除法 print(np.divide(a, b)) print(a / b) print("-" * 30) # 模运算 print(np.mod(a, b)) print(a % b) print("-" * 30) # out参数的使用 => 把运算结果输出到指定的数组 y = np.empty(a.shape) np.multiply(a, 10, out=y) # 把a中每个元素都乘10,结果存储在y中 print(y)
1. numpy提供了标准的三角函数: (1)sin() (2) cos() (3) tan() 2. np.around(a,decimals) 返回指定数组的四舍五入值 (1) 参数 decimals: 舍入的小数位数,默认值为0,如果为负,整数将四舍五入到小数点左侧的位置 3. np.floor() 返回数字的下舍整数 4. np.ceil() 返回数字的上入整数
# code19_数学函数.py # (1) sin() cos() tan() # (2) around() floor() ceil() import numpy as np from numpy import pi a = np.array((0, pi / 6, pi / 4, pi / 3, pi / 2, pi)) print(np.sin(a)) # np.sin() print(np.cos(a)) # np.cos() print(np.tan(a)) # np.tan() print("-" * 30) print(np.around(np.sin(a))) # np.around() 四舍五入 print(np.floor(np.sin(a))) # np.floor() 向下取整 print(np.ceil(np.sin(a))) # np.ceil() 向上取整
numpy中提供了大量的统计函数
# code20_统计(聚合)函数.py import numpy as np a = np.arange(1, 13).reshape(3, 4) # 1. np.power(ndarray,指数) 幂运算 b = np.power(a, 2) # 运算的函数都有out参数,可以指定输出 print(b) # 2. np.median(a, axis=None, out=None, overwrite_input=False, keepdims=False) 统计中位数 # 一维数组的中位数 # 中位数的计算: 排序后,中间的数 =>奇数不做处理,偶数中间两个数求平均值 b = a.reshape(-1) print("数组b", b) print("数组b的中位数", np.median(b)) # 二维数组的中位数 => 要指定axis print("数组a", a) print("数组a,axis=0(垂直方向)的中位数", np.median(a, axis=0)) print("数组a,axis=1(水平方向)的中位数", np.median(a, axis=1)) print("-" * 30) # 3. np.mean(a,axis=None,out=None) 求平均值 # 一维数组求平均值 print("数组b", b) print("数组b的平均值",np.mean(b)) # 二维数组求平均值 => 要指定axis print("数组a", a) print("数组a,axis=0(垂直方向)的平均数", np.mean(a, axis=0)) print("数组a,axis=1(水平方向)的平均数", np.mean(a, axis=1)) print("-" * 30) # 4. np.sum() np.min() np.max() # 一样区分一维数组和二维数组 # 5. np.argmax() np.argmin() 最值的下标