1. Jupyter Notebook、numpy的使用

一. Jupter Notebook中的魔法方法

%run的使用

  • 加载不在项目包中的文件
  • 项目中的包不使用%run, 使用python的import语法即可
1. %run  myscript/hello.py

2. hello("balabala")      # 这样就可以直接调用hello.py中的函数了

%timeit的使用

  • 会先自动 把程序重复执行一定次数, 程序执行时间太短就会循环更多次
  • 通过找到最快的3次循环, 得到程序执行的时间
1. %timeit  L = [i**2 for i in range(1000)]

结果:  1000 loops, best of 3: 515 µs per  loop

%time的使用

  • 不会把程序重复运行, 只执行一次得到程序的运行时间
  • cputime是计算机cpu和sys 计算所用时间的和
  • walltime是现实世界流逝的时间
  • 得到的时间是不稳定的
  • 在只需要知道大概的时间或者程序运行时间太长, 适用
1. %time L = [i**2 for i in range(1000)]

结果:  CPU times: user 452 µs, sys: 17 µs, total: 469 µs
       Wall time: 536 µs

如果想要测试整段代码, 可以使用%%

  • 举例
%%time
for e in [1,2,3,4,6]:
  print(e)


二. Numpy数据基础

np.array的使用

1. import numpy as np
2. nparr = np.array([i for i in range(10)])
3. nparr

out: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])


1. nparr[5]
out: 5


1. nparr[5]=100.0
2. nparr[5]
out: 100  

1. nparr.dtype
out: dtype('int64')     # 之前的100.0被 隐式地类型转换了

三. 创建Numpy数组和矩阵

  • 创建全零矩阵
1. np.zeros(10)    # 默认是浮点数类型
out: array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])

2. np.zeros(10, dtype=int)    # 可以指定为 int 类型
out: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

3. np.zeros((3,5))     # 传入元组 表示维度
out:array([[0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.]])

4. np.zeros(shape=(3,5), dtype=int)   # 3中其实省略了shape
out:array([[0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]])
  • 创建全一矩阵
1. np.ones((3,5))    # 用法和zeros一样
out: array([[1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1.]])
  • 创建全部都为指定值的矩阵
1. np.full((3,5), 666)    # 省略了参数名 np.full(shape=(3,5), full_value=666)
out:array([[666, 666, 666, 666, 666],
       [666, 666, 666, 666, 666],
       [666, 666, 666, 666, 666]])



# 这里 full_value是 666, out就会是int型, 如果给的是666.0, out就会是浮点型
  • np.arrange
1. np.arange(0,1,0.2)
out: array([0. , 0.2, 0.4, 0.6, 0.8])

# np.arange使用方法和python基础语法range一样, 得到前闭后开的数据集
# 但np.arange步长可以是浮点数, 二range只能是整数
  • np.linspace
1. np.linspace(0,20,10)
out:array([ 0.        ,  2.22222222,  4.44444444,  6.66666667,  8.88888889,
       11.11111111, 13.33333333, 15.55555556, 17.77777778, 20.        ])

# linspace  第三个参数是 得到的数据个数, 而非步长
  • np.random.randint
1. np.random.randint(0, 10, 10)   # 生成10个 0~10的随机数, 组成的向量
out:array([1, 8, 1, 4, 6, 8, 7, 1, 7, 1])


2. np.random.randint(4,8,size=(3,5))   # 生成3x5的随机矩阵
out:array([[7, 5, 4, 5, 5],
       [4, 6, 7, 6, 5],
       [5, 6, 6, 6, 7]])
       
3. np.random.seed(666)  # 指定随机种子
4. np.random.randint((4,8, size=(3,5))
out:array([[4, 6, 5, 6, 6],
       [6, 5, 6, 4, 5],
       [7, 6, 7, 4, 7]])

5. np.random.randint((4,8, size=(3,5))   # 在指定了随机种子后, 会生成一样的随机矩阵
out:array([[4, 6, 5, 6, 6],
       [6, 5, 6, 4, 5],
       [7, 6, 7, 4, 7]])
       

# 调试时, 希望重现 一样的随机矩阵, 这时需要用到np.random.seed

  • np.random.random
1. np.random.random()   # 生成0~1的 随机浮点数
out:0.2811684913927954

2. np.random.random(10)
out:array([0.46284169, 0.23340091, 0.76706421, 0.81995656, 0.39747625,
       0.31644109, 0.15551206, 0.73460987, 0.73159555, 0.8578588 ])

3. np.random.random((3,5))
out:array([[0.76741234, 0.95323137, 0.29097383, 0.84778197, 0.3497619 ],
       [0.92389692, 0.29489453, 0.52438061, 0.94253896, 0.07473949],
       [0.27646251, 0.4675855 , 0.31581532, 0.39016259, 0.26832981]])

4. np.random.normal()      # 符合正态分布,均值为0 , 方差为1 的随机浮点数 
out:0.7760516793129695


5. np.random.normal(10,100)    # 指定均值为10, 方差为100 
out:128.06359754812632


6. np.random.normal(0,1, (3,5))      # 均值0 方差1  size为3x5
out:array([[ 0.06102404,  1.07856138, -0.79783572,  1.1701326 ,  0.1121217 ],
       [ 0.03185388, -0.19206285,  0.78611284, -1.69046314, -0.98873907],
       [ 0.31398563,  0.39638567,  0.57656584, -0.07019407,  0.91250436]])

当对函数的参数不清楚时, 使用?

1. np.random.normal?   # 带上?  就会跳出 对应的文档

Docstring:
normal(loc=0.0, scale=1.0, size=None)   # loc均值   scale方差

Draw random samples from a normal (Gaussian) distribution.

The probability density function of the normal distribution, first
derived by De Moivre and 200 years later by both Gauss and Laplace
independently [2]_, is often called the bell curve because of
its characteristic shape (see the example below)............



2. help(np.random.normal)    
# 和使用?, 效果类似, 
# 但? 是为跳出一个小页面的说明文档
# help  会把说明文档 放在 out: 后面

四. Numpy数组和矩阵的基本操作

属性

In:x1 = np.arange(10)
In:x2 = np.arange(15).reshape(3,5)

In:x1.ndim
out: 1     # ndim表示矩阵 的维度

In:x2.ndim
out: 2


In:x1.shape
out: (10,)      # shape表示  矩阵是 多少x多少的

In:x2.shape
out: (3,5)


In:x1.size
out: 10       # size表示 矩阵中元素的个数

In:x2.size
out: 15

numpy.array 的数据访问

In:x2
out:array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])


In:x2[0][0]
out:0     # [][] 的访问方法  是可行的, 但不建议

In:x2[2,2]
out: 12   # 建议 [,]这样访问



# python切片的语法同样适用于np.array
In:x1
out: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In:x1[:4]
out: array([0, 1, 2, 3])



# 对于多维的访问 必须使用[,] 不能使用[][]

In: x2[:2][:3]
out: array([[0, 1, 2, 3, 4],       # 得到的不是 前两行的 前3列
       [5, 6, 7, 8, 9]])
       
In: x2[:2,:3]
out: array([[0, 1, 2],             # 得到了想要的结果
       [5, 6, 7]])



# 子矩阵的修改会 直接影响到父矩阵
# np.array中因为追求效率, 所以子矩阵是父矩阵的引用

In: subX = x2[:2,:3]
In: subX
out: array([[0, 1, 2],
       [5, 6, 7]])
       
In: subX[0,0] = 100000
In: subX
out: array([[100000,      1,      2],
       [     5,      6,      7]])


In: x2
out:array([[100000,      1,      2,      3,      4],
       [     5,      6,      7,      8,      9],
       [    10,     11,     12,     13,     14]])        # 可以看到父矩阵的[0,0]元素也改变了
       
# 同理, 父矩阵的元素改变, 子矩阵也会改变




# 如果想要子矩阵 与 父矩阵 不互相影响, 可以使用copy

In: subX = x2[:2, :3].copy()     # 这样子矩阵和父矩阵就不会相互影响了

reshape

In: x1.reshape(2,5)
out: array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])


# 想把 x1 变为10行, 有多少列  不清楚, 可以用-1代替
In: x1.reshape(10, -1)
out:array([[0],
       [1],
       [2],
       [3],
       [4],
       [5],
       [6],
       [7],
       [8],
       [9]])
       
       
       
In: x1.reshape(2, -1)   # 变为2 行, 多少列 不去管
out:array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])

五.Numpy数组(和矩阵)的合并与分割

合并

# 一维矩阵的合并
In:x = np.array([1,2,3])
In:y = np.array([3,2,1])

In:np.concatenate([x,y])
out:array([1, 2, 3, 3, 2, 1])

In:z = np.array([666,666,666])
In:np.concatenate([x,y,z])
out: array([  1,   2,   3,   3,   2,   1, 666, 666, 666])



# 二维矩阵  的合并
In: A = np.array([[1,2,3],
In:             [4,5,6]])
In: np.concatenate([A,A])     # 这里默认参数axis=0, 即拓展行数
out: array([[1, 2, 3],
       [4, 5, 6],
       [1, 2, 3],
       [4, 5, 6]])
       

In: np.concatenate([A,A], axis=1)   # 拓展列
out: array([[1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6]])
       
       

# 不同维度矩阵的合并方法一
In: np.concatenate([A, z.reshape(1, -1)])   # 需要将z的维度 由3行1列 变为1行3列, 和A一样
out: array([[  1,   2,   3],
       [  4,   5,   6],
       [666, 666, 666]])



# 补充说明
[1,2,3]  向量
[[1,2,3]]  1行3列矩阵
[[1],[2],[3]]  3行1列矩阵


# 不同维度矩阵的合并方法二: vstack和hstack
In:np.vstack([A,z])       # A的列数和z的元素个数相等, 所以使用vstack垂直方向合并, 并不需要对z进行reshape
out: array([[  1,   2,   3],
       [  4,   5,   6],
       [666, 666, 666]])
       
In:B = np.array([[777],[777]])     # [777,777]就表示向量, hstack会报错
In:B
out:array([[777],
       [777]])

In: np.hstack([A,B])
out: array([[  1,   2,   3, 777],
       [  4,   5,   6, 777]])

分割

  • 一维的分割
In:x = np.arange(10)
In:x1, x2, x3 = np.split(x, [3, 7])

In:x1
out:array([0, 1, 2])

In:x2
out:array([3, 4, 5, 6])

In:x3
out:array([7, 8, 9])
  • 多维的分割
# 行方向的分割
In:A = np.arange(16).reshape((4,4))
In:A
out:array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
    
    
In:A1, A2 = np.split(A, [2])      # 或者  upper, lower = np.vsplit(A, [2])
In:A1
out:array([[0, 1, 2, 3],
       [4, 5, 6, 7]])

In:A2
out:array([[ 8,  9, 10, 11],
       [12, 13, 14, 15]])
       

# 列方向的分割
In:A1, A2 = np.split(A, [2], axis=1)    # axis=1指定列分割  或者 left,right = np.hsplit(A, [2])
In:A1
out:array([[ 0,  1],
       [ 4,  5],
       [ 8,  9],
       [12, 13]])
       
In:A2
out:array([[ 2,  3],
       [ 6,  7],
       [10, 11],
       [14, 15]])

六. Numpy中矩阵的运算

对矩阵的元素的元素

# python原生list 实现 将矩阵的元素都x2
n = 10
L = [i for i in range(n)]
A = [2*e for e in L]


# numpy.array实现   将矩阵的元素都x2
import numpy as np
L = np.arange(n)
A = np.array(2*e for e in L)  


# np.array  如果用%%time测试运行时间, 发现比python的list实现, 快得多
# np.array 可以直接*2, 符合矩阵的运算结果, python的list*2 则是list+list  连起来

A = L*2   # 可以直接得到每个元素*2的新矩阵


# np.array  几乎支持其他所有运算  如  
L+1      每个元素+1
L-1
L*2
L/3
1/L      每个元素都变为  倒数
L//5      每个元素整除5
L**3      每个元素幂运算
L%7        每个元素求余数

对矩阵间的运算

  • 运算符进行的是 矩阵元素间的运算
In:A=np.arange(4).reshape(2,2)
In:A
out:array([[0, 1],
       [2, 3]])
       
In:B=np.full((2,2), 10)
In:B
out:array([[10, 10],
       [10, 10]])
      
In:A+B
out:array([[10, 11],
       [12, 13]])

In:A-B
out:array([[-10,  -9],
       [ -8,  -7]])

In:A*B
out:array([[ 0, 10],
       [20, 30]])
       
In:A/B
out:array([[0. , 0.1],
       [0.2, 0.3]])
       

#  可以看到都是元素间 进行运算, 而不是矩阵的运算
  • 矩阵运算
# 矩阵相乘
In: A.dot(B)
out:array([[10, 10],
       [50, 50]])
       

# 矩阵的转置
In: A.T
out: array([[0, 2],
       [1, 3]])

  • 向量和矩阵的运算
In:v=np.array([1,2])
In:A
out:array([[0, 1],
       [2, 3]])
       
In:v+A       # 向量直接与矩阵相加, 会让矩阵的每一行都加上该向量
out:array([[1, 3],
       [3, 5]])
       
       

In: np.vstack([v]*A.shape[0])   # 或者可以把向量变为维度和A一样的矩阵 再进行相加
out:array([[1, 2],
       [1, 2]])


In:np.tile(v, (2,1))        # tile也可以改变维度, 2表示复制为2行, 1表示复制为1列, 即列方向不拓展 
out:array([[1, 2],
       [1, 2]])



In: v*A     # 这样的到 是 v与A的每一行乘, 不是矩阵的乘法
out:array([[0, 2],
       [2, 6]])


In: v.dot(A)     # 想要矩阵相乘   依然使用dot
out:array([4, 7])


In: A.dot(v)     # v是向量, numpy会自动把v变为2*1的矩阵
out:array([2, 8])
  • 矩阵的逆
In:A
out:array([[0, 1],
       [2, 3]])

In:invA = np.linalg.inv(A)   # 得到A的逆矩阵 invA
In:invA
out:array([[-1.5,  0.5],
       [ 1. ,  0. ]])


In: A.dot(invA)    # 原矩阵乘 逆矩阵  得到单位矩阵
out:array([[1., 0.],
       [0., 1.]])



七. Numpy的聚合运算

# 聚合

import numpy as np
L = np.random.random(100)     # 生成100个元素的随机数组
L.dtype
out:dtype('float64')


np.sum(L)   # 求和
out:48.17857390434729



sum(L)      # python的sum 也可以实现, 但 速度比np.sum  慢非常多
out:48.178573904347246


np.min(L)    # 找出最小值
out:0.007983418226231609

np.max(L)     # 找出最大值
out:0.9875521184825461


X= np.arange(16).reshape(4,-1)
X
out:array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])


np.sum(X)    # 默认为  对所有元素求和
out:120


np.sum(X, axis=0)    # 对每一列  求和,  axis=0可以理解为 压缩为一行
out:array([24, 28, 32, 36])


np.sum(X, axis=1)    # 对每一行 求和,  axis=1可以理解为  压缩为一列
out:array([ 6, 22, 38, 54])


np.prod(X)   # 所有元素的乘积
out:0


np.mean(X)   # 所有元素均值
out:7.5

np.median(X)   # 所有元素 中位数
out:7.5


np.percentile(X, q=50)    # 在50%的 地方找到 百分位点   和np.median(X) 等价
out:7.5

np.percentile(X, q=90)     # 在90% 的地方找到百分位点
out:13.5


np.var(X)   # 方差
out:21.25


np.std(X)    # 标准差
out:4.6097722286464435

八. Numpy中的索引运算(arg运算)

  • 找到最值的索引
x = np.random.normal(0,1,size=1000000)   # 生成 均值为0 方差为1 的正态分布点
np.min(x)    # 得到了 最小值, 但想知道 该值 在哪个位置
out:-5.024177664592925


np.argmin(x)   # 找到最小值   的索引位置
out:628924

#同样的 有argmax
  • 排序和使用索引
# 排序
x = np.arange(16)
x
out:array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])


np.random.shuffle(x)    # shuffle 将x中元素顺序打乱
x    
out:array([ 3,  4,  0,  7, 11,  8, 12, 15,  5, 14, 13,  1,  9,  6, 10,  2])


np.sort(x)      # 得到一个新的 排好序的数列
out:array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])

x.sort()        # 在原来的x中排序
x  
out:array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])





# arg排序
np.random.shuffle(x)   # 打乱顺序
x
out:array([13, 10,  7,  0, 12,  5, 14, 15,  9,  2,  3,  6, 11,  4,  8,  1])

np.argsort(x)     # 得到的是索引, 按索引 找到的元素, 都是排序好的元素
out:array([ 2, 11,  9, 15,  1, 10, 14,  7,  4,  3,  5,  6, 12,  8,  0, 13])





# partition操作
np.partition(x,3)    # 小于3的放3前面   大于3的放3后面,   和快速排序中的partition一致
out:array([ 1,  0,  2,  3,  4,  6,  7,  5,  8,  9, 10, 12, 11, 13, 14, 15])

np.argpartition(x,3)   # 同样有 arg方法
out:array([15,  3,  9, 10, 13, 11,  2,  5, 14,  8,  1,  4, 12,  0,  6,  7])





# 多维的排序
X = np.random.randint(10, size=(4,4))    # 生成4x4的 随机矩阵
X
out:array([[2, 1, 7, 8],
       [0, 8, 7, 3],
       [7, 6, 1, 9],
       [0, 2, 9, 8]])


np.sort(X)   # 默认axis=1
out:array([[1, 2, 7, 8],
       [0, 3, 7, 8],
       [1, 6, 7, 9],
       [0, 2, 8, 9]])


np.sort(X, axis=1)   # 沿着列的方向  对每一行排序
out:array([[1, 2, 7, 8],
       [0, 3, 7, 8],
       [1, 6, 7, 9],
       [0, 2, 8, 9]])


np.sort(X, axis=0)   # 沿着行的方向  对每一行列序
out:array([[0, 1, 1, 3],
       [0, 2, 7, 8],
       [2, 6, 7, 8],
       [7, 8, 9, 9]])

九. Numpy中的比较和Fancy indexing

  • Fancy indexing
import numpy as np

x = np.arange(16)
x
out:array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])



[x[3], x[5],x[8]]     # 得到新的数组, 但numpy有更加方便的方法
out: [3, 5, 8]


ind = [3,5,8]     # numpy提供的方法, 即fancy indexing
x[ind]
out:array([3, 5, 8])



# 多维的Fancy indexing
X = x.reshape(4,-1)
X
out:array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
       
row = np.array([0,1,2])    #现在想要得到3个点, row中存放这3个点的所在行数
col = np.array([1,2,3])    # col 放3个点所在列数
X[row, col]
out:array([ 1,  6, 11])


X[0, col]
out:array([1, 2, 3])

X[:2, col]    # 前两行的  对应col  得到数值
out:array([[1, 2, 3],
       [5, 6, 7]])


X[1:3,col]
out:array([[ 5,  6,  7],
       [ 9, 10, 11]])

  • numpy.array的比较
x
out:array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])


x > 3
out:array([False, False, False, False,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True])

x < 3
out:array([ True,  True,  True, False, False, False, False, False, False,
       False, False, False, False, False, False, False])


x >= 3
out:array([False, False, False,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True])

x <= 3
out:array([ True,  True,  True,  True, False, False, False, False, False,
       False, False, False, False, False, False, False])



x == 3
out:array([False, False, False,  True, False, False, False, False, False,
       False, False, False, False, False, False, False])
       
       
       
# 更加复杂的
2*x == 24 - 4*x
out:array([False, False, False, False,  True, False, False, False, False,
       False, False, False, False, False, False, False])
       

# x中有多少元素 <=3
np.sum(x<=3)
out:4


# x中有多少元素 <=3  的另一种方法
np.count_nonzero(x<=3)
out:4


# x中是否存在0
np.any(x == 0)
out: True


# 值>10 且为 偶数的  元素个数
np.sum((x % 2==0) | (x>10))
out:11

猜你喜欢

转载自blog.csdn.net/weixin_41207499/article/details/85220763