NumPy简介:
NumPy 是高性能科学计算和数据分析的基础包;它是pandas等其他工具的基础。
NumPy的主要功能:
1. ndarray,一个多维数组结构,高效且节省空间 (最主要的功能) 2. 无需循环对整组数据进行快速运算的数学函数 3. 线性代数、随机数生成和傅里叶变换功能
安装方法:
pip install numpy
引用方式:
import numpy as np
ndarray --- 多维数组对象
import numpy as np 创建 ndarray: np.array(array_like)
数组与列表的区别:
1. 数组对象内的元素类型必须相同
2. 数据大小不可修改
ndarray 的数据类型:
1. 布尔型:bool_
2. 整型:int_ int8 int16 int32 int64
3. 无符号整型:uint8 uint16 uint32 uint64
4. 浮点型:float_ float16 float32 float64
5. 复数型:complex_ complex64 complex128
array 基础:
示例代码1:(运行在 jupyter notebook 上)
import numpy as np import random # 示例1:已知若干跨国公司的市值(美元),将其换算成人民币 company_value = [random.uniform(100.0,200.0) for i in range(50)] # random.uniform(浮点数1,浮点数2) : 随机生成浮点数 exchange_rate = 6.8 company_value = np.array(company_value) company_value * exchange_rate # company_value 这个列表中的每一个元素会都和 exchange_rate 相乘 """ # 输出结果: array([ 845.86596363, 830.59247689, 925.73635851, 994.17431358, 1202.07839264, 1108.3175636 , 1135.15916313, 1171.85643304, 743.06118207, 1213.00933088, 882.02326337, 1004.72845351, 874.40129737, 722.8946267 , 1308.49169262, 1096.72738352, 1231.12116846, 1255.03236732, 1077.22583737, 1323.68310872, 765.1724099 , 1188.17611809, 940.02458512, 1141.96064667, 1323.77261344, 1301.97767208, 969.35890194, 1291.7188247 , 1082.17748458, 961.91630791, 1158.81519619, 918.03641864, 970.21533038, 1174.21974931, 1154.29890466, 1050.87454 , 1269.64470711, 850.13327118, 1021.26461162, 712.55711713, 1156.62432585, 684.48019691, 996.70613004, 750.45285854, 1243.63861422, 1304.56338027, 1156.27695066, 1235.00442836, 1083.40377629, 783.09838542]) """
示例代码2:(运行在 jupyter notebook 上)
# 示例2:已知购物车中每件端口的价格与商品件数,求总金额 import numpy as np import random unit_price = [random.uniform(10.0,20.0) for i in range(50)] amount = [random.randint(1,10) for i in range(50)] unit_price = np.array(unit_price) amount = np.array(amount) unit_price * amount # unit_price 这个列表中的每一个元素都会和 amount 这个列表中的每一个元素相乘 (unit_price * amount).sum() # .sum() 是 np.array 的求和
示例代码3:数组的属性(运行在 jupyter notebook 上)
# 数组的属性 import numpy as np np.array([1,2,3,4,5]) # 输出结果:array([1, 2, 3, 4, 5]) np.array(range(10)) # 输出结果: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) a = np.array(range(10)) a.dtype # 查看类型 # 输出结果: dtype('int32') a.size # 当前数组存了多少个数 # 输出结果: 10 np.array([[1,2,3,],[4,5,6,]]) # [[1,2,3,],[4,5,6,]] 是一个二维列表;np.array([[1,2,3,],[4,5,6,]]) 是一个二维数组 # 输出结果: array([[1, 2, 3], # [4, 5, 6]]) b= np.array([[1,2,3],[4,5,6]]) b.dtype # 输出结果: dtype('int32') b.size # 返回总的元素个数 # 输出结果: 6 b.shape # 返回的是 几乘几 (元组的形式),这是对于二维数组;对于一维数组而言,返回的是: (数组的长度,) # 输出结果:(2, 3) # 意思是 2行3列 b.T # 数组的转置 (如:行变成列,列变成行) """ 输出结果: array([[1, 4], [2, 5], [3, 6]]) """ b.ndim # 查看当前维度 # 输出结果: 2
numpy-array 创建:
import numpy as np # 以下方式中 np. 被省略 #方式1.: array() # 将列表转换为数组,可选择显式指定 dtype # 方式2: arange() # python3 range的numpy版,支持浮点数 # 方式3: linspace() # 类似 np.arange() ,第三个参数为数组长度 # 方式4: zeros() # 根据指定形状和dtype创建全0数组 # 方式5: ones() # 根据指定形状和dtype创建全1数组 # 方式6: empty() # 根据指定形状和dtype创建空数组(随机值) # 方式7: eye() # 根据指定形状和dtype创建单位矩阵
示例代码:(运行在jupytor notebook上)
# numpy-array 的创建 import numpy as np # 方式一: np.array([1,2,3]) # 输出结果: array([1, 2, 3]) # 方式二: 创建10个全0的数组 (数组中的元素默认为 浮点数 类型) np.zeros(10) # 输出结果: array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) a = np.zeros(5) a.dtype # 输出结果: dtype('float64') # 指定 元素类型 b = np.zeros(3,dtype="int64") b.dtype # 输出结果:dtype('int64') # 方式三:创建5个全1的数组(默认为 浮点数 类型) np.ones(5) # 输出结果: array([1., 1., 1., 1., 1.]) c = np.ones(5) c.dtype # dtype('float64') # 方式四:创建长度为10的空数组(随机值) np.empty(20) """ # 输出结果: array([1.42417221e-306, 1.37961641e-306, 1.24610383e-306, 1.69118108e-306, 8.06632139e-308, 1.20160711e-306, 1.69119330e-306, 1.29062229e-306, 1.60217812e-306, 1.37961370e-306, 1.78020712e-306, 8.90104239e-307, 1.05700515e-307, 1.11261774e-306, 1.29060871e-306, 8.34424766e-308, 8.34445138e-308, 1.37959129e-306, 1.02360528e-306, 8.90029544e-307]) """ # np.empty() 的作用: 数组的大小(长度)是不能变的,所以创建数组时必须先指定好数组的长度,然后再往里面写入值; np.empty() 的效率比 np.zeros()高(速度快) # 方式五:np.arange(起始值,结束值,步长) # 步长可为 浮点数 np.arange(10) # 输出结果: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) np.arange(2,10) # 输出结果: array([2, 3, 4, 5, 6, 7, 8, 9]) np.arange(3,10,2) # 输出结果: array([3, 5, 7, 9]) np.arange(7,10,0.3) # 输出结果: array([7. , 7.3, 7.6, 7.9, 8.2, 8.5, 8.8, 9.1, 9.4, 9.7]) # 方式六: np.linspace(起始值,结束值,分成多少份) # 第三个参数“分成多少份”表示数组的长度 np.linspace(2,10,3) # 输出结果: array([ 2., 6., 10.]) # 数组元素的间隔是一样的 d = np.linspace(1,10,20) d.size # 输出结果: 20 # np.arange() 是“顾首不顾尾”; np.linspace() "顾首且顾尾" # np.linspace() 的用法: import matplotlib.pyplot as plt x = np.linspace(-10,10,10000) y = x**2 plt.plot(x,y) # [<matplotlib.lines.Line2D at 0x19089552d30>] plt.show() # 方式七:np.eye() # 创建线性矩阵 (对角线上是1,其他元素为0) np.eye(10) """ # 输出结果: array([[1., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 1., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 1., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 1., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.]]) """
np.linspace()用途的 plt.show() 效果图:
array 索引和切片:
ndarray-批量运算:
import numpy as np a = np.arange(10) #1. 数组和标量之间的运算: a+1 a*3 1//a a**0.5 a>5 # 2. 同样大小数组之间的运算: a+b a/b a**b a%b a==b a > b # 最后两个返回bool值
ndarray-索引:
# 一维数组的索引: a[5] # 多维数组的索引: 列表式写法: a[2][3] 新式写法: a[2,3] # [2,3] -- 2表示行,3表示列;逗号前是行,逗号后是列
ndarray - 切片:
# 一维数组的切片: a[5:8] a[4:] a[2:10] = 1 # 二维数组的切片: a[1:2,3:4] a[:,3:5] a[:,1]
示例代码:(jupyter notebook)
# array索引和切片 # ndarray--索引: import numpy as np # 快速生成一个二维数组的方法: np.arange(15).reshape((3,5)) # reshape() 里面放一个元组(a,b),a表示行数,b表示列数;.reshape()即将 原数组变成 a行 b列 的多维数组 """ # 输出结果: array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) """ a = np.arange(15).reshape((3,5)) # 索引一: a[1][2] # 第一行 第三列 (行和列都是从0开始) # 输出结果: 7 # 索引二:(对于二维数组);主要用这个 a[1,2] # [1,2] --- 1 表示行, 2表示列 # 输出结果: 7 # ndarray - 切片 # 1. 一维数组的切片: np.arange(15) # 输出结果: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]) b = np.arange(15) b[0:4] # 也是 “顾首不顾尾” # 输出结果: array([0, 1, 2, 3]) b[:5] # array([0, 1, 2, 3, 4]) b[5:] # array([ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]) # 数组 和 列表 的不同: c = list(range(15)) # 列表 c # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] d = b[0:4] # 数组 d # array([0, 1, 2, 3]) e = c[0:4] # 列表 e # [0, 1, 2, 3] d[0] = 20 # 数组:此时会修改原数组 b 的值 b # array([20, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]) e[0] = 20 # 列表 : 此时不会修改原列表的值 c # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] # copy() 方法可以创建数组的深拷贝 f = b[0:4].copy() f # array([20, 1, 2, 3]) f[0] = 30 # 通过 copy()方法 ,此时就不会修改原数组的值 b # array([20, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]) # 二级数组的切片: bia = np.arange(15).reshape((3,5)) bia """ array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) """ # 切出 0,1,5,6 这四个值 # 错误写法: bia[0:2][0:2] """ array([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]) """ """ # 错误分析: bia[0:2] 切出的结果如下: array([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]) 因为 bia[0:2] 默认是按行切,即 从第0行 切到 第1行 此时 bia[0:2] 继续如果继续按照 [0:2] 切,那么得到的依然是原数组(因为还是继续按行切) """ # 正确写法: bia[0:2,0:2] # [,] 逗号前面是行切,逗号后面是列切 """ array([[0, 1], [5, 6]]) """ # 切 7,8,12,13 这四个数 bia[1:3,2:4] """ array([[ 7, 8], [12, 13]]) """ bia[1:,2:4] # 另一种写法 """ array([[ 7, 8], [12, 13]]) """ """ 数组切片与列表的不同:数组切片时并不会自动复制(而是创建一个视图),在切片数组上的修改会影响原数组 .copy() 方法可以创建数组的深拷贝 """
array 布尔型索引:
# 问题:给一个数组,选出数组中所有大于5的数 a[a>5] #原理: 1. 数组与标量的运算: a>5 会对a中的每一个元素进行判断,返回一个布尔数组 2. 布尔型索引: 将同样大小的布尔数组传进索引,会返回一个由所有True对应位置的元素的数组
示例代码:
# ndarray 布尔型索引 # 问题1:给一个数组,选出数组中所有大于5的数 import numpy as np import random a = [random.randint(0,10) for i in range(20)] a = np.array(a) a[a>5] # array([ 8, 9, 6, 7, 8, 8, 8, 7, 6, 7, 10]) """ a[a>5] 的过程分析: 第一步是 a>5 返回一组 布尔值 (即 数组和标量做运算); 第二步是 a[] 中放一个 布尔型的 列表 或者 数组,且这个列表(或数组)的长度和 a 相同,则 a[] 会将所有为 True 的元素过滤出来返回 """ a = np.arange(4) a # array([0, 1, 2, 3]) a[[True,False,False,True]] # array([0, 3]) # 问题二:给一个数组,选出数组中所有大于5的偶数 b = [random.randint(0,10) for i in range(20)] b = np.array(b) # 方式一: c = b[b>5] c[c%2==0] # array([ 6, 10, 10, 8]) # 错误写法: # b[b>5][b%2==0] # 这种写法会报错,因为 [b%2==0] 的长度是 b 的长度, 而 b[b>5] 是一个新的数组,长度已经不再是 b 的长度,所以长度不一致 # 方式二:两个条件写到一个 [] 中 b[(b>5) & (b%2==0)] # 用 & 连接多个条件,并且由于位运算符的优先级,每个条件要加上 () ;此处的 & 不能换成 and ,换成 and 会报错;& 表示 与,| 表示 或,~ 表示 非 b[(b>5)| (b%2==0)]
array -- 花式索引:
# 问题1:对于一个数组,选出其第1,3,4,6,7 个元素,组成新的二维数组 a[[1,3,4,6,7]] # 问题2:对于一个二维数组,选出其第一列和第三列,组成新的二维数组 a[:,[1,3]]
示例代码:
# ndarray - 花式索引 # 问题1:对于一个数组,选出其第1,3,4,6,7 个元素,组成新的二维数组 import numpy as np a = np.arange(20) # 错误写法: # a[1,3,4,6,7] # 逗号 分的是 行和列 # 正确写法:(对于一维数组) a[[1,3,4,6,7]] # a[] 中 放一个列表,列表中放索引值 # array([1, 3, 4, 6, 7]) # 对于二维数组: b = np.arange(20).reshape(4,5) b """ array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19]]) """ # 普通索引、切片、布尔索引、花式索引,想要行列搭配,就用 中间一个 逗号,逗号左右用哪种都可以 b[0,2:4] # 左边用常规索引,表示第0行,右边用切片 # array([2, 3]) b[0,b[0]>2] # 逗号左边是普通索引,右边是布尔索引 # array([3, 4]) b[0:2,b[0]>2] # b[0]>2 返回的是 布尔型数组:array([False, False, False, True, True]) """ array([[3, 4], [8, 9]]) """ # 注意:花式索引 和 花式索引 不能同时出现在 逗号 两边,如下:想选取 b 中的 6,8,16,18 b[[1,3],[1,3]] # 不要用这种写法 # array([ 6, 18]) # 逗号两个都是花式索引时,不会得到自己想要的结果 # 选取 b 中的 6,8,16,18:分步去取 b[[1,3],:][:,[1,3]] # [[1,3],:] -- 行上取1和3行,列上全取;[:,[1,3]] 列上取1和3列,行上全取 """ array([[ 6, 8], [16, 18]]) """
NumPy -- 通用函数:
通用函数: 能同时对数组中所有元素进行运算的函数
常见通用函数:
1. 一元函数: abc ,sqrt ,exp ,log ,ceil ,floor ,rint ,trunc ,modf ,isnan ,isinf ,cos ,sin ,tan 2. 二元函数: add ,substract ,multiply ,divide ,power ,mod ,maximum ,minimum
示例代码:
# 通用函数 import numpy as np a = np.arange(-5,5) a # array([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]) abs(a) # python 内置的 abs 也能对数组进行绝对值操作 # 输出结果: array([5, 4, 3, 2, 1, 0, 1, 2, 3, 4]) np.abs(a) # 对数组中的每个元素进行绝对值操作 # array([5, 4, 3, 2, 1, 0, 1, 2, 3, 4]) np.sqrt(a) # 对数组中的每个元素进行 开方(二次方) 运算 """ array([ nan, nan, nan, nan, nan, 0. , 1. , 1.41421356, 1.73205081, 2. ]) """ # 小数变整数的方法: # 1. int 方法: 向 0 取整法(向0的方法取整) b = 1.6 int(b) # 输出结果: 1 c = -1.6 int(c) # 输出结果: -1 # 2. round 方法: 四舍五入 ;小数位的值小于 0.5时,向0取整,小数位的值大于等于0.5时 向 0 的反方向取整 round(b) # 输出结果: 2 round(c) # 输出 结果: -2 import math # 3. 向上取整 # 3.1 . math.ceil() math.ceil(b) # 2 math.ceil(c) # -1 # 4. 向下取整 # 4.1 . math.floor() math.floor(b) # 输出结果: 1 math.floor(c) # -2 d = np.arange(-5.5,5.5) d # array([-5.5, -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5]) # 数组的取整: # 1. np.floor(数组) : 对数组中的所有元素进行 向下取整 np.floor(d) # array([-6., -5., -4., -3., -2., -1., 0., 1., 2., 3., 4.]) # 2. np.ceil(数组) : 对数组中的所有元素进行 向上取整 np.ceil(d) # array([-5., -4., -3., -2., -1., -0., 1., 2., 3., 4., 5.]) # 3. np.round(数组) : 对数组中的元素进行 四舍五入 np.round(d) # array([-6., -4., -4., -2., -2., -0., 0., 2., 2., 4., 4.]) """ 在实际使用中发现round函数并不总是如上所说的四舍五入。可参考以下链接: http://www.runoob.com/python/func-number-round.html http://www.runoob.com/w3cnote/python-round-func-note.html """ # 4. np.rint(数组) : 作用和 np.round() 一样 np.rint(d) # array([-6., -4., -4., -2., -2., -0., 0., 2., 2., 4., 4.]) # 5. np.trunc(数组) : 对数组中的每个数值进行 向0取整 np.trunc(d) # array([-5., -4., -3., -2., -1., -0., 0., 1., 2., 3., 4.]) # np.modf(数组) : 返回两个数组, 一个数组中是 小数 部分,一个数组中是 整数 部分 np.modf(d) """ (array([-0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]), array([-5., -4., -3., -2., -1., -0., 0., 1., 2., 3., 4.])) """ x,y = np.modf(d) # 可用元组、列表的方式接收 x # 输出结果: array([-0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]) y # 输出结果: array([-5., -4., -3., -2., -1., -0., 0., 1., 2., 3., 4.]) # 数组的 inf e = np.arange(0,5) e # array([0, 1, 2, 3, 4]) 5/e # array([ inf, 5. , 2.5 , 1.66666667, 1.25 ]) # 数组的 nan np.sqrt(d) """ array([ nan, nan, nan, nan, nan, nan, 0.70710678, 1.22474487, 1.58113883, 1.87082869, 2.12132034]) """ """ 补充: 浮点数特殊值 1. nan (not a number):不等于任何浮点数(nan != nan) 2. inf (infinity):比任何浮点数都大 3. NumPy 中创建特殊值:np.nan 和 np.inf 4. 在数据分析中, nan 常被用作表示数据缺失值 """ # float("amaosi") # 对这种字符串进行 float() 会报错 float("nan") # 对字符串 "nan" 进行 float 则不会报错 # 输出结果: nan float("inf") # 输出结果: inf e/e # 输出结果: array([nan, 1., 1., 1., 1.]) np.nan # 输出结果: nan np.nan == np.nan # 输出结果: False np.nan is np.nan # 输出结果: True f = e/e f # 输出结果: array([nan, 1., 1., 1., 1.]) # 判断 f 中是否有 nan f == np.nan # 输出结果: array([False, False, False, False, False]) # 所以不能用类似布尔型索引判断 f 中是否有 nan f is np.nan # 输出结果: False # 这种方式也不行 np.nan in f # 输出结果: False # 正确方法: np.isnan(数组) 方法: 返回数组中是否有 nan ; ** 该方法很重要,用于缺失值处理 np.isnan(f) # 输出结果: array([ True, False, False, False, False]) # 用法: 去掉 f 中的 nan f[~np.isnan(f)] # ~ 表示“非”; & 表示“与”, | 表示“或” # 输出结果: array([1., 1., 1., 1.]) # inf 的相关: float("inf") > 10000000000000000000000000000000 # 输出结果: True # 去掉数组中的 inf : m = np.array([1,2,3,4,5]) n = np.array([1,0,1,0,1]) k = m/n k # 输出结果: array([ 1., inf, 3., inf, 5.]) # 方式一: k[k!=np.inf] # 输出结果: array([1., 3., 5.]) # 方式二: k[~np.isinf(k)] # 输出结果: array([1., 3., 5.]) # 二元函数:能放两个数组 # np.maximum(数组1,数组2) # 返回较大的数 m = np.array([6,2,8,9,7]) n = np.array([4,5,3,10,5]) np.maximum(m,n) # 输出结果: array([ 6, 5, 8, 10, 7])
numpy -- 统计方法和随机数生成:
1. 数学和统计方法:
sum # 求和 mean # 求平均数 std # 求标准差 var # 求方差 min # 求最小值 max # 求最大值 argmin # 求最小值的索引 argmax # 求最大值的索引
2. NumPy随机数生成:
rand # 给定形状产生随机数组(0到1之间的数) randint # 给定形状产生随机整数 choice # 给定形状产生随机选择 shuffle # 与 random.shuffle 相同 uniform # 给定形状产生随机数组