Numpy -2 介绍:机器学习和数据科学的绝对初学者指南。
Numpy -2 介绍:机器学习和数据科学的绝对初学者指南。

这是 numpy 教程系列的第二部分。如果你没有读过我之前关于 numpy 的教程,我建议你在这里阅读。在本教程中,我将涵盖数据科学和机器学习所需的一些重要内容,也就是说,我不会涵盖 numpy 的所有可能。
好了那么,我们在之前的教程中已经看到了 np.array(),np.arange(),np.eye(),np.dot(),np.shape,NP . shape(),np.sum()。让我们首先指出我们导入 numpy 的方式,您已经看到如下:
import numpy as np
我们告诉 python“NP”是对 numpy 的正式引用。
np.random.rand():
现在,我们来谈谈使用 numpy 的随机值生成。假设你想得到矩阵形式的随机值。就像下面的语句一样简单:
# generate random values in a 2 x 3 matrix form
np.random.rand(2,3)
====================================================================
array([[ 0.2248368 , 0.49652272, 0.76189091],
[ 0.73520939, 0.48107188, 0.3883801 ]])
好的,那么这个可以扩展到多个 dim 吗?当然是的!这就是 numpy 被建造的原因。
# generate random values in a 12 x 13 matrix form
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.2635477 , 0.88291404, 0.42043263, 0.83565607, 0.92982761,0.79879409, 0.91323242, 0.37954769, 0.60198588, 0.44773903,0.70699903, 0.3892703 , 0.94314732],
[ 0.12593268, 0.97838364, 0.81297353, 0.3368167 , 0.33501746,0.99619471, 0.22476839, 0.93321408, 0.41301684, 0.01808732,0.61321647, 0.22462791, 0.468457 ],
[ 0.63765001, 0.13884884, 0.67648642, 0.65589694, 0.80931411,0.46202022, 0.40819602, 0.03863341, 0.16494124, 0.69603883,0.96849077, 0.19150476, 0.8968954 ],
[ 0.25646945, 0.21928867, 0.70952192, 0.80569537, 0.84562245,0.54595757, 0.00684613, 0.19142737, 0.94387805, 0.80871064,0.73648968, 0.80105002, 0.16716087],
[ 0.3894393 , 0.61933361, 0.41088568, 0.88781578, 0.40932049,0.90947387, 0.71984125, 0.81259019, 0.69020009, 0.56480145,0.43041522, 0.02650665, 0.7738148 ],
[ 0.21326808, 0.2036178 , 0.30368209, 0.51081501, 0.64345557,0.99061654, 0.96805793, 0.19446453, 0.25974565, 0.74033622,0.37379014, 0.67444828, 0.82899251],
[ 0.47571066, 0.82012796, 0.50881338, 0.3900192 , 0.34356749,0.36440024, 0.58048805, 0.74650051, 0.24974157, 0.70129048,0.99920892, 0.29142188, 0.09263266],
[ 0.4140815 , 0.25578684, 0.5485647 , 0.07581615, 0.28539059,0.93805043, 0.56897052, 0.23606972, 0.78568646, 0.609795,0.70741831, 0.51003452, 0.53791667],
[ 0.53967367, 0.78513565, 0.94739241, 0.03891731, 0.15962705,0.45470422, 0.56172944, 0.49735169, 0.35216862, 0.87391629,0.43953245, 0.18160601, 0.78307107],
[ 0.1725005 , 0.89132449, 0.05287284, 0.2113003 , 0.69802999,0.12609322, 0.83490382, 0.34199806, 0.90740966, 0.33934554,0.02015816, 0.13498658, 0.06695927],
[ 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]])
这里有 12 行,每行包含 13 列。很酷,对吧?np 真的是一个很棒的图书馆。我们都知道。
如果我想在数组中手动添加元素呢?np.append()在这里回答你的祈祷!
# generate an array using np.arange()
A = np.arange(5,15,2)
A
====================================================================
array([ 5, 7, 9, 11, 13])
假设我想把 19 加到 a 上,我该怎么做?
这正是我们使用 np.append()的原因。
A = np.append(A,19)
A
====================================================================
array([ 5, 7, 9, 11, 13, 19])
np.append()将元素添加到指定数组中。
另一个(我不是 DJ khaled!):
A = np.append(A,[3,55,34,553])
A
====================================================================
array([ 5, 7, 9, 11, 13, 19, 3, 55, 34, 553])
这一次是需要添加到中的元素列表。因此,我们可以预计,无论是一个元素还是一个元素列表,都将作为参数传递给 np.append(这里是原始数组,这里是元素)。
捕捉返回值很重要,否则这些元素实际上不会被更新到旧列表中。它的意思是:
# A not updated because returned not captured.
np.append(A,[3,55,34,553])# A updated because returned value captured.
A = np.append(A,[3,55,34,553])
我为什么要告诉你这些?很明显很简单!事情是这样的:我花了很长时间试图弄清楚发生了什么,最终归结为我没有抓住这个小错误。
太好了!我如何找到相邻元素之间的区别?
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 的长度小 1。
如果我继续在 B 上做同样的 np.diff(),我会得到如下结果:
B = np.diff(B,n=1)
B
===================================================================
array([ 0, 0, 0, 4, -22, 68, -73, 540])
我可以告诉 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])
所以,简单来说那就是 np.diff()。n 是定义迭代计数的参数。
现在如果我想堆叠元素,形成一个矩阵/向量呢?np.vstack(),np.column_stack()
# lets define 3 lists.
a = [1,2,3]
b = [4,5,6]
c = [7,8,9]
当我们考虑堆叠元素时,有两种变体可以考虑。
如何通过堆叠 3 个列表直接生成一个矩阵?
# 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]])
如何通过堆叠 3 个列为行的列表来生成矩阵?
# 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])
再说广播。
广播是 numpy 最好的特性之一。numpy 能够将操作扩展到所有元素。
那是什么意思?
A
===================================================================
array([ 5, 7, 9, 11, 13, 19, 3, 55, 34, 553])
如果我想给 A 的所有元素加 1 呢?我们的自然倾向是做以下事情:
# create an empty array to hold the new values
K = np.array([])# go through all the elements in A and add 1 to each
# and append the new value to the array.
for e in A:
K = np.append(K,e+1)# print the k array.
K
====================================================================
array([ 6, 8, 10, 12, 14, 20, 4, 56, 35, 554])
这看起来很自然,很可能每个人都会同意这种方法。问题是,所有 numpy 爱好者和极客可能会报告这篇文章“费时低效”,因为它提供了这种低效的解决方案。
真的!?为什么这样效率低?
这就是广播开始发挥作用的时候。我可以只用一行代码而不用任何 for 循环来做同样的事情,如下所示:
K = A+1
K
====================================================================
array([ 6, 8, 10, 12, 14, 20, 4, 56, 35, 554])
但是这是如何工作的呢?
numpy 根据需要在内部匹配元素。
# This is how numpy matches internally aka broadcasting
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 循环,你也知道广播很酷。
这里有一个视频教程,解释了我所做的一切,如果你有兴趣通过视频消费。