写点什么

前置机器学习(三):30 分钟掌握常用 NumPy 用法

用户头像
caiyongji
关注
发布于: 2021 年 03 月 22 日
前置机器学习(三):30分钟掌握常用NumPy用法

NumPy 支持大量的维度数组与矩阵运算,是针对数组运算的 Python 库。


本文收录于机器学习前置教程系列


一、Python 基础


我们首先巩固一下 Python 的基础知识。Python 有 6 种标准数据类型:Number(数字),String(字符串),List(列表),Tuple(元组),Set(集合),Dictionary(字典)。

其中:

不可变数据:Number(数字)、String(字符串)、Tuple(元组)。

可变数据:List(列表)、Dictionary(字典)、Set(集合)。


1. List[列表]


列表由方括号 [ ] 包裹,每个位置的数值可变。


list = [1, 2, 3, 4, 5, 6]
复制代码

根据位置取值,如取第 2 个位置的值:

list[1]
复制代码

得到 2

从第 3 个位置取值,到列表末尾的所有值:

a[2:]
复制代码

得到 [3, 4, 5, 6]


改变指定位置的值:


list[0] = 9
复制代码

列表 a 此时输出为 [9, 2, 3, 4, 5, 6]


2. Tuple(元组)


元组由圆括号 ( ) 包裹,每个位置的数值不可变。允许数据重复


tuple = ('a', 'a, 'c', 1, 2, 3.0)
复制代码

输出('a', 'a', 'c', 1, 2, 3.0)

取最后一个位置的元素:

tuple[-1]
复制代码

输出 3.0


元组操作与列表类似,但不可改变元组内元素的值,否则会报错。

tuple[2] = 'caiyongji'
复制代码



3. Set{集合}


集合是包含不重复元素的集体,由花括号 { } 包裹。


set1 = {'a','b','c','a'}set2 = {'b','c','d','e'}
复制代码

set1 的输出结果为:{'a', 'b', 'c'}注意:集合会删除重复元素。

set2 的输出结果为:{'b', 'c', 'd', 'e'}


与列表和元组不同,集合是不可下标的,如:

set1[0]
复制代码



下面,我们来看看集合运算。


set1 和 set2 的差集

set1 - set2#set1.difference(set2) 
复制代码

输出:{'a'}


set1 和 set2 的并集

set1 | set2#set1.union(set2) 
复制代码

输出:{'a', 'b', 'c', 'd', 'e'}


set1 和 set2 的交集

set1 & set2#set1.intersection(set2) 
复制代码

输出:{'b', 'c'}


set1 和 set2 的对称差集

set1 ^ set2 #(set1 - set2) | (set2 - set1)#set1.symmetric_difference(set2)
复制代码

输出:{'a', 'd', 'e'}


以上差集、并集、交集、对称差集都有对应的集合方法,可以注释方法自己试试。


4. Dictionary{字典:Dictionary}


字典是一种映射关系,是无序有键值对(key-value)集合。字典不允许重复的键(key),但允许重复的值(value)。

dict = {'gongzhonghao':'caiyongji','website':'caiyongji.com', 'website':'blog.caiyongji.com'}
复制代码

字典输出{'gongzhonghao': 'caiyongji', 'website': 'blog.caiyongji.com'},需要注意的是,当字典包含重复键,后面的会覆盖前面的元素。

dict['gongzhonghao']
复制代码

输出字符串 caiyongji。我们也可以使用get方法得到相同效果。

dict.get('gongzhonghao')
复制代码

查看所有的键(key):

dict.keys()
复制代码

输出 dict_keys(['gongzhonghao', 'website'])


查看所有的值(value):

dict.values()
复制代码

输出 dict_values(['caiyongji', 'blog.caiyongji.com'])

改变某一项的值:

dict['website'] = 'caiyongji.com'dict
复制代码

输出 {'gongzhonghao': 'caiyongji', 'website': 'caiyongji.com'}


了解了 Python 的数据类型,我们可以学着使用 NumPy 了。


二、Numpy 常见用法


1. 创建数组

import numpy as nparr = np.array([1, 2, 3, 4, 5])
复制代码

arr 的输出为array([1, 2, 3, 4, 5])


我们输入以下代码创建二维数组:

my_matrix = [[1,2,3],[4,5,6],[7,8,9]]mtrx= np.array(my_matrix)
复制代码

mtrx 的输出如下:

array([[1, 2, 3],       [4, 5, 6],       [7, 8, 9]])
复制代码

2. 索引与切片


索引一维数组与二位数组如下:

print('arr[0]=',arr[0],'mtrx[1,1]=',mtrx[1,1])
复制代码

输出 arr[0]= 1 mtrx[1,1]= 5


对数组切片:


arr[:3]
复制代码

输出结果为 array([1, 2, 3])


倒数切片:


arr[-3:-1]
复制代码

输出 array([3, 4])


加入步长(step),步长决定了切片间隔:

arr[1:4:2]
复制代码

输出 array([2, 4])


二维数组切片:

mtrx[0:2, 0:2]
复制代码

输出,代码意义为取第 1、2 行,第 1、2 列:


array([[1, 2],       [4, 5]])
复制代码


3. dtype


NumPy 的 dtpe 有如下几种数据类型:

  • i - integer

  • b - boolean

  • u - unsigned integer

  • f - float

  • c - complex float

  • m - timedelta

  • M - datetime

  • O - object

  • S - string

  • U - unicode string

  • V - fixed chunk of memory for other type ( void )


import numpy as nparr1 = np.array([1, 2, 3, 4])arr2 = np.array(['apple', 'banana', 'cherry'])print('arr1.dtype=',arr1.dtype,'arr2.dtype=',arr2.dtype)
复制代码

输出为 arr1.dtype= int32 arr2.dtype= <U6。arr1 数据类型为 int32,arr2 的<U6 表示不超过 6 位 Unicode 字符串。


我们可以指定 dtype 类型。


arr = np.array(['1', '2', '3'], dtype='f')
复制代码

输出结果位 array([1., 2., 3.], dtype=float32),其中 1.表示 1.0,可以看到 dtype 被设置位 float32 数据类型。


4. 一般方法


4.1 arange


np.arange(0,101,2)输出结果如下,该命令表示,在[0,101)区间内均匀地生成数据,间隔步长为 2。


array([  0,   2,   4,   6,   8,  10,  12,  14,  16,  18,  20,  22,  24,        26,  28,  30,  32,  34,  36,  38,  40,  42,  44,  46,  48,  50,        52,  54,  56,  58,  60,  62,  64,  66,  68,  70,  72,  74,  76,        78,  80,  82,  84,  86,  88,  90,  92,  94,  96,  98, 100])
复制代码


4.2 zeros


np.zeros((2,5))输出结果如下,该命令表示,输出 2 行 5 列全为 0 的矩阵(二维数组)。


array([[0., 0., 0., 0., 0.],       [0., 0., 0., 0., 0.]])
复制代码

4.3 ones


np.ones((4,4))输出结果如下,该命令表示,输出 4 行 4 列全为 1 的矩阵。

array([[1., 1., 1., 1.],       [1., 1., 1., 1.],       [1., 1., 1., 1.],       [1., 1., 1., 1.]])
复制代码

4.4 eye


np.eye(5)输出结果如下,该命令表示,输出对角线为 1 其余全为 0 的 5 行 5 列方阵。方阵为行列相同的矩阵。


array([[1., 0., 0., 0., 0.],       [0., 1., 0., 0., 0.],       [0., 0., 1., 0., 0.],       [0., 0., 0., 1., 0.],       [0., 0., 0., 0., 1.]])
复制代码


4.5 rand

np.random.rand(5,2) 命令生成 5 行 2 列的随机数。


array([[0.67227856, 0.4880784 ],       [0.82549517, 0.03144639],       [0.80804996, 0.56561742],       [0.2976225 , 0.04669572],       [0.9906274 , 0.00682573]])
复制代码

如果想保证随机出与本例一样的随机数,可使用与本例相同的随机种子。通过np.random.seed方法设置。


np.random.seed(99)np.random.rand(5,2)
复制代码

4.6 randint

np.random.randint(0,101,(4,5))输出结果如下,该命令表示,在[0,101)区间内随机选取整数生成 4 行 5 列的数组。


array([[ 1, 35, 57, 40, 73],       [82, 68, 69, 52,  1],       [23, 35, 55, 65, 48],       [93, 59, 87,  2, 64]])
复制代码


4.7 max min argmax argmin


我们先随机生成一组数:


np.random.seed(99)ranarr = np.random.randint(0,101,10)ranarr
复制代码

输出:


array([ 1, 35, 57, 40, 73, 82, 68, 69, 52,  1])
复制代码

查看最大最小值分别为:

print('ranarr.max()=',ranarr.max(),'ranarr.min()=',ranarr.min())
复制代码

输出结果为ranarr.max()= 82 ranarr.min()= 1

其中最大值和最小值的索引位置分别为:

print('ranarr.argmax()=',ranarr.argmax(),'ranarr.argmin()=',ranarr.argmin())
复制代码

输出:ranarr.argmax()= 5 ranarr.argmin()= 0。注意,当出现多个最大最小值时,取前面的索引位置。


三、NumPy 进阶用法


1. reshape

arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])newarr = arr.reshape(4, 3)
复制代码

其中,arr 为一维数组,newarr 为二位数组,其中行为 4,列为 3。

print('arr.shape=',arr.shape,'newarr.shape=',newarr.shape)
复制代码

输出 arr.shape= (12,) newarr.shape= (4, 3)


newarr的输出结果如下:

array([[ 1,  2,  3],       [ 4,  5,  6],       [ 7,  8,  9],       [10, 11, 12]])
复制代码


2. 合并与分割


2.1 concatenate


一维数组合并:


arr1 = np.array([1, 2, 3])arr2 = np.array([4, 5, 6])arr = np.concatenate((arr1, arr2))arr
复制代码

输出: array([1, 2, 3, 4, 5, 6])


二维数组合并:


arr1 = np.array([[1, 2], [3, 4]])arr2 = np.array([[5, 6], [7, 8]])arr = np.concatenate((arr1, arr2))arr
复制代码

输出为:


array([[1, 2], [3, 4], [5, 6], [7, 8]])
复制代码

我们添加参数 axis=1

arr1 = np.array([[1, 2], [3, 4]])arr2 = np.array([[5, 6], [7, 8]])arr = np.concatenate((arr1, arr2), axis=1)arr
复制代码

输出为:

array([[1, 2, 5, 6],       [3, 4, 7, 8]])
复制代码

我们把鼠标移到 concatenate,按快捷键Shift+Tab查看方法说明。可以看到concatenate方法沿着现有的轴进行合并操作,默认 axis=0。当我们设置 axis=1 后,合并操作沿着列进行。



2.2 array_split

分割数组:


arr = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]])newarr = np.array_split(arr, 3)newarr
复制代码

newarr 的值为:

[array([[1, 2],        [3, 4]]), array([[5, 6],        [7, 8]]), array([[ 9, 10],        [11, 12]])]
复制代码


3. 搜索与筛选

3.1 搜索

NumPy 可通过where方法查找满足条件的数组索引。

arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])x = np.where(arr%2 == 0)x
复制代码

输出:

(array([1, 3, 5, 7], dtype=int64),)
复制代码

3.2 筛选

我们看看下面的代码:

bool_arr = arr > 4arr[bool_arr]
复制代码

输出:array([5, 6, 7, 8])。这回我们返回的是数组中的值,而非索引。

我们看看bool_arr的内容究竟是什么。

bool_arr的输出为:

array([False, False, False, False,  True,  True,  True,  True])
复制代码

所以我们可以用以下命令代替以上筛选。

arr[arr > 4]
复制代码


4. 排序


sort方法可对 ndarry 数组进行排序。

arr = np.array(['banana', 'cherry', 'apple'])np.sort(arr)
复制代码


输出排序后的结果:array(['apple', 'banana', 'cherry'], dtype='<U6')


针对二维数组,sort方法对每一行单独排序。

arr = np.array([[3, 2, 4], [5, 0, 1]])np.sort(arr)
复制代码

输出结果:

array([[2, 3, 4],       [0, 1, 5]])
复制代码

5. 随机


5.1 随机概率


如果我们想完成如下需求该如何处理?

>生成包含 100 个值的一维数组,其中每个值必须为 3、5、7 或 9。

>将该值为 3 的概率设置为 0.1。

>将该值为 5 的概率设置为 0.3。

>将该值为 7 的概率设置为 0.6。

>将该值为 9 的概率设置为 0。


我们用如下命令解决:


random.choice([3, 5, 7, 9], p=[0.1, 0.3, 0.6, 0.0], size=(100))
复制代码

输出结果:


array([7, 5, 7, 7, 7, 7, 5, 7, 5, 7, 7, 5, 5, 7, 7, 5, 3, 5, 7, 7, 7, 7,       7, 7, 7, 7, 7, 7, 5, 3, 7, 5, 7, 5, 7, 3, 7, 7, 3, 7, 7, 7, 7, 3,       5, 7, 7, 5, 7, 7, 5, 3, 5, 7, 7, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 5,       7, 7, 7, 7, 7, 5, 7, 7, 7, 7, 3, 7, 7, 5, 7, 5, 7, 5, 7, 7, 5, 7,       7, 7, 7, 7, 7, 3, 5, 5, 7, 5, 7, 5])
复制代码


5.2 随机排列


5.2.1 permutation


根据原有数组生成新的随机排列。


np.random.seed(99)arr = np.array([1, 2, 3, 4, 5])new_arr = np.random.permutation(arr)new_arr
复制代码

输出为:array([3, 1, 5, 4, 2])。原数组arr不变。


5.2.2 shuffle


改变原有数组为随机排列。shuffle 在英文中有洗牌的意思。


np.random.seed(99)arr = np.array([1, 2, 3, 4, 5])np.random.shuffle(arr)arr
复制代码

输出为:array([3, 1, 5, 4, 2])。原数组arr改变。


5.3 随机分布


5.3.1 正太分布


使用np.random.normal方法生成符合正太分布的随机数。


x = np.random.normal(loc=1, scale=2, size=(2, 3))x
复制代码


输出结果为:


array([[ 0.14998973,  3.22564777,  1.48094109],       [ 2.252752  , -1.64038195,  2.8590667 ]])
复制代码


如果我们想查看 x 的随机分布,需安装 seaborn 绘制图像。使用 pip 安装:

>pip install -i https://pypi.tuna.tsinghua.edu.cn/simple seaborn


import matplotlib.pyplot as pltimport seaborn as snssns.distplot(x, hist=False)plt.show()
复制代码



5.3.2 二项分布


使用np.random.binomial方法生成符合二项分布的随机数。


x = np.random.binomial(n=10, p=0.5, size=10)x
复制代码

输出结果为: array([8, 6, 6, 2, 5, 5, 5, 5, 3, 4])


绘制图像:


import matplotlib.pyplot as pltimport seaborn as snssns.distplot(x, hist=True, kde=False)plt.show()
复制代码



5.3.3 多项式分布


多项式分布是二项分布的一般表示。使用np.random.multinomial方法生成符合多项式分布的随机数。


x = np.random.multinomial(n=6, pvals=[1/6, 1/6, 1/6, 1/6, 1/6, 1/6])x
复制代码

上面代码,我们可以简单理解为投掷骰子。n=6 为骰子的面,pvals 表示每一面的概率为 1/6。


5.3.4 其他


除以上分布外还有泊松分布、均匀分布、指数分布、卡方分布、帕累托分布等。感兴趣的可自行搜索。




本文收录于机器学习前置教程系列。欢迎大家点赞、收藏、关注,更多关于机器学习的精彩内容持续更新中……!


发布于: 2021 年 03 月 22 日阅读数: 12
用户头像

caiyongji

关注

还未添加个人签名 2017.12.28 加入

还未添加个人简介

评论

发布
暂无评论
前置机器学习(三):30分钟掌握常用NumPy用法