小白的机器学习之路:Numpy探索

本文介绍了NumPy库在数据科学和机器学习中的应用,包括生成随机矩阵、数组操作、计算差值、堆叠生成矩阵及数组切片等核心知识点。

这是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])

# 使用返回值更新A
A = np.append(A,[3,55,34,553])

这么明显又简单的事情,为什么我还要讲? 是这样:我吃过亏。我曾经花了数小时来搞清楚代码为什么失败,最终却发现都是这个微不足道的错误引起的:-(

如何计算邻接元素的差值?

例如,对于数组A:

A
===========
array([  5,   7,   9,  11,  13,  19,   3,  55,  34, 553])

我的问题是,在矩阵A中,我如何计算7-59-711-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,1113。 该怎么做?

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,该怎么做? 很自然地,我们可能会尝试下面的代码:

# 创建目标数组K
K = np.array([])

# 遍历A中所有元素,加1后设置为K的元素
# and append the new value to the array.
for e in A:
    K = np.append(K,e+1)

# 打印目标数组K
K
======================
array([  6,   8,  10,  12,  14,  20,   4,  56,  35, 554])

很可能每个人都会认可这种看起来相当自然的做法。 问题是,这种实现“耗时且效率低下”。

真的吗? 为什么这是低效的?

这就是广播的作用。 我可以只用一行代码实现同样的功能,而不需要任何for循环,如下所示:

K = A+1
K
===============
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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值