Numpy学习笔记

目录

  • 数组简介和数组的构造(ndarray)
  • 数组取值与赋值
  • 数学运算
  • Broadcasting(广播)
  • 逻辑运算
  • 数组高级操作
  • 文件输入输出
  • 随堂练习:用numpy写一个softmax

数组简介和数组的构造(ndarray)

ndarray = n dimensional array

import numpy as np

b = np.array([[1,2,3], [2,3,4]])
print(b)
[[1 2 3]
 [2 3 4]]
 
print(b.shape)
(2, 3)

a = np.zeros((2,3))
print(a)
[[ 0.  0.  0.]
 [ 0.  0.  0.]]

b = np.ones((1,2))
print(b)
[[ 1.  1.]]

c = np.full((2,2), 8)
print(c)
[[8 8]
 [8 8]]

d = np.eye(3)
print(d)
[[ 1.  0.  0.]
 [ 0.  1.  0.]
 [ 0.  0.  1.]]

g = np.arange(15)
print(g)
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14]

arr = np.array([1,2,3])
print(arr.dtype)
int32

arr = np.array([1,2,3], dtype=np.float64)
print(arr.dtype)
float64

int_arr = np.array([1,2,3,4,5])
print(int_arr, int_arr.dtype)
[1 2 3 4 5] int32

float_arr = int_arr.astype(np.float64)
print(float_arr.dtype, float_arr)
float64 [ 1.  2.  3.  4.  5.]

int_arr = np.arange(10)
float_arr = np.array([2.3,4.6,9.8])
print(float_arr.dtype, int_arr.dtype)
float64 int32

int_arr.astype(dtype=float_arr.dtype)
array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.])

数组取值与赋值

import numpy as np

a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])

b = a[1, :2]	# [行, 列]
print(b)
[5 6]

b = a[0:2,2:4]
print(b)
[[3 4]
 [7 8]]

b[0,0] = 111111
print(b)
[[111111      4]
 [     7      8]]
 print(a)	# a也会变!! 因为numpy是引用
 [[     1      2 111111      4]
 [     5      6      7      8]
 [     9     10     11     12]]
 # 最好切片的时候 b = a[0:2,2:4].copy()

a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
row_r1 = a[0, ]
print(row_r1, row_r1.shape)
[1 2 3 4] (4,)
row_r2 = a[0:1]	# X到X会多内嵌一维
print(row_r2, row_r2.shape)
[[1 2 3 4]] (1, 4)
row_r3 = a[[0], :]
print(row_r3, row_r3.shape)
[[1 2 3 4]] (1, 4)

col_r1 = a[:, 1]
print(col_r1, col_r1.shape)
[ 2  6 10] (3,)
col_r2 = a[:, 1:2]
print(col_r2, col_r2.shape)
[[ 2]
 [ 6]
 [10]] (3, 1)

a = np.array([[1,2], [3, 4], [5, 6]])
b = a[[0,1,2], [0,1,0]]	# 取出[0, 0], [1, 1], [2, 0]
print(a)
[[1 2]
 [3 4]
 [5 6]]
print(b, b.shape)
[1 4 5] (3,)
print(np.array([a[0, 0], a[1, 1], a[2, 0]]))# 先取出这三个数,构成list,再变为ndarray
[1 4 5]

a = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
print(a)
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]

b = np.array([0, 2, 0, 1])
print(a[np.arange(4), b])	# 行0-3,列[0, 2, 0, 1],坐标[0, 0], [1, 2], [2, 0], [3, 1]
[ 1,  6,  7, 11]

a[np.arange(4), b] += 10	# 元素操作
print(a)
[[11  2  3]
 [ 4  5 16]
 [17  8  9]
 [10 21 12]]

# 用条件判定取值
a = np.array([[1,2], [3, 4], [5, 6]])
print(a)
[[1 2]
 [3 4]
 [5 6]]
bool_index = (a > 2)
print(bool_index)
[[False False]
 [ True  True]
 [ True  True]]
# 用布尔型数组作为下标就可以取出符合条件的元素了
print(a[bool_index])
[3 4 5 6]
# 其实一句话就行
print(a[a>2])
[3 4 5 6]

在这里插入图片描述
在这里插入图片描述

数学运算

import numpy as np

x = np.array([[1,2],[3,4]], dtype=np.float64)
y = np.array([[5,6],[7,8]], dtype=np.float64)
print(x)			print(y)
[[ 1.  2.]			[[ 5.  6.]				
 [ 3.  4.]]          [ 7.  8.]]
# 加法1) x+y
(2) np.add(x,y)
array([[  6.,   8.],
       [ 10.,  12.]])

# 减法1) x-y
(2) np.subtract(x,y)
array([[-4., -4.],
       [-4., -4.]])

# 乘法1) x*y
(2) np.multiply(x,y)
array([[  5.,  12.],
       [ 21.,  32.]])

# 除法1) x/y
(2) np.divide(x, y)
array([[ 0.2       ,  0.33333333],
       [ 0.42857143,  0.5       ]])

# 平方根
np.sqrt(x)
array([[ 1.        ,  1.41421356],
       [ 1.73205081,  2.        ]])

# 向量内积
v = np.array([9,10])
w = np.array([10,11])1) v.dot(w)2) np.dot(v,w)
200

# 矩阵乘法
x = np.array([[1,2], [3,4]])
y = np.array([[5,6], [7,8]])1) x.dot(y)2) np.dot(x,y)
array([[19, 22],
       [43, 50]])

# v = np.array([9,10])	# 一维可看成行向量又可以看成列向量,此处为满足矩阵乘法为列向量(2x1)1) x.dot(v)2) np.dot(x, v)
array([29, 67])	

# 转置(与数学相同)
x.T
array([[1, 3],
       [2, 4]])
# 一维向量转置就是本身
v.T
array([9, 10])
# 二维不同
w = np.array([[1,2,3]])
print(w, w.shape)
[[1 2 3]] (1, 3)
print(w.T)
[[1]
 [2]
 [3]]

# 高维数组(tensor)
# 例:
f = np.random.randn(2,3,4)	# 总共两大块,每大块里三小块,每小块四元素
print(f)
[[[ 0.03866615 -1.07901707  0.16366115 -0.53048756]
  [-0.81813884 -0.53505294  0.82491683 -1.09155967]
  [ 0.82251694 -0.05660042 -0.7786442   0.61981324]]

 [[ 1.41040236 -1.04999785 -0.36338812 -0.4984866 ]
  [-0.56534221 -0.56177563  0.78985078 -1.47727231]
  [-1.28708395 -0.33997327  0.63821361 -0.52293797]]]
  
# (1) transpose()
arr = np.arange(16).reshape(2,2,4)
print(arr)
[[[ 0  1  2  3]
  [ 4  5  6  7]]
  
 [[ 8  9 10 11]
  [12 13 14 15]]]

print(arr.transpose((1,0,2)))	# 还是(2, 2, 4)的矩阵
'''
transpose()将索引改变了,以数字9为例,9原本的索引是(1, 0, 1),
即第1大块中第0小块的第1个元素,经过transpose(1, 0, 2)后,
索引变为(0, 1, 1),即第0大块中第1小块的第1个元素,
如下所示,其他数字同理
'''
[[[ 0  1  2  3]
  [ 8  9 10 11]]

 [[ 4  5  6  7]
  [12 13 14 15]]]

print(arr.transpose((0,2,1)))	# (2, 4, 2)的矩阵
'''
以数字6为例,原本索引为(0, 1, 2),变为(0, 2, 1),
即第0大块,第2小块,第1个元素
'''
[[[ 0  4]
  [ 1  5]
  [ 2  6]
  [ 3  7]]

 [[ 8 12]
  [ 9 13]
  [10 14]
  [11 15]]]

print(arr.transpose((0,1,2)))	# (0, 1, 2)不变,索引就为(0, 1, 2),即第0维第1维第2维
[[[ 0  1  2  3]
  [ 4  5  6  7]]
  
 [[ 8  9 10 11]
  [12 13 14 15]]]

# (2) swapaxes()
print(arr.swapaxes(1,2))	# 和transpose(0, 2, 1)相同,即第1维与第2维互换
[[[ 0  4]
  [ 1  5]
  [ 2  6]
  [ 3  7]]

 [[ 8 12]
  [ 9 13]
  [10 14]
  [11 15]]]

# 张量乘法
x = np.arange(24).reshape(2,3,4)
y = np.arange(8).reshape(4,2)

print(np.matmul(x,y).shape)
(2, 3, 2)	# 即2x3x4  x  4x2,与矩阵乘法类似,最后一维消掉得2x3x2
print(np.dot(x,y).shape)
(2, 3, 2)

# matmul()与dot()区别
x = np.arange(24).reshape(2,3,4)
y = np.arange(16).reshape(2,4,2)
print(x.dot(y).shape)
(2, 3, 2, 2)	# 将2x3x4中的4与2x4x2中的4消掉,得2x3x2x2
print(np.matmul(x,y).shape)
(2, 3, 2)

# 矩阵内运算
# sum
x= np.array([[1,2], [3,4]])
[[1 2]
 [3 4]]1) np.sum(x
(2) x.sum()
10
print(np.sum(x, axis=0))	# 对第0维求和
[4 6]
print(np.sum(x, axis=1))	# 对第1维求和
[3, 7]

print(x.cumsum(axis=0))			print(x.cumsum(axis=1))
[[1 2]							[[1 3]
 [4 6]]							 [3 7]]

# mean(平均)
print(np.mean(x))
print(np.mean(x, axis=0))
print(np.mean(x, axis=1))
2.5
[ 2.  3.]
[ 1.5  3.5]

# 找出排序后5%的数字
large_arr = np.random.randn(1000)
large_arr.sort()
print(large_arr[int(0.05 * len(large_arr))])
-1.71556330464

Broadcasting(广播)

如果要用小矩阵去和大矩阵做一些操作,但是希望小矩阵能循环和大矩阵的那些块做一样的操作,那就需要用broadcasting

# 给x的每一行都逐元素加上一个向量,然后生成y
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)
# (1) for循环
for i in range(4):
    y[i,:] = x[i,:] + v		# y的i行等于x的i行加上v
    
print(y)
[[ 2  2  4]
 [ 5  5  7]
 [ 8  8 10]
 [11 11 13]]
# 直接加
print(x + v)
[[ 2,  2,  4],
 [ 5,  5,  7],
 [ 8,  8, 10],
 [11, 11, 13]]
'''
当操作两个array时,numpy会逐个比较它们的shape,
在下述情况下,两arrays会兼容和输出broadcasting结果:
1. 相等
2. 其中一个为1,(进而可进行拷贝拓展已至,shape匹配)

比如求和的时候有:
'''
Image (3d array):  256 x 256 x 3
Scale (1d array):              3
Result (3d array): 256 x 256 x 3
# 3相等,只要把3拓展成256x256x3即可

A      (4d array):  8 x 1 x 6 x 1
B      (3d array):      7 x 1 x 5
Result (4d array):  8 x 7 x 6 x 5
# 其中一个为1,取最大值即可

A      (2d array):  5 x 4
B      (1d array):      1
Result (2d array):  5 x 4

A      (2d array):  15 x 3 x 5
B      (1d array):  15 x 1 x 5
Result (2d array):  15 x 3 x 5


# 例子:
v = np.array([1,2,3])
w = np.array([4,5])
v = v.reshape(3,1)
v + w
array([[5, 6],			[[1+4, 1+5],
       [6, 7],			 [2+4, 2+5],					
       [7, 8]])			 [3+4, 3+5]]

x = np.array([[1,2,3], [4,5,6]]) # 2x3的
w = np.array([4,5]) # 2
(x.T + w).T		# x=3x2
array([[ 5,  6,  7],
       [ 9, 10, 11]])
x + np.reshape(w, (2,1))	# w=2x1
array([[ 5,  6,  7],
       [ 9, 10, 11]])

broadcasting总结:
在这里插入图片描述

逻辑运算

x_arr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
y_arr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
cond = np.array([True, False, True, True, False])
print(np.where(cond, x_arr, y_arr))	# True取x_arr,False取y_arr
[ 1.1  2.2  1.3  1.4  2.5]

arr = np.random.randn(4,4)
print(np.where(arr > 0, 1,-1))	# arr>0为True取1,否则为False取-1
[[ 1  1  1  1]
 [-1 -1  1 -1]
 [ 1 -1  1 -1]
 [-1 -1 -1  1]]

数组高级操作

arr = np.arange(15)
print(arr.reshape(5,3).shape)
print(arr.reshape(5,-1).shape)	# 如果我们在某一个维度上写上-1,numpy会帮我们自动推导出正确的维度
(5, 3)

# 高维数组可以用ravel来拉平
arr.ravel().shape
(15,)

# 连接两个数组
arr1 = np.array([[1, 2, 3], [4, 5, 6]])
arr2 = np.array([[7, 8, 9], [10, 11, 12]])
np.concatenate([arr1, arr2], axis=0)	# 先把arr1和arr2拼成一个list,再指定在第0维上拼到一起
array([[ 1,  2,  3],
       [ 4,  5,  6],
       [ 7,  8,  9],
       [10, 11, 12]])  
np.concatenate([arr1, arr2], axis=1)
array([[ 1,  2,  3,  7,  8,  9],
       [ 4,  5,  6, 10, 11, 12]])

np.vstack((arr1, arr2)) # vertical(垂直)
array([[ 1,  2,  3],
       [ 4,  5,  6],
       [ 7,  8,  9],
       [10, 11, 12]])
np.hstack((arr1, arr2)) # horizontal
array([[ 1,  2,  3,  7,  8,  9],
       [ 4,  5,  6, 10, 11, 12]])

# 拆分数组
arr = np.random.rand(5,5)
print(arr)
[[ 0.80642843  0.43253953  0.24511404  0.21328645  0.50991311]
 [ 0.19373378  0.72169396  0.05192132  0.1746048   0.69771988]
 [ 0.59689743  0.82253158  0.03346062  0.9002945   0.03960687]
 [ 0.06061257  0.27390675  0.19740262  0.76815388  0.02035703]
 [ 0.58031701  0.63341072  0.75286027  0.82066801  0.24301514]]

first, second, third = np.split(arr, [1,3], axis=0)	# 在第1个位置和第3个位置上截
print(first, '\n\n', second, '\n\n', third)
[[ 0.80642843  0.43253953  0.24511404  0.21328645  0.50991311]] 


 [[ 0.19373378  0.72169396  0.05192132  0.1746048   0.69771988]
 [ 0.59689743  0.82253158  0.03346062  0.9002945   0.03960687]] 


 [[ 0.06061257  0.27390675  0.19740262  0.76815388  0.02035703]
 [ 0.58031701  0.63341072  0.75286027  0.82066801  0.24301514]]

# 堆叠的一些方法
arr = np.arange(6)
arr1 = arr.reshape((3, 2))
arr2 = np.random.randn(3, 2)
# r_用于按行堆叠
print(np.r_[arr1, arr2])
[[ 0.          1.        ]
 [ 2.          3.        ]
 [ 4.          5.        ]
 [-0.60392123 -0.1769936 ]
 [ 0.46523138  0.71963034]
 [-0.51733042  1.50108329]]
# c_用于按列堆叠
print(np.c_[np.r_[arr1, arr2], arr])
[[ 0.          1.          0.        ]
 [ 2.          3.          1.        ]
 [ 4.          5.          2.        ]
 [-0.60392123 -0.1769936   3.        ]
 [ 0.46523138  0.71963034  4.        ]
 [-0.51733042  1.50108329  5.        ]]

# 使用repeat来重复
arr = np.arange(3)
print(arr)
[0 1 2]
print(arr.repeat(3))
[0 0 0 1 1 1 2 2 2]
print(arr.repeat([2,3,5]))
[0 0 1 1 1 2 2 2 2 2]

# 指定axis来重复
arr = np.random.rand(2,2)
print(arr.repeat(2, axis=0))
[[ 0.90063544  0.36862431  0.46734451]
 [ 0.90063544  0.36862431  0.46734451]
 [ 0.61467785  0.63962631  0.61288228]
 [ 0.61467785  0.63962631  0.61288228]]
print(arr.repeat(2, axis=1))
[[ 0.90063544  0.90063544  0.36862431  0.36862431  0.46734451  0.46734451]
 [ 0.61467785  0.61467785  0.63962631  0.63962631  0.61288228  0.61288228]]


# Tile: 贴瓷砖
print(np.tile(arr, 2))
[[ 0.9682022   0.99265567  0.9682022   0.99265567]
 [ 0.62174828  0.12614083  0.62174828  0.12614083]]
print(np.tile(arr, (2,3)))
[[ 0.9682022   0.99265567  0.9682022   0.99265567  0.9682022   0.99265567]
 [ 0.62174828  0.12614083  0.62174828  0.12614083  0.62174828  0.12614083]
 [ 0.9682022   0.99265567  0.9682022   0.99265567  0.9682022   0.99265567]
 [ 0.62174828  0.12614083  0.62174828  0.12614083  0.62174828  0.12614083]]

文件输入输出

# 读取csv文件作为数组
arr = np.loadtxt('array_ex.txt', delimiter=',')
print(arr)
[[ 0.580052  0.18673   1.040717  1.134411]
 [ 0.194163 -0.636917 -0.938659  0.124094]
 [-0.12641   0.268607 -0.695724  0.047428]
 [-1.484413  0.004176 -0.744203  0.005487]
 [ 2.302869  0.200131  1.670238 -1.88109 ]
 [-0.19323   1.047233  0.482803  0.960334]]

# 数组文件读写
arr = np.arange(50).reshape(2,5,5)
np.save('some_array', arr)
arr2 = np.load('some_array.npy')

# 多个数组打包
arr3 = np.arange(15).reshape(3,5)
np.savez("array_archive.npz", a=arr, b=arr2, c=arr3)
arch = np.load('array_archive.npz')
print(arch['a'])
print(arch['b'])
print(arch['c'])

用numpy做一个softmax

在这里插入图片描述

  • 计算exponential
  • 按行求和
  • 每一行都要除以计算的和
# 计算exponential
m = np.random.rand(10,10) * 10 + 1000
# np.exp(m)太大了,变成了inf
m_row_max = m.max(axis=1).reshape(10,1)	# 取出每一行最大的数
m = m - m_row_max
m_exp = np.exp(m)

# 按行求和
m_exp_row_sum = m_exp.sum(axis=1).reshape(10,1)

# 每一行都要除以计算的和
m_softmax = m_exp / m_exp_row_sum
print(m_softmax)

# 验证
print(m_softmax.sum(axis=1))
[ 1.  1.  1.  1.  1.  1.  1.  1.  1.  1.]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值