• 【12月DW打卡】joyful-pandas


    joyful-pandas 01 - 预备知识

    python基础+numpy基础

    使用命令生成 jupyter nbconvert --to markdown E:PycharmProjectsTianChiProject0_山枫叶纷飞competitions08_joyful-pandas1-python基础.ipynb 生成

    # 下面举一个例子,截断列表中超过 5 的元素:
    L=[x for x in range(0,10)]
    
    [x if x<=5 else 5 for x in L]
    
    [0, 1, 2, 3, 4, 5, 5, 5, 5, 5]
    
    # 实现乘于2倍输出
    L = range(5)
    print([(lambda x:2*x)(i) for i in L])
    print(list(map(lambda x:2*x, L)))
    
    [0, 2, 4, 6, 8]
    [0, 2, 4, 6, 8]
    
    """
    zip 函数能够把多个可迭代对象打包成一个元组构成的可迭代对象,它返回了一个 zip 对象,通过 tuple, list
    可以得到相应的打包结果:
    """
    L1, L2, L3 = list('abc'), list('def'), list('hij')
    
    list(zip(L1,L2,L3))
    
    [('a', 'd', 'h'), ('b', 'e', 'i'), ('c', 'f', 'j')]
    
    tuple(zip(L1,L2,L3))
    
    (('a', 'd', 'h'), ('b', 'e', 'i'), ('c', 'f', 'j'))
    
    L = list('abcd')
    for index, val in enumerate(L):
        print(index, val)
    
    0 a
    1 b
    2 c
    3 d
    
    for index, val in zip(range(len(L)), L):
        print(index, val)
    
    0 a
    1 b
    2 c
    3 d
    
    dict(zip(L1, L2))
    
    
    {'a': 'd', 'b': 'e', 'c': 'f'}
    
    zipped = list(zip(L1, L2, L3))
    zipped
    
    [('a', 'd', 'h'), ('b', 'e', 'i'), ('c', 'f', 'j')]
    
    list(zip(*zipped))
    
    
    
    [('a', 'b', 'c'), ('d', 'e', 'f'), ('h', 'i', 'j')]
    
    
    
    # 最一般的方法是通过 array 来构造
    import numpy as np
    np.array([1, 2, 3])
    
    array([1, 2, 3])
    
    np.linspace(1, 19, 10) # 起始、终止(包含)、样本个数
    
    array([ 1.,  3.,  5.,  7.,  9., 11., 13., 15., 17., 19.])
    
    np.array(1, 19, 10) # 起始、终止(不包含)、样本个数
    
    np.eye(3,3)
    
    array([[1., 0., 0.],
           [0., 1., 0.],
           [0., 0., 1.]])
    
    np.full((2,3), 10) # 元组传入大小,10 表示填充数值
    
    array([[10, 10, 10],
           [10, 10, 10]])
    
    np.full((2,3), [1, 2, 3]) # 通过传入列表填充每列的值
    
    array([[1, 2, 3],
           [1, 2, 3]])
    
    # 最常用的随机生成函数为 rand, randn, randint, choice ,它们分别表示 0-1 均匀分布的随机数组、标准正态的随机数组、随机整数组和随机列表抽样.
    np.random.rand(3, 3) # 注意这里传入的不是元组,每个维度大小分开输入
    
    array([[0.30180431, 0.39218832, 0.37574252],
           [0.41168547, 0.18685168, 0.80999859],
           [0.72171395, 0.82255286, 0.27006587]])
    
    
    
    np.zeros((2, 3)).T
    
    array([[0., 0.],
           [0., 0.],
           [0., 0.]])
    
    # 对于二维数组而言,r_ 和 c_ 分别表示上下合并和左右合并:
    
    np.r_[np.zeros((2,3)),np.zeros((2,3))]
    
    array([[0., 0., 0.],
           [0., 0., 0.],
           [0., 0., 0.],
           [0., 0., 0.]])
    
    # Translates slice objects to concatenation along the second axis.
    np.c_[np.zeros((2,3)),np.zeros((2,3))]
    
    array([[0., 0., 0., 0., 0., 0.],
           [0., 0., 0., 0., 0., 0.]])
    
    # reshape 能够帮助用户把原数组按照新的维度重新排列。在使用时有两种模式,分别为 C 模式和 F 模式,分别以逐行和逐列的顺序进行填充读取。
    
    target = np.arange(8).reshape(2, 4)
    target
    
    array([[0, 1, 2, 3],
           [4, 5, 6, 7]])
    
    target.reshape(4,2) # 默认按行进行读取和填充
    # target.reshape(4,2) # order='C') , 按照行读取和填充 默认按行进行读取和填充
    
    array([[0, 1],
           [2, 3],
           [4, 5],
           [6, 7]])
    
    target.reshape((4,2), order='F') # 按照列读取和填充
    
    array([[0, 2],
           [4, 6],
           [1, 3],
           [5, 7]])
    
    # 特别地,由于被调用数组的大小是确定的,reshape 允许有一个维度存在空缺,此时只需填充-1 即可:
    target = np.ones((5, 1))
    trans = target.reshape((-1))
    trans
    
    array([1., 1., 1., 1., 1.])
    
    # 数组的切片模式支持使用 slice 类型的 start:end:step 切片,还可以直接传入列表指定某个维度的索引进行切片
    target = np.arange(9).reshape(3,3)
    target[:, [0,2]]
    
    array([[0, 2],
           [3, 5],
           [6, 8]])
    
    target[np.ix_([True, False, True], [True, False, True])]
    
    array([[0, 2],
           [6, 8]])
    
    target[np.ix_([0,1], [True, False, True])]
    
    array([[0, 2],
           [3, 5]])
    
    target[np.ix_([0,2], [True, False, True])]
    
    array([[0, 2],
           [6, 8]])
    
    new = target.reshape(-1)
    new[new%2==0]
    
    array([0, 2, 4, 6, 8])
    
    test = np.arange(4).reshape(-1,2)
    print(test)
    print(test.sum(0))
    print(test.sum(1))
    
    [[0 1]
     [2 3]]
    [2 4]
    [1 5]
    
    
    
    22
    
    a = np.array([1,2,3])
    b = np.array([1,3,5])
    a.dot(b)
    
    """
    矩阵范数的定义
    一个在 的矩阵上的矩阵范数(matrix norm)是一个从 线性空间到实数域上的一个函数,
    记为映射|| · ||,它对于任意的 矩阵A和B及所有实数a,满足以下四条性质:
    ||A||>=0;
    ||A||=0 iff A=O (零矩阵); (1和2可统称为正定性)
    ||aA||=|a| ||A||; (齐次性)
    ||A+B||<= ||A|| + ||B||. (三角不等式)
    """
    martix_target = np.arange(4).reshape(-1,2)
    martix_target
    
    array([[0, 1],
           [2, 3]])
    
    np.linalg.norm(martix_target, 'fro')
    
    3.7416573867739413
    
    np.linalg.norm(martix_target, np.inf)
    
    
    5.0
    
    np.linalg.norm(martix_target, 2)
    
    3.702459173643833
    
    vector_target = np.arange(4)
    vector_target
    
    array([0, 1, 2, 3])
    
    a = np.arange(4).reshape(-1,2)
    b = np.arange(4).reshape(-1,2)
    a@b
    
    array([[ 2,  3],
           [ 6, 11]])
    

    1.3 练习

    Ex1:利用列表推导式写矩阵乘法

    一般的矩阵乘法根据公式,可以由三重循环写出,这里改写为列表推导式的形式来书写

    # 如下为三重循环写出:
    M1 = np.random.rand(2,3)
    M2 = np.random.rand(3,4)
    res = np.empty((M1.shape[0],M2.shape[1]))
    for i in range(M1.shape[0]):
        for j in range(M2.shape[1]):
            item = 0
            for k in range(M1.shape[1]):
                item += M1[i][k] * M2[k][j]
            res[i][j] = item
    ((M1@M2 - res) < 1e-15).all() # 排除数值误差
    
    M1 = np.random.rand(2,3)
    M2 = np.random.rand(3,4)
    res = np.empty((M1.shape[0], M2.shape[1]))
    # 改为列表推导式
    res = [
        [sum(M1[i][k]*M2[k][j] for k in range(M1.shape[1]) for j in range(M2.shape[1]))] for i in range(M1.shape[0])
    ]
    
    ((M1@M2 - res) < 1e-15).all() # 排除数值误差
    
    True
    

    Ex2:更新矩阵

    设矩阵 (A_{m×n}) ,现在对 (A) 中的每一个元素进行更新生成矩阵 (B) ,更新方法是 (B_{ij}=A_{ij}sum_{k=1}^nfrac{1}{A_{ik}}) ,例如下面的矩阵为 (A) ,则 (B_{2,2}=5 imes(frac{1}{4}+frac{1}{5}+frac{1}{6})=frac{37}{12}) ,请利用 Numpy 高效实现。

    [egin{split}A=left[ egin{matrix} 1 & 2 &3\4&5&6\7&8&9 end{matrix} ight]end{split} ]

    A=np.array([[1,2,3],[4,5,6],[7,8,9]])
    # 做个cache
    cacheA = [sum(1.0/x for x in A[j, :]) for j in range(A.shape[1]) ]
    cacheA
    
    [1.8333333333333333, 0.6166666666666667, 0.37896825396825395]
    
    B = [
        [ A[i][j] * cacheA[i] for j in range(A.shape[1])]
         for i in range(A.shape[0])
    ]
    B
    
    [[1.8333333333333333, 3.6666666666666665, 5.5],
     [2.466666666666667, 3.0833333333333335, 3.7],
     [2.6527777777777777, 3.0317460317460316, 3.4107142857142856]]
    

    Ex3:卡方统计量

    设矩阵(A_{m imes n}),记(B_{ij} = frac{(sum_{i=1}^mA_{ij}) imes (sum_{j=1}^nA_{ij})}{sum_{i=1}^msum_{i=1}^nA_{ij}}),定义卡方值如下:

    [chi^2 = sum_{i=1}^msum_{j=1}^nfrac{(A_{ij}-B_{ij})^2}{B_{ij}} ]

    请利用Numpy对给定的矩阵(A)计算(chi^2)

    np.random.seed(0)
    A = np.random.randint(10, 20, (8, 5))
    # 计算步骤如下:
    B = A.sum(0)*A.sum(1).reshape(-1, 1)/A.sum()
    print(B)
    res = ((A-B)**2/B).sum()
    res
    
    
    [[14.14211438 13.08145581 15.20277296 13.67071057 11.90294627]
     [15.18197574 14.04332756 16.32062392 14.67590988 12.77816291]
     [16.63778163 15.38994801 17.88561525 16.08318891 14.0034662 ]
     [16.42980936 15.19757366 17.66204506 15.88214905 13.82842288]
     [17.67764298 16.35181976 19.0034662  17.08838821 14.87868284]
     [12.68630849 11.73483536 13.63778163 12.26343154 10.67764298]
     [13.93414211 12.88908146 14.97920277 13.46967071 11.72790295]
     [13.3102253  12.31195841 14.3084922  12.86655113 11.20277296]]
    
    
    
    
    
    11.842696601945802
    

    Ex4:改进矩阵计算的性能

    (Z)(m×n)的矩阵,(B)(U)分别是(m×p)(p×n)的矩阵,(B_i)(B)的第(i)行,(U_j)(U)的第(j)列,下面定义(displaystyle R=sum_{i=1}^msum_{j=1}^n|B_i-U_j|_2^2Z_{ij}),其中(|mathbf{a}|_2^2)表示向量(a)的分量平方和(sum_i a_i^2)

    现有某人根据如下给定的样例数据计算(R)的值,请充分利用Numpy中的函数,基于此问题改进这段代码的性能。

    """
    改造前
    """
    np.random.seed(0)
    m, n, p = 100, 80, 50
    B = np.random.randint(0, 2, (m, p))
    U = np.random.randint(0, 2, (p, n))
    Z = np.random.randint(0, 2, (m, n))
    def solution(B=B, U=U, Z=Z):
        L_res = []
        for i in range(m):
            for j in range(n):
                norm_value = ((B[i]-U[:,j])**2).sum()
                L_res.append(norm_value*Z[i][j])
        return sum(L_res)
    solution(B, U, Z)
    
    100566
    
    """
    改造后
    """
    
    (((B**2).sum(1).reshape(-1,1) + (U**2).sum(0) - 2*B@U)*Z).sum()
    
    100566
    

    Ex5:连续整数的最大长度

    输入一个整数的Numpy数组,返回其中递增连续整数子数组的最大长度,正向是指递增方向。例如,输入[1,2,5,6,7],[5,6,7]为具有最大长度的连续整数子数组,因此输出3;输入[3,2,1,2,3,4,6],[1,2,3,4]为具有最大长度的连续整数子数组,因此输出4。请充分利用Numpy的内置函数完成。(提示:考虑使用nonzero, diff函数)

    # np.diff 意思如下:
    # Calculate the n-th discrete difference along the given axis.
    # np.r_ 按列进行合并   Translates slice objects to concatenation along the second axis.
    func = lambda x:np.diff(np.nonzero(np.r_[1,np.diff(x)!=1,1])).max()
    func([1,2,5,6,7])
    
    
    
    3
    
    func([3,2,1,2,3,4,6])
    
    
      4
    

    复习内容链接

  • 相关阅读:
    关于Sprte2d的图片切割
    关于U3d GameObject类型的可用描述
    [小巩u3d] Sprite 2D的资源占用分析
    [小巩u3d] 关于Raycast对BoxCollider和BoxCollider2d的碰撞监测规则
    Web服务器父与子 Apache和Tomcat区别
    [转]IIS添加MIME扩展类型及常用的MIME类型列表
    转载自知乎:程序员干到三十就干不动了」的说法是从哪来的?
    Unity之如何去除动画scale
    Unity shader学习之简单的水效果
    Unity shader学习之卡通渲染,轮廓线
  • 原文地址:https://www.cnblogs.com/zhazhaacmer/p/14130243.html
Copyright © 2020-2023  润新知