首页 > 技术文章 > NumPy模块

Treelight 2020-02-17 23:00 原文

NumPy模块的作用

这个模块是用C语言写的模块,主要是用于科学计算。而使用这个模块是基于多维数组的。

数组与列表的区别

一、数组里的元素必须是同一类型的数据 二、数组的大小是固定的。

numpy的安装

pip install numpy

数组对象的创建

数组对象的创建一般有以下的方法(注意首先导入numpy)
import numpy as np

# 创建对象的方法,均可带参数dtype指定数组元素的类型
# 方法一、
# arr = np.array([1, 2, 3, 4])

# 方法二、类似于range,不过此处步长可为小数
# arr = np.arange(3, 10, 0.2)

# 方法三、前两个参数与arange一样,但第三个参数表明元素的个数
# arr = np.linspace(3, 10, 10)

# 方法四、由于创建的数组不能为空,以下创建的数组的元素均是0
# arr = np.zeros(3)  # [0. 0. 0.]
# arr = np.zeros((3, 5))  # 创建的是3个数组,而每个数组含有5个元素
"""
[[0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0.]]
"""

# 方法五、与四类似,但元素均是1
# arr = np.ones(4)
# arr = np.ones((3, 5))

# 方法六、随机从内容里筛选出废弃的内存地址
arr = np.empty((3, 5))

ndarray数据类型:dtype

布尔型:bool_ 整数型:int_ int8 int16 int32 int64 无符号整数型:uint8 unit16 uint32 uint64 浮点型:float_ float16 float32 float64 复数型:complex_ complex64 complex128

多维数组的操作

运算

数组与一般的数值型数据也可以进行加减乘除等运算,运算结果是每一个元素都与数值型数据进行运算,例子如下:
# 与数值型数据的运算
arr = np.arange(0, 15)
print(arr * 2)  # [ 0  2  4  6  8 10 12 14 16 18 20 22 24 26 28]

数组也可以与数组之间进行运算,但注意必须要求两个数组的shape是一样,运算过程是对同一个索引的元素进行运算,例子如下:

# 与数组的运算
arr = np.arange(0, 15)
arr1 = np.arange(3, 18)
print(arr*arr1)  # [  0   4  10  18  28  40  54  70  88 108 130 154 180 208 238]

索引

普通索引

一维的索引和列表是一样的,但二维的也可以和列表一样,也可以使用[行号,列号]获取,如下:
# 索引
array2d = np.arange(0, 15).reshape((3, 5))
"""
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]
"""
# 获取7的方式一,但不推荐
print(array2d[1][2])  # 7,第二列的第3个,和列表是一样的
# 获取7的方式二,推荐
print(array2d[1, 2])

布尔索引

请看以下例子:
# 布尔索引
import random

arr = np.array([random.randint(0, 10) for _ in range(50)])
# 找出大于5的值
print(arr[arr > 5])
# 找出大于5并且是偶数的
print(arr[(arr > 5) & (arr % 2 == 0)])
# 找出大于5或者是偶数的值
print(arr[(arr > 5) | (arr % 2 == 0)])
# 找出小于等于5的值
print(arr[~(arr > 5)])

原理:数组除了可以进行加减等运算,也可以进行布尔运算,得出True或False,如下

arr = np.array([1, 2, 3, 7, 9, 20, 5, 4, 8, 9])
print(arr > 5)  # [False False False  True  True  True False False  True  True]

然后取其对应为True的值

arr = np.arange(5)
print(arr[[True, False, False, True, True]])  # [0 3 4]

花式索引

一维数组的例子:
arr = np.array([1, 2, 3, 4, 5, 6])
# 取其中索引为0,2,3的
print(arr[[0, 2, 3]])  # [1 3 4]

二维数组的例子:

arr2d = np.arange(15).reshape((3, 5))
"""
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]
"""
# 取所有行的第2和第4个数字
print(arr2d[:, [1, 3]])
# 但如果在切片中使用两个花式索引,和我们想像中的效果不同
print(arr2d[[0, 1], [1, 3]])  # 相当于print([arr2d[0,1], arr2d[1,3]])
# 如果需要获取1、3、11、13这些值,需要两次切片
print(arr2d[:, [1, 3]][[0, 2]])

切片

一维的和列表切片是一样的,这里主要是说明多维的切片 用法:ndarray对象[行切片,列切片]
array2d = np.arange(0, 15).reshape((3, 5))
"""
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]
"""
# 获取第二行到第三行的第四个数:数组对象[行数切片,列切片]
print(array2d[1:, 3])
# 获取第1行到第二行的前3个数
print(array2d[0:3, :3])

切片的赋值

对切片进行赋值,会把切片的内容改为设置的值,如下:
# 切片赋值
arr1 = np.arange(0, 15)
# 把前4个数都改为0
arr1[:5] = 0
print(arr1)  # [ 0  0  0  0  0  5  6  7  8  9 10 11 12 13 14]

但注意以下情况:
arr2 = arr1[0:5]
这样arr1和arr2是同一内存地址,任何一个数组改变,另外一个也会改变

arr1 = np.arange(0, 15)
# 引用了arr1,这样其实它们是不会复制,而是指向同一内存地址,所以arr2改变了,arr1也会改变
arr2 = arr1[3:8]
arr2[0] = 100
print(arr1)  # [  0   1   2 100   4   5   6   7   8   9  10  11  12  13  14]

而要实现这两个数组是不同的内存地址,可使用copy()方法,则彼此不会影响

arr1 = np.arange(0, 15)
arr2 = arr1[3:8].copy()
arr2[0] = 100
print(arr1)  # [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14]

属性

ndarray对象具有以下属性: dtype:元素类型 size:元素个数 ndim:维度 shape:返回一个元组(行数,列数) T:行与列的转换
array2d = np.arange(0, 15).reshape((3, 5))
print(array2d.dtype)  # int32
print(array2d.size)  # 15个元素
print(array2d.ndim)  # 维度
print(array2d.shape)  # (3,5)表示3行5列
print(array2d.T)  # 行与列进行置换

函数

一元函数

接收一个参数 np.sqrt(数组):计算算术平方根 np.abs(数组):求绝对值 np.exp(数组):求指数 np.log(数组):求指数 np.trunc(数组):向零取整 np.round/rint(数组):四舍五入,round还可以指定小数位数 np.floor(数组):向下取整 np.ceil(数组):向上取整 np.modf(数组):把小数和小数点后的分开成两个数组
arr = np.linspace(1, 5, 10)
print(np.modf(arr))
"""
(array([0.        , 0.44444444, 0.88888889, 0.33333333, 0.77777778,
       0.22222222, 0.66666667, 0.11111111, 0.55555556, 0.        ]), array([1., 1., 1., 2., 2., 3., 3., 4., 4., 5.]))
"""

np.isnan(数组):判断此浮点数是不是nan
np.isinf(数组):判断此浮点数是不是inf
这里要特别说明一下什么是nan和inf?它们都是浮点数,都是特殊的浮点数。
nan是not a number,不是一个数字,它与任何浮点数包括它自己都不相等!!一般用于表示数据缺失,而在numpy中两个数组相除,如果都为0,则会得出nan

a = float('nan')
print(a==a) # false

inf表示无穷大,它大于任何的浮点数,而与自己相等。在数学中,0是不能作为除数,但在numpy 数组中,如果0作为除数,则可以得出无穷大的值

a = float('inf')
b = float('inf')
print(a == b)  # True

isinf和isnan的应用

arr1 = np.array([1, 2, 0, 4, 5])
arr2 = np.array([3, 6, 0, 4, 0])
arr3 = arr1 / arr2  # [0.33333333 0.33333333        nan 1.                inf]
# 在arr3中把nan去掉
print(arr3[~np.isnan(arr3)])
# 在arr3中把inf去掉
print(arr3[~np.isinf(arr3)])
# 在arr3中把inf和nan都去掉
print(arr3[~(np.isnan(arr3) | np.isinf(arr3))])

np.cos(数组):求余弦
np.sin(数组):求正弦
np.tan(数组):求正切

二元函数

二元函数需要接收两个参数 np.add(数组1,数组2):相加 np.substract(数组1,数组2):相减 np.multiply(数组1,数组2):乘法 np.divide(数组1,数组2):除法 np.power(数组1,数组2):乘方 np.mod(数组1,数组2):求余 以上与用符号是一样的 np.maximun(数组1,数组2):比较相同位置的值,求最大值
arr1 = np.array([1, 6, 8, 4, 3])
arr2 = np.array([5, 6, 3, 5, 9])
print(np.maximum(arr1, arr2))  # [5 6 8 5 9]

np.minimun(数组1,数组2)

方法

数组.astype('数据类型'):指定数据类型 数组.sum():求数组的总各 数组.mean():求平均值 数组.std():求标准差。即先求此数组的平均值,再用数组里的每一个数减去均值,得出的结果再乘方,再把乘方结果加起来,把加起来的结果除以数组元素个数 数组.var():求平方差 数组.min():求最小值 数组.max():求最大值 数组.argmin():求最大值索引 数组.argmax():求最大值索引

np.random包

此表的函数用法与python的random差不多,只不过里面可以多了一个shape参数 np.random.rand
# 随机生成3个小数
arr1 = np.random.rand(3)  # [0.7977485  0.86182382 0.32340359]
print(type(arr1))

np.random.randint
np.random.choice
np.random.shuffle:打乱数组顺序
np.random.uniform

推荐阅读