Numpy

Numpy知识点总结

2019-02-23  本文已影响39人  EL33
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

一、创建ndarray

1.1 通过列表和内置函数创建

# 通过列表创建
np.array([[2,3,4],[5,6,7]])
# 通过内置函数创建
np.arange(0,10,2)    # 和Python里面的range一样,创建一个一维数组
np.zeros((2,3))    # 创建一个全0的 2×3 数组
np.ones((2,3),'int32')    # 创建一个 2×3 的全1的数组,并且改变数组元素类型为 int32
np.full((2,3),10,'int64')    # 创建一个 2×3 的指定数(这里为10)的数组,改变数组元素类型为 int64
np.empty((2,3))    # 创建一个 2×3 的空数组,只分配内存,但不填充,返回未被初始化的垃圾值
np.eye(5)    # 创建一个单位矩阵数组
array([[1., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 0., 0., 1., 0.],
       [0., 0., 0., 0., 1.]])

1.2 通过random函数创建

1.2.1 均匀分布

均匀分布也叫 矩形分布,它是对称概率分布,在相同长度间隔的分布概率是等可能的。
均匀分布由两个参数a和b定义,它们是数轴上的最小值和最大值,通常缩写为U(a,b)。

# 通过random函数创建
np.random.random((2,3))    # 服从均匀分布U(0,1),构建2×3的数组
array([[0.5191731 , 0.97337981, 0.43615165],
       [0.26726161, 0.868919  , 0.1627226 ]])
np.random.rand(2,3) # 同上面的
array([[0.27252121, 0.09276636, 0.17518565],
       [0.3519029 , 0.7170142 , 0.33306299]])

1.2.2 随机等概率

np.random.randint(0,10,(3,3))    # 随机等概率的抽取 0-9范围内的整数,构建3×3的数组
array([[0, 4, 3],
       [1, 0, 2],
       [5, 5, 0]])

1.2.3服从正态分布的两个随机函数

标准正态。分布期望值μ=0,即曲线图象对称轴为Y轴,标准差σ=1条件下的正态分布,记为N(0,1)。

# 标准正态分布 N(0,1)
np.random.randn(2,3)
array([[ 1.43797336,  1.2564011 , -1.98322929],
       [ 0.21843254,  1.36461946, -0.92210014]])
# 正态分布 N(μ,σ^2)
np.random.normal(10,2,(2,3))
array([[ 7.7503975 ,  9.37959585, 11.31247388],
       [ 9.34024262, 11.74541123, 10.66043646]])

二、查看ndarray的信息

arr1 = np.random.randint(0,100,(10,10))
arr1
array([[86, 11, 50, 13, 86, 79, 72, 44, 71, 81],
       [ 5, 89, 74, 23, 39, 67, 72, 23,  3, 15],
       [50, 30, 68, 36, 49, 25, 64, 96, 33, 68],
       [92, 41, 13, 96,  7, 20, 15, 45,  7, 46],
       [70, 94, 15, 47, 58, 41, 80, 77, 37, 27],
       [76, 37, 33, 31, 93, 71, 93,  8, 92, 59],
       [72, 70, 65, 88, 78, 31, 52, 30, 78, 43],
       [79, 22, 15, 62, 53, 67, 84, 18, 96, 95],
       [14, 22, 99,  2, 60, 52, 64, 39,  9,  6],
       [20, 78, 30, 50, 86, 65,  4, 48, 10, 89]])
arr1.shape    # 查看数组形状
(10, 10)
arr1.ndim   # 查看数组维度
2
arr1.size    # 查看数组大小
100
arr1.dtype    # 查看数组元素的类型
dtype('int64')
arr1.astype(np.float32)    # 修改数组元素的类型,但是注意并不改变原有数组
array([[86., 11., 50., 13., 86., 79., 72., 44., 71., 81.],
       [ 5., 89., 74., 23., 39., 67., 72., 23.,  3., 15.],
       [50., 30., 68., 36., 49., 25., 64., 96., 33., 68.],
       [92., 41., 13., 96.,  7., 20., 15., 45.,  7., 46.],
       [70., 94., 15., 47., 58., 41., 80., 77., 37., 27.],
       [76., 37., 33., 31., 93., 71., 93.,  8., 92., 59.],
       [72., 70., 65., 88., 78., 31., 52., 30., 78., 43.],
       [79., 22., 15., 62., 53., 67., 84., 18., 96., 95.],
       [14., 22., 99.,  2., 60., 52., 64., 39.,  9.,  6.],
       [20., 78., 30., 50., 86., 65.,  4., 48., 10., 89.]], dtype=float32)
arr1.dtype    # 可以看到原有数组元素类型并没有改变
dtype('int64')
arr1.reshape(4,25)    # 重构数组的形状,也是不改变原有数组
array([[86, 11, 50, 13, 86, 79, 72, 44, 71, 81,  5, 89, 74, 23, 39, 67,
        72, 23,  3, 15, 50, 30, 68, 36, 49],
       [25, 64, 96, 33, 68, 92, 41, 13, 96,  7, 20, 15, 45,  7, 46, 70,
        94, 15, 47, 58, 41, 80, 77, 37, 27],
       [76, 37, 33, 31, 93, 71, 93,  8, 92, 59, 72, 70, 65, 88, 78, 31,
        52, 30, 78, 43, 79, 22, 15, 62, 53],
       [67, 84, 18, 96, 95, 14, 22, 99,  2, 60, 52, 64, 39,  9,  6, 20,
        78, 30, 50, 86, 65,  4, 48, 10, 89]])

三、索引操作

3.1 切片索引

arr2 = np.arange(1,10).reshape(3,3)
arr2
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
arr2[2][:2]    # 先取第 3 行,然后对第三行里面的索引为0,1的列切片
array([7, 8])
arr2[1:3,:2]     # arr2 [行切片,列切片],获取行下标从0到2,列下标0到1的内容
array([[4, 5],
       [7, 8]])

切片说明
list [x:y:z] 从索引x开始取,到索引为y为止,但不包括y,取值步长为z

需要注意的是,数组切片是原始数组的视图。视图上的任何修改都会直接反映到源数组上。

arr2[0][0] = 666
print(arr2)
[[666   2   3]
 [  4   5   6]
 [  7   8   9]]

当你将一个标量值赋值给一个切片时,该值会自动传播(也就说后面将会讲到的“广播”)到整个选区。

arr2[1:3,1:3] = 999
print(arr2)
arr2 = np.arange(1,10).reshape(3,3)    # 为避免影响后面的内容,将arr2还原
[[666   2   3]
 [  4 999 999]
 [  7 999 999]]

当你要得到独立的原始数据副本而不是视图的时候,你可以使用copy()

s = arr2[1:3,1:3].copy()
s[:,:] = 888
print(arr2)
print(s)
[[1 2 3]
 [4 5 6]
 [7 8 9]]
[[888 888]
 [888 888]]

并不是单纯的深复制和浅复制

3.2 花式索引

arr2
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
# 针对行的花式索引,取出顺序与索引顺序一致
arr2[[2,1,0]]    # 这里将本来0,1,2的索引顺序取值为2,1,0
array([[7, 8, 9],
       [4, 5, 6],
       [1, 2, 3]])
# 针对列的花式索引,同上
arr2[:,[2,1,0]]
array([[3, 2, 1],
       [6, 5, 4],
       [9, 8, 7]])
# 花式索引取单个值
arr2[[1,2],[0,1]]    # arr2[行,列] 取(1,0)、(2,1)对应位置的值 
array([4, 8])

3.3布尔型索引

arr2 > 4    # 直接比较元素的值,生成一个True和False的ndarray对象
array([[False, False, False],
       [False,  True,  True],
       [ True,  True,  True]])

可以将这个ndarray对象做为索引来取其中为True的值

arr3 = arr2[arr2>4]    # 取arr2中大于4的元素,但是会失去数组的形状
print(arr3)
print(type(arr3))
print(arr3.shape)
[5 6 7 8 9]
<class 'numpy.ndarray'>
(5,)
arr2[~(arr2 > 4)]    # 对bool值索引取反
array([1, 2, 3, 4])

四、数组计算

Numpy的矢量化(vectorization)使得你不用编写循环就可以对数据进行批量运算。大小相等的数组之间的任何算术运算都会将运算应用到元素级。

4.1 基础计算

对应的+、-、*、/ 直接用,会应用到元素级对应的加减乘除,无需赘述

arr2 * arr2    #同shape直接运算
array([[ 1,  4,  9],
       [16, 25, 36],
       [49, 64, 81]])
arr2 * arr1    # 不同shape的运算会这样(不是矩阵运算) 
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-31-77c6c3c81a3a> in <module>()
----> 1 arr2 * arr1    # 不同shape的运算会这样(不是矩阵运算)


ValueError: operands could not be broadcast together with shapes (3,3) (10,10) 

数组与标量之间的运算也是同样将标量“广播”到各个元素

arr2 * 10    # 将arr2每个元素对应的乘10
array([[10, 20, 30],
       [40, 50, 60],
       [70, 80, 90]])
1/arr2    # 对arr2每个元素求倒数
array([[1.        , 0.5       , 0.33333333],
       [0.25      , 0.2       , 0.16666667],
       [0.14285714, 0.125     , 0.11111111]])
arr2**0.5    # 对arr2每个元素开方
array([[1.        , 1.41421356, 1.73205081],
       [2.        , 2.23606798, 2.44948974],
       [2.64575131, 2.82842712, 3.        ]])

4.2 数组比较

同shape数组之间的比较会生成bool、型数组

arr4 = np.random.randint(1,20,arr2.shape)
arr4
array([[18,  6, 17],
       [18,  8, 13],
       [15, 13,  4]])
arr4 > arr2
array([[ True,  True,  True],
       [ True,  True,  True],
       [ True,  True, False]])

不同大小的数组之间的运算叫做广播(broadcasting),后面介绍

4.3通用函数

4.3.1 一元函数:只需要一个参数

arr3
array([5, 6, 7, 8, 9])
np.abs(arr3*-1)    # 绝对值
array([5, 6, 7, 8, 9])
np.sqrt(arr3)    # 开方
array([2.23606798, 2.44948974, 2.64575131, 2.82842712, 3.        ])
np.square(arr3)    # 平方
array([25, 36, 49, 64, 81])
np.exp(arr3)    # 指数函数,y=e^x函数
array([ 148.4131591 ,  403.42879349, 1096.63315843, 2980.95798704,
       8103.08392758])
# 对数函数
np.log(arr2)
np.log2(arr2)
np.log10(arr2)
array([[0.        , 0.30103   , 0.47712125],
       [0.60205999, 0.69897   , 0.77815125],
       [0.84509804, 0.90308999, 0.95424251]])
# 三角函数
np.sin(arr2)
np.cos(arr2)
np.tan(arr2)
np.tanh(arr2)    # 双弦正切
array([[0.76159416, 0.96402758, 0.99505475],
       [0.9993293 , 0.9999092 , 0.99998771],
       [0.99999834, 0.99999977, 0.99999997]])
print(arr2/3)
np.modf(arr2 / 3)    # 将数组元素的整数和小数部分拆分,返回两个数组
[[0.33333333 0.66666667 1.        ]
 [1.33333333 1.66666667 2.        ]
 [2.33333333 2.66666667 3.        ]]





(array([[0.33333333, 0.66666667, 0.        ],
        [0.33333333, 0.66666667, 0.        ],
        [0.33333333, 0.66666667, 0.        ]]), array([[0., 0., 1.],
        [1., 1., 2.],
        [2., 2., 3.]]))
np.isnan(arr2)    # 判断是否有缺失
array([[False, False, False],
       [False, False, False],
       [False, False, False]])
np.isinf(arr2)    # 判断是否无穷
array([[False, False, False],
       [False, False, False],
       [False, False, False]])

4.3.2 二元函数

二元函数的第二个参数可以是标量,也可以是数组(同shape)

np.add(arr2,arr2)    # 加
np.subtract(arr2,arr2)    # 减
np.multiply(arr2,arr2)    # 乘
np.divide(arr2,arr2)    # 除
np.mod(arr2,arr2)    # 取余数
np.power(arr2,3)    # 开方
array([[  1,   8,  27],
       [ 64, 125, 216],
       [343, 512, 729]])

4.4 线性代数

arr2.T    # 转置
array([[1, 4, 7],
       [2, 5, 8],
       [3, 6, 9]])
np.dot(arr2,arr4)    # 矩阵内积
array([[ 99,  61,  55],
       [252, 142, 157],
       [405, 223, 259]])
np.diag(arr2)    # 取对角线的元素
array([1, 5, 9])
np.trace(arr2)    # 求迹(对角线元素之和)
15
np.linalg.det(arr2)    # 求方阵的行列式
6.66133814775094e-16
np.linalg.matrix_rank(arr2)    # 求矩阵的秩
2
np.linalg.eig(arr2)    # 求方阵的特征值和特征向量
(array([ 1.61168440e+01, -1.11684397e+00, -1.30367773e-15]),
 array([[-0.23197069, -0.78583024,  0.40824829],
        [-0.52532209, -0.08675134, -0.81649658],
        [-0.8186735 ,  0.61232756,  0.40824829]]))
np.linalg.inv(arr2)    # 求满秩方阵的逆
array([[-4.50359963e+15,  9.00719925e+15, -4.50359963e+15],
       [ 9.00719925e+15, -1.80143985e+16,  9.00719925e+15],
       [-4.50359963e+15,  9.00719925e+15, -4.50359963e+15]])
np.linalg.pinv(arr2)    # 求伪逆
array([[-6.38888889e-01, -1.66666667e-01,  3.05555556e-01],
       [-5.55555556e-02, -2.60208521e-16,  5.55555556e-02],
       [ 5.27777778e-01,  1.66666667e-01, -1.94444444e-01]])
np.linalg.svd(arr2)    # svd矩阵分解
(array([[-0.21483724,  0.88723069,  0.40824829],
        [-0.52058739,  0.24964395, -0.81649658],
        [-0.82633754, -0.38794278,  0.40824829]]),
 array([1.68481034e+01, 1.06836951e+00, 1.47280825e-16]),
 array([[-0.47967118, -0.57236779, -0.66506441],
        [-0.77669099, -0.07568647,  0.62531805],
        [ 0.40824829, -0.81649658,  0.40824829]]))

五、数据处理

5.1 条件判断

np.where(1>0,arr2,arr4)    
# 判断为真输出arr2,为假输出arr4,可嵌套。arr2和arr4有相同的shape
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

5.2查看唯一值

np.unique(arr2)  
array([1, 2, 3, 4, 5, 6, 7, 8, 9])

5.3 排序

-arr2
array([[-1, -2, -3],
       [-4, -5, -6],
       [-7, -8, -9]])
arr5 = -np.sort(-arr2)    # 排逆序
print(arr5)
[[3 2 1]
 [6 5 4]
 [9 8 7]]
np.sort(arr5,axis=1)    # 排序,axis默认为0方向(列方向)
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

5.4判断元素存在性

np.in1d(arr2,[1,2,3])    
#判断数组的元素是否在后一个list-like(ndarray-like)里面
array([ True,  True,  True, False, False, False, False, False, False])

六、持久化

6.1 二进制格式

np.save('path/name.npy',arr2)    # 保存arr2到本地
np.load('path/name.npy')    # 载入
np.savez('path/name/npz',a=arr1,b=arr2)    
# 保存多个数组,读的时候也是一样的方式

6.2 文本格式

np.savetxt('path/name.txt',arr2,delimiter=',')
# 保存为文本格式,delimiter=','为用','将列隔开
np.loadtxt('path/name.txt',delimter=',')
# 读取文本文件
上一篇下一篇

猜你喜欢

热点阅读