%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 |
|