第一课实践:NumPy基础

Github:https://github.com/GakkiWl/July_data_mining

NumPy是Python的科学计算的一个核心库。它提供了一个高性能的多维数组(矩阵)对象,可以完成在其之上的很多操作。很多机器学习中的计算问题,把数据vectorize之后可以进行非常高效的运算。

数组

一个NumPy数组是一些类型相同的元素组成的类矩阵数据。用list或者层叠的list可以初始化:

import numpy as np

a = np.array([1, 2, 3])  # 一维Numpy数组
print(type(a))            # Prints "<type 'numpy.ndarray'>"
print (a.shape)            # Prints "(3,)"
print (a[0], a[1], a[2])   # Prints "1 2 3"
a[0] = 5                 # 重赋值
print(a)                 # Prints "[5, 2, 3]"

b = np.array([[1,2,3],[4,5,6]])   # 二维Numpy数组
print(b.shape)                     # Prints "(2, 3)"
print(b[0, 0], b[0, 1], b[1, 0])   # Prints "1 2 4"
<class 'numpy.ndarray'>
(3,)
1 2 3
[5 2 3]
(2, 3)
1 2 4
  • 生成一些特殊的Numpy数组(矩阵)时,我们有特定的函数可以调用:
a = np.zeros((2,2))  # 全0的2*2 Numpy数组
print(a)              # Prints "[[ 0.  0.]
                     #          [ 0.  0.]]"

b = np.ones((1,2))   # 全1 Numpy数组
print(b)              # Prints "[[ 1.  1.]]"

c = np.full((2,2), 7) # 固定值Numpy数组
print(c)               # Prints "[[ 7.  7.]
                      #          [ 7.  7.]]"
d = np.eye(2)        # 2*2 对角Numpy数组
print(d)              # Prints "[[ 1.  0.]
                     #          [ 0.  1.]]"

e = np.random.random((2,2)) # 2*2 的随机Numpy数组
print(e)                     # 随机输出
[[0. 0.]
 [0. 0.]]
[[1. 1.]]
[[7 7]
 [7 7]]
[[1. 0.]
 [0. 1.]]
[[0.38227831 0.01159011]
 [0.57602631 0.43452925]]

Numpy数组索引与取值

可以通过像list一样的分片/slicing操作取出需要的数值部分。

# 创建如下的3*4 Numpy数组
# [[ 1  2  3  4]
#  [ 5  6  7  8]
#  [ 9 10 11 12]]
a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])

# 通过slicing取出前两行的2到3列:
# [[2 3]
#  [6 7]]
b = a[:2, 1:3]#取出前两行和两列
print(b)

# 需要注意的是取出的b中的数据实际上和a的这部分数据是同一份数据.
print (a[0, 1])   # Prints "2"
b[0, 0] = 77    # b[0, 0] 和 a[0, 1] 是同一份数据
print (a[0, 1])   # a也被修改了,Prints "77"
[[2 3]
 [6 7]]
2
77
a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])

row_r1 = a[1, :]    # a 的第二行  
row_r2 = a[1:2, :]  # 同上
print row_r1, row_r1.shape  # Prints "[5 6 7 8] (4,)"
print row_r2, row_r2.shape  # Prints "[[5 6 7 8]] (1, 4)"

col_r1 = a[:, 1]
col_r2 = a[:, 1:2]
print col_r1, col_r1.shape  # Prints "[ 2  6 10] (3,)"
print col_r2, col_r2.shape  # Prints "[[ 2]
                            #          [ 6]
                            #          [10]] (3, 1)"
[5 6 7 8] (4L,)
[[5 6 7 8]] (1L, 4L)
[ 2  6 10] (3L,)
[[ 2]
 [ 6]
 [10]] (3L, 1L)
  • 还可以这么着取:
a = np.array([[1,2], [3, 4], [5, 6]])

# 取出(0,0) (1,1) (2,0)三个位置的值
print a[[0, 1, 2], [0, 1, 0]]  # Prints "[1 4 5]"

# 和上面一样
print np.array([a[0, 0], a[1, 1], a[2, 0]])  # Prints "[1 4 5]"

# 取出(0,1) (0,1) 两个位置的值
print a[[0, 0], [1, 1]]  # Prints "[2 2]"

# 同上
print np.array([a[0, 1], a[0, 1]])  # Prints "[2 2]"
[1 4 5]
[1 4 5]
[2 2]
[2 2]
  • 我们还可以通过条件得到bool型的Numpy数组结果,再通过这个数组取出符合条件的值,如下:
a = np.array([[1,2], [3, 4], [5, 6]])

bool_idx = (a > 2)  # 判定a大于2的结果矩阵

print(bool_idx)      # Prints "[[False False]
                    #          [ True  True]
                    #          [ True  True]]"

# 再通过bool_idx取出我们要的值
print(a[bool_idx])  # Prints "[3 4 5 6]"

# 放在一起我们可以这么写
print(a[a > 2])     # Prints "[3 4 5 6]"
[[False False]
 [ True  True]
 [ True  True]]
[3 4 5 6]
[3 4 5 6]
  • Numpy数组的类型
x = np.array([1, 2])  
print x.dtype         # Prints "int64"

x = np.array([1.0, 2.0]) 
print x.dtype             # Prints "float64"

x = np.array([1, 2], dtype=np.int64)  # 强制使用某个type
print x.dtype                         # Prints "int64"
int32
float64
int64

Numpy数组的运算

x = np.array([[1,2],[3,4]], dtype=np.float64)
y = np.array([[5,6],[7,8]], dtype=np.float64)

# [[ 6.0  8.0]
#  [10.0 12.0]]

print ('x+y的值是:\n',np.add(x, y))

# [[-4.0 -4.0]
#  [-4.0 -4.0]]


print('x-y的值是:\n',np.subtract(x, y))

# 元素对元素,点对点的乘积
# [[ 5.0 12.0]
#  [21.0 32.0]]

print('x点乘y的值是:\n',np.multiply(x, y))

# 元素对元素,点对点的除法
# [[ 0.2         0.33333333]
#  [ 0.42857143  0.5       ]]


print('x点除y的值是:\n',np.divide(x, y))

# 开方
# [[ 1.          1.41421356]
#  [ 1.73205081  2.        ]]
print('x进行开方的值是:\n',np.sqrt(x))
x+y的值是:
 [[ 6.  8.]
 [10. 12.]]
x-y的值是:
 [[-4. -4.]
 [-4. -4.]]
x点乘y的值是:
 [[ 5. 12.]
 [21. 32.]]
x点除y的值是:
 [[0.2        0.33333333]
 [0.42857143 0.5       ]]
x进行开方的值是:
 [[1.         1.41421356]
 [1.73205081 2.        ]]
  • 矩阵的内积是通过下列方法计算的:
x = np.array([[1,2],[3,4]])
y = np.array([[5,6],[7,8]])

v = np.array([9,10])
w = np.array([11, 12])

# 向量内积,得到 219

print(np.dot(v, w))

# 矩阵乘法,得到 [29 67]

print(np.dot(x, v))

# 矩阵乘法
# [[19 22]
#  [43 50]]

print(np.dot(x, y))
219
[29 67]
[[19 22]
 [43 50]]
  • 特别特别有用的一个操作是,sum/求和(对某个维度):
x = np.array([[1,2],[3,4]])

print(np.sum(x))  # 整个矩阵的和,得到 "10"
print(np.sum(x, axis=0))  # 每一列的和 得到 "[4 6]"
print(np.sum(x, axis=1))  # 每一行的和 得到 "[3 7]"
10
[4 6]
[3 7]
  • 还有一个经常会用到操作是矩阵的转置,在Numpy数组里用.T实现:
x = np.array([[1,2], [3,4]])
print(x)    # Prints "[[1 2]
           #          [3 4]]"
    
print(x.T)  # Prints "[[1 3]
           #          [2 4]]"

# 1*n的Numpy数组,用.T之后其实啥也没做:
v = np.array([1,2,3])
print(v)    # Prints "[1 2 3]"
print(v.T)  # Prints "[1 2 3]"
[[1 2]
 [3 4]]
[[1 3]
 [2 4]]
[1 2 3]
[1 2 3]

Broadcasting

Numpy还有一个非常牛逼的机制,你想想,如果你现在有一大一小俩矩阵,你想使用小矩阵在大矩阵上做多次操作。额,举个例子好了,假如你想将一个1n的矩阵,加到mn的矩阵的每一行上:

#你如果要用for循环实现是酱紫的(下面用y的原因是,你不想改变原来的x)

x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
v = np.array([1, 0, 1])
y = np.empty_like(x)   # 设置一个和x一样维度的Numpy数组y

# 逐行相加
for i in range(4):
    y[i, :] = x[i, :] + v

# 恩,y就是你想要的了
# [[ 2  2  4]
#  [ 5  5  7]
#  [ 8  8 10]
#  [11 11 13]]
print(y)
[[ 2  2  4]
 [ 5  5  7]
 [ 8  8 10]
 [11 11 13]]
#上一种方法如果for的次数非常多,会很慢,于是我们改进了一下
import numpy as np

x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
v = np.array([1, 0, 1])
vv = np.tile(v, (4, 1))  # 变形,重复然后叠起来
print(vv)                 # Prints "[[1 0 1]
                         #          [1 0 1]
                         #          [1 0 1]
                         #          [1 0 1]]"
y = x + vv  # 相加
print(y)  # Prints "[[ 2  2  4
         #          [ 5  5  7]
         #          [ 8  8 10]
         #          [11 11 13]]"
[[1 0 1]
 [1 0 1]
 [1 0 1]
 [1 0 1]]
[[ 2  2  4]
 [ 5  5  7]
 [ 8  8 10]
 [11 11 13]]
#其实因为Numpy的Broadcasting,你可以直接酱紫操作

x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
v = np.array([1, 0, 1])
y =x + v  # 直接加!!!
print(y)  # Prints "[[ 2  2  4]
         #          [ 5  5  7]
         #          [ 8  8 10]
         #          [11 11 13]]"
[[ 2  2  4]
 [ 5  5  7]
 [ 8  8 10]
 [11 11 13]]
#更多Broadcasting的例子请看下面:
v = np.array([1,2,3])  # v has shape (3,)
w = np.array([4,5])    # w has shape (2,)
# 首先把v变成一个列向量
# v现在的形状是(3, 1);
# 作用在w上得到的结果形状是(3, 2),如下
# [[ 4  5]
#  [ 8 10]
#  [12 15]]
print(np.reshape(v, (3, 1)) * w)

# 逐行相加
x = np.array([[1,2,3], [4,5,6]])
# 得到如下结果:
# [[2 4 6]
#  [5 7 9]]
print(x + v)

# 先逐行相加再转置,得到以下结果:
# [[ 5  6  7]
#  [ 9 10 11]]
print((x.T + w).T)
# 恩,也可以这么做
print(x + np.reshape(w, (2, 1)))
[[ 4  5]
 [ 8 10]
 [12 15]]
[[2 4 6]
 [5 7 9]]
[[ 5  6  7]
 [ 9 10 11]]
[[ 5  6  7]
 [ 9 10 11]]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安替-AnTi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值