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

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

原文:https://medium.com/hackernoon/introduction-to-numpy-2-an-absolute-beginners-guide-to-machine-learning-and-data-science-967b21e3542a

这是 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 循环,你也知道广播很酷。

这里有一个视频教程,解释了我所做的一切,如果你有兴趣通过视频消费。

如果你喜欢这篇文章,请鼓掌/推荐。它帮助我写更多这样的文章。


本站为非盈利网站,作品由网友提供上传,如无意中有侵犯您的版权,请联系删除