zoukankan      html  css  js  c++  java
  • 【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
    

    复习内容链接

  • 相关阅读:
    Median Value
    237. Delete Node in a Linked List
    206. Reverse Linked List
    160. Intersection of Two Linked Lists
    83. Remove Duplicates from Sorted List
    21. Merge Two Sorted Lists
    477. Total Hamming Distance
    421. Maximum XOR of Two Numbers in an Array
    397. Integer Replacement
    318. Maximum Product of Word Lengths
  • 原文地址:https://www.cnblogs.com/zhazhaacmer/p/14130243.html
Copyright © 2011-2022 走看看