numpy模块

时间:2024-01-19 15:47:41

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() 效果图:

numpy模块

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)
#
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 # 给定形状产生随机数组