小白的机器学习之路:Numpy探索
来源:互联网 发布:数淘宝指数 编辑:程序博客网 时间:2024/05/18 20:53
这是numpy
教程系列的第二部分。 如果你还没有阅读过第一部分,我建议你先读一下。 在这个教程中,我将介绍Numpy
中与数据科学和机器学习相关的重要知识点,也就是说,我不打算涵盖numpy
所有的功能。
在前面的教程中,我们已经学习了np.array()
、np.arange()
、np.eye()
、np.dot()
、np.shape()
、np.reshape()
、np.sum()
。如果你想马上就练习下Numpy
,可以使用汇智网的Numpy在线运行环境。
现在还是先导入numpy
:
import numpy as np
上面的语句告诉python
,在后面的代码中,我们将使用np
来引用numpy
。
np.random.rand()
先来看看使用numpy
来生成随机值。 假设你想获得矩阵形式的随机值, 这很简单:
# 生成 2 x 3 随机矩阵np.random.rand(2,3)=======================array([[ 0.2248368 , 0.49652272, 0.76189091], [ 0.73520939, 0.48107188, 0.3883801 ]])
好吧,这可以扩展到多个维度吗? 当然可以! 这就是开发numpy
的原因。
# 生成 12 x 13 随机矩阵np.random.rand(12,13)======================array([[ 0.43385691, 0.15503296, 0.19860119, 0.65346609, 0.16774261,0.56058978, 0.84974275, 0.05887681, 0.27276929, 0.88750259,0.25141674, 0.05663906, 0.54186252],...[ 0.14066135, 0.34828447, 0.0780561 , 0.00126867, 0.57958087,0.93641585, 0.70294758, 0.21712057, 0.24902555, 0.53284372,0.19795993, 0.69817631, 0.71156616]])
很容易就得到12x13
的随机矩阵。 这很酷,对吧? np
的确是一个出色的库。
如果想手动添加元素到数组中,该怎么办?
例如,对于下面的数组A
:
A = np.append(A,19)A====================array([ 5, 7, 9, 11, 13, 19])
如果想给A
添加一个成员19
,该怎么做?
np.append()
满足的就是这个需求,它将元素添加到指定的数组中:
A = np.append(A,19)A===================array([ 5, 7, 9, 11, 13, 19])
另一个小例子:
A = np.append(A,[3,55,34,553])A====================array([ 5, 7, 9, 11, 13, 19, 3, 55, 34, 553])
上面的例子是将一组元素添加到数组A
中。所以不管是元素还是元素列表,都可以作为参数传入np.append()
。
注意np.append()
不会更新原有的数组,因此需要捕捉其返回值来更新原始数组:
# A 不会自动更新np.append(A,[3,55,34,553])# 使用返回值更新AA = np.append(A,[3,55,34,553])
这么明显又简单的事情,为什么我还要讲? 是这样:我吃过亏。我曾经花了数小时来搞清楚代码为什么失败,最终却发现都是这个微不足道的错误引起的:-(
如何计算邻接元素的差值?
例如,对于数组A:
A===========array([ 5, 7, 9, 11, 13, 19, 3, 55, 34, 553])
我的问题是,在矩阵A
中,我如何计算7-5
,9-7
,11-9
? 换句话说,我怎样才能批量计算A [n + 1] -A [n]
?
np
有一个内置方法np.diff()
专用于解决这个问题。 它看起来像这样:
B = np.diff(A,n=1)B===============array([ 2, 2, 2, 2, 6, -16, 52, -21, 519])
如果简单做一下减法计算,就会注意到这个数组正好是A [n + 1] -A [n]
。 这个数组比A
要少一个元素。
如果继续在B
上执行相同的np.diff()
,最终会得到以下结果:
B = np.diff(B,n=1)B===================================================================array([ 0, 0, 0, 4, -22, 68, -73, 540])
也可以使用迭代参数n
告诉np.diff()
进行两次差分计算,而不必进行两次调用:
# parameter n indicates that this diff() must be run twice. np.diff(A,n=2)===================================================================array([ 0, 0, 0, 4, -22, 68, -73, 540])
如何通过堆叠来生成矩阵/向量?
先定义三个列表:
# lets define 3 lists.a = [1,2,3]b = [4,5,6]c = [7,8,9]
当我们谈到堆叠元素时,有两种思路:行堆叠和列堆叠。
列堆叠
# directly stack with lists passed in the same order.np.vstack((a,b,c))=====================array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])np.vstack((b,a,c))=======================array([[4, 5, 6], [1, 2, 3], [7, 8, 9]])
行堆叠
# stack with lists passed taking their columns as rows. np.vstack((a,b,c))===================================================================array([[1, 4, 7], [2, 5, 8], [3, 6, 9]])
我们再回头来看看这些列表:
a = [1,2,3]b = [4,5,6]c = [7,8,9]
在这里,列方向是元素[1,4,7]
,[2,5,8]
,[3,6,9]
。 问题是,如何让这些元素按行堆叠?
np.column_stack()
np.column_stack((a,b,c))========================array([[1, 4, 7], [2, 5, 8], [3, 6, 9]])np.column_stack((b,a,c))========================array([[4, 1, 7], [5, 2, 8], [6, 3, 9]])
完美!
如何从数组中选择子集合?
例如,在处理数组A
时,我只想选中元素9
,11
和13
。 该怎么做?
A==================array([ 5, 7, 9, 11, 13, 19, 3, 55, 34, 553])
这其实就是数组切片:指定开始序号和停止序号,切片选出在这两者之间(不包括停止序号)的所有元素。
例如:
A[2:5] ===================array([ 9, 11, 13])
在原数组中,成员9
位于序号2
,而成员13
位于序号4
。当进行数组切片时,要获取序号4
处的元素,必须设置停止索引为5
。
从现在开始,我将把起始序号作为下界,停止序号作为上界。 因此,一般来说,切片可以被表述为:
A[lowerbound(inclusive): upperbound(exclusive)]
另一个例子:
A[0:3]==============array([5, 7, 9])
现在谈谈广播
广播(broadcasting
)是numpy
最棒的特性之一,可以将一个操作扩展到矩阵中的所有元素。
什么意思?
A================array([ 5, 7, 9, 11, 13, 19, 3, 55, 34, 553])
如果我想给A
的所有元素加1
,该怎么做? 很自然地,我们可能会尝试下面的代码:
# 创建目标数组KK = np.array([])# 遍历A中所有元素,加1后设置为K的元素# and append the new value to the array.for e in A: K = np.append(K,e+1)# 打印目标数组KK======================array([ 6, 8, 10, 12, 14, 20, 4, 56, 35, 554])
很可能每个人都会认可这种看起来相当自然的做法。 问题是,这种实现“耗时且效率低下”。
真的吗? 为什么这是低效的?
这就是广播的作用。 我可以只用一行代码实现同样的功能,而不需要任何for
循环,如下所示:
K = A+1K===============array([ 6, 8, 10, 12, 14, 20, 4, 56, 35, 554])
但是这是什么原理?
numpy
在内部实现中,可以根据需要来进行操作元素匹配:
# numpy实现广播的原理:展开A+[1,1,1,1,1,1,1,1,1,1]
另一个例子:
A*-1=============array([ -5, -7, -9, -11, -13, -19, -3, -55, -34, -553])
注意整个数组现在带有减号。 这就是广播。
现在你知道了,如果想处理一个numpy
数组中的所有元素,不一定需要使用for
循环,广播真的很酷。
如果你喜欢这篇文章,记得关注我的头条号:新缸中之脑!
原文:Introduction to Numpy -2 : An absolute beginners guide to Machine Learning and Data science.