zoukankan      html  css  js  c++  java
  • numpy

    《Python数据分析基础教程,munpy学习指南(第二版)》:代码
    http://www.pudn.com/Download/item/id/2742220.html

    numpy 学习指南

    http://www.pudn.com/Download/item/id/2742220.html
    https://www.jianshu.com/p/04d180d90a3f
    https://wizardforcel.gitbooks.io/pandas-cookbook-code-notes/content/2.html


    http://pandas.pydata.org

    1,测试numpy 和python 自带数组操作时间比较

    import numpy as np
    import datetime  as datetime
    def numpysum(n):
        a = np.arange(n) ** 2
        b = np.arange(n) ** 3 
        c = a + b 
        return c
    def pythonsum(n):
        a = list(range(n))
        b = list(range(n))
        c = []
        for i in range(len(a)):
            a[i] = i ** 2
            b[i] = i ** 3
            c.append(a[i] + b[i])
        return c
    
    
    
    start = int(round(time.time() * 1000))
    c = numpysum(500000)
    delta = int(round(time.time() * 1000)) - start 
    print("numpysum use " )
    print(str(delta))
    
    
    start = int(round(time.time() * 1000))
    c = pythonsum(500000)
    delta = int(round(time.time() * 1000)) - start 
    print("pysum use " )
    print(str(delta))
    

    帮助

    np.arange?
    

    NumPy 数组对象

    ndarray是一个多维数组对象,该对象由两部分组成, (The N-dimensional array (ndarray))

    实际的数据;

    描述这些数据的元数据

    大部分的数组操作仅仅修改元数据部分,而不改变底层的实际数据

    一维数组向量:

    一个包含5个元素的向量,取值分别为0~4的整数。数组的shape属性返回一个元组(tuple),元组中的元素即为NumPy数组每一个维度上的大小

    a = np.arange(5)
    print(a)
    a.dtype
    [0 1 2 3 4]
    dtype('int64')
    
    
    a.shape
    (5,)
    
    

    多维数据向量

    m = np.array([np.arange(2), np.arange(2)])
    m.shape  2 
    [[0 1]
     [0 1]]
    
    
    ##3x3维度
    np.array([np.arange(3), np.arange(3), np.arange(3)])
    

    选取数组

    a[m,n]  m,n 为元素下标
    [0,0][0,1]
    [1,0][1,1]
    
    

    numpy 数据类型

    bool 用一位存储的布尔类型(值为TRUE或FALSE)
    inti 由所在平台决定其精度的整数(一般为int32或int64)
    int8 整数,范围为128至127
    int16 整数,范围为32 768至32 767
    int32 整数,范围为231至231 1
    int64 整数,范围为263至263 1
    uint8 无符号整数,范围为0至255
    uint16 无符号整数,范围为0至65 535
    uint32 无符号整数,范围为0至2321
    uint64 无符号整数,范围为0至2641
    float16 半精度浮点数(16位):其中用1位表示正负号,5位表示指数,10位表示尾数
    float32 单精度浮点数(32位):其中用1位表示正负号,8位表示指数,23位表示尾数
    float64或float 双精度浮点数(64位):其中用1位表示正负号,11位表示指数,52位表示尾数
    complex64 复数,分别用两个32位浮点数表示实部和虚部
    complex128或complex 复数,分别用两个64位浮点数表示实部和虚部

    数据类型对象:

    数据类型对象是numpy.dtype类的实例。如前所述,NumPy数组是有数据类型的,更确切地说,NumPy数组中的每一个元素均为相同的数据类型。数据类型对象可以给出单个数组元素在内存中占用的字节数,即dtype类的itemsize属性. m.dtype.itemsize

    字符编码

    整数 i
    无符号整数 u
    单精度浮点数 f
    双精度浮点数 d
    布尔值 b
    复数 D
    字符串 S
    unicode字符串 U
    void (空) V

    np.arange(7, dtype='f')
    

    自定义数据类型

    In: dtype(float) 
    Out: dtype('float64') 
    
    In: dtype('f') 
    Out: dtype('float32') 
    
    
    In: dtype('d') 
    Out: dtype('float64') 
    

    创建自定义数据类型

    t = np.dtype([('name',str, 40), ('numitems', int), ('price',float)]) 
    t['name']
    
    itemz = np.array([('Meaning of life DVD', 42, 3.14), ('Butter', 13, 2.72)], dtype=t)
    
    t = np.dtype([('name', 'S', 40), ('numitems', 'int32'), ('price', 'float32')])   ##这个是正常的
    获取帮助 np.dtype?
    
    

    一维数组的索引和切片

    In: a[::-1] 
    Out: array([8, 7, 6, 5, 4, 3, 2, 1, 0])    利用负数下标翻转数组
    

    多维数组的切片和索引

    b = np.arange(24).reshape(2,3,4)
    array([[[ 0,  1,  2,  3],
            [ 4,  5,  6,  7],
            [ 8,  9, 10, 11]],
    
           [[12, 13, 14, 15],
            [16, 17, 18, 19],
            [20, 21, 22, 23]]])
    
    b.shape
    (2, 3, 4)
    
    多维数组b中有0~23的整数,共24个元素,是一个2×3×4的三维数组。我们可以形象地把它看做一个两层楼建筑,每层楼有12个房间,并排列成3行4列
    
    或者将其看成是电子表格中工作表(sheet)、行和列的关系
    
    #以用三维坐标来选定任意一个房间,即楼层、行号和列号
    b[0,0,0]
    
    
    #如果我们不关心楼层,也就是说要选取所有楼层的第1行、第1列的房间,那么可以将第1个下标用英文标点的冒号:来代替
    b[:, 0,0]
    
    #选取第1层楼的所有房间
    b[0, :, :]
    多个冒号可以用一个省略号(...)来代替
    b[0, ...]
    
    #选取第1层楼、第2排的所有房间
    b[0,1]
    
    #数组切片中间隔地选定元素
    b[0,1,::2]
    #要选取所有楼层的位于第2列的房间,即不指定楼层和行号
    b[...,1]
    #选取所有位于第2行的房间,而不指定楼层和列号
    b[:,1]
    #选取第1层楼的所有位于第2列的房间
    b[0,:,1]
    #要选取第1层楼的最后一列的所有房间
    b[0,::-1, -1]
    
    #该数组切片中间隔地选定元素
    b[0,::2,-1]
    
    #数组切片中间隔地选定元素
    b[0,::2,-1]
    
    #第1层楼和第2层楼的房间交换
    b[::-1]
    

    改变数组的维度

    #用ravel函数完成展平的操作
    array([[[ 0,  1,  2,  3],
            [ 4,  5,  6,  7],
            [ 8,  9, 10, 11]],
    
           [[12, 13, 14, 15],
            [16, 17, 18, 19],
            [20, 21, 22, 23]]])
    
    b.ravel()
    array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
           17, 18, 19, 20, 21, 22, 23])
    
    #flatten就是展平的意思,与ravel函数的功能相同,flatten函数会请求分配内存来保存结果,而ravel函数只是返回数组的一个视图(view)
    b.flatten()
    
    #用元组设置维度
    b.shape = (6,4)
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11],
           [12, 13, 14, 15],
           [16, 17, 18, 19],
           [20, 21, 22, 23]])
    
    # transpose 在线性代数中,转置矩阵是很常见的操作。对于多维数组
    b.transpose()
    array([[ 0,  4,  8, 12, 16, 20],
           [ 1,  5,  9, 13, 17, 21],
           [ 2,  6, 10, 14, 18, 22],
           [ 3,  7, 11, 15, 19, 23]])
    
    # resize resize和reshape函数的功能一样,但resize会直接修改所操作的数组
    b.resize((2,12)) 
    
    

    组合数组

    水平组合,垂直, 深度组合,列组合,行组合

    import numpy as np
    a = np.arange(9).reshape(3,3)
    array([[0, 1, 2],
           [3, 4, 5],
           [6, 7, 8]])
    b = 2 * a
    array([[ 0,  2,  4],
           [ 6,  8, 10],
           [12, 14, 16]])
    ## 水平组合   
    np.hstack((a,b))
    np.concatenate((a,b), axis=1)
    array([[ 0,  1,  2,  0,  2,  4],
           [ 3,  4,  5,  6,  8, 10],
           [ 6,  7,  8, 12, 14, 16]])
    ##垂直
    np.vstack((a,b))
    np.concatenate((a, b), axis = 0)
    array([[ 0,  1,  2],
           [ 3,  4,  5],
           [ 6,  7,  8],
           [ 0,  2,  4],
           [ 6,  8, 10],
           [12, 14, 16]])
    
    #深度组合 是将一系列数组沿着纵轴(深度)方向进行层叠组合
    举个例子,有若干张二维平面内的图像点阵数据,我们可以将这些图像数据沿纵轴方向层叠在一起
    
    np.dstack((a,b))
    array([[[ 0,  0],
            [ 1,  2],
            [ 2,  4]],
    
           [[ 3,  6],
            [ 4,  8],
            [ 5, 10]],
    
           [[ 6, 12],
            [ 7, 14],
            [ 8, 16]]])
    
    ##列组合 column_stack函数对于一维数组将按列方向进行组合
    In: oned = arange(2) 
    In: oned 
    Out: array([0, 1]) 
    In: twice_oned = 2 * oned 
    In: twice_oned 
    Out: array([0, 2]) 
    In: column_stack((oned, twice_oned)) 
    Out: 
    array([[0, 0], 
     [1, 2]]) 
    
    对于二维数组,column_stack与hstack的效果是相同的
    In: column_stack((a, b)) 
    Out: 
    array([[ 0, 1, 2, 0, 2, 4], 
     [ 3, 4, 5, 6, 8,10], 
     [ 6, 7, 8,12,14,16]]) 
    In: column_stack((a, b)) == hstack((a, b)) 
    Out: 
    array([[ True, True, True, True, True, True], 
     [ True, True, True, True, True, True], 
     [ True, True, True, True, True, True]], dtype=bool) 
    
    我们可以用==运算符来比较两个NumPy数组
    #行组合 
    In: row_stack((oned, twice_oned)) 
    Out: 
    array([[0, 1], 
     [0, 2]])
    
    对于二维数组,row_stack与vstack的效果是相同的:
    In: row_stack((a, b)) 
    Out: 
    array([[ 0, 1, 2], 
     [ 3, 4, 5], 
     [ 6, 7, 8], 
     [ 0, 2, 4], 
     [ 6, 8,10], 
     [12,14,16]]) 
    In: row_stack((a,b)) == vstack((a, b)) 
    Out: 
    array([[ True, True, True], 
     [ True, True, True], 
     [ True, True, True], 
     [ True, True, True], 
     [ True, True, True], 
     [ True, True, True]], dtype=bool)
    

    数组的分割

    NumPy数组可以进行水平、垂直或深度分割,相关的函数有hsplit、vsplit、dsplit和split。我们可以将数组分割成相同大小的子数组,也可以指定原数组中需要分割的位置

    ##水平分割   把数组沿着水平方向分割为3个相同大小的子数组:
    hsplit(a, 3)
    
    ##垂直分割
    
    
    ##深度分割
    
    ##
    

    数组的属性

    除了shape和dtype属性以外,ndarray对象还有很多其他的属

    nidm
    b.ndim 维度
    
    size属性  给出数组元素的总个数
    
    itemsize属性,给出数组中的元素在内存中所占的字节数
    
    

    使用tolist函数将NumPy数组转换成Python列表

    In: b 
    Out: array([ 1.+1.j, 3.+2.j]) 
    In: b.tolist() 
    Out: [(1+1j), (3+2j)] 
    

    astype函数可以在转换数组时指定数据类型

    In: b 
    Out: array([ 1.+1.j, 3.+2.j]) 
    In: b.astype(int) 
    /usr/local/bin/ipython:1: ComplexWarning: Casting complex values to real discards the 
    imaginary part 
     #!/usr/bin/python 
    Out: array([1, 3]) 
    

    股票实验

    原始数据

    AAPL,28-01-2011, ,344.17,344.4,333.53,336.1,21144800 
    AAPL,31-01-2011, ,335.8,340.04,334.3,339.32,13473000 
    AAPL,01-02-2011, ,341.3,345.65,340.98,345.03,15236800 
    AAPL,02-02-2011, ,344.45,345.25,343.55,344.32,9242600 
    AAPL,03-02-2011, ,343.8,344.24,338.55,343.44,14064100 
    AAPL,04-02-2011, ,343.61,346.7,343.51,346.5,11494200 
    AAPL,07-02-2011, ,347.89,353.25,347.64,351.88,17322100 
    AAPL,08-02-2011, ,353.68,355.52,352.15,355.2,13608500 
    AAPL,09-02-2011, ,355.19,359,354.87,358.16,17240800 
    AAPL,10-02-2011, ,357.39,360,348,354.54,33162400 
    AAPL,11-02-2011, ,354.75,357.8,353.54,356.85,13127500 
    AAPL,14-02-2011, ,356.79,359.48,356.71,359.18,11086200 
    AAPL,15-02-2011, ,359.19,359.97,357.55,359.9,10149000 
    AAPL,16-02-2011, ,360.8,364.9,360.5,363.13,17184100 
    AAPL,17-02-2011, ,357.1,360.27,356.52,358.3,18949000 
    AAPL,18-02-2011, ,358.21,359.5,349.52,350.56,29144500 
    AAPL,22-02-2011, ,342.05,345.4,337.72,338.61,31162200 
    AAPL,23-02-2011, ,338.77,344.64,338.61,342.62,23994700 
    AAPL,24-02-2011, ,344.02,345.15,338.37,342.88,17853500 
    AAPL,25-02-2011, ,345.29,348.43,344.8,348.16,13572000 
    AAPL,28-02-2011, ,351.21,355.05,351.12,353.21,14395400 
    AAPL,01-03-2011, ,355.47,355.72,347.68,349.31,16290300 
    AAPL,02-03-2011, ,349.96,354.35,348.4,352.12,21521000 
    AAPL,03-03-2011, ,357.2,359.79,355.92,359.56,17885200 
    AAPL,04-03-2011, ,360.07,360.29,357.75,360,16188000 
    AAPL,07-03-2011, ,361.11,361.67,351.31,355.36,19504300 
    AAPL,08-03-2011, ,354.91,357.4,352.25,355.76,12718000 
    AAPL,09-03-2011, ,354.69,354.76,350.6,352.47,16192700 
    AAPL,10-03-2011, ,349.69,349.77,344.9,346.67,18138800 
    AAPL,11-03-2011, ,345.4,352.32,345,351.99,16824200 
    

    分析日期数据

    from datetime import datetime
    def datestr2num(s): 
     return datetime.strptime(s.decode("utf-8"), "%d-%m-%Y").date().weekday()
    
    
    
    dates, close=np.loadtxt('data.csv', delimiter=',',  converters={1: datestr2num}, usecols=(1,6), unpack=True)
    
    dates
    array([4., 0., 1., 2., 3., 4., 0., 1., 2., 3., 4., 0., 1., 2., 3., 4., 1.,
           2., 3., 4., 0., 1., 2., 3., 4., 0., 1., 2., 3., 4.])
    
    averages = np.zeros(5)
    for i in range(5):  
       indices = np.where(dates == i)   
       prices = np.take(close, indices)  
       avg = np.mean(prices)  
       print("Day", i, "prices", prices, "Average", avg  )
       averages[i] = avg
    
    
    np.max(averages)  argmax函数返回的是averages数组中最大元素的索引值
    
    
    

    NumPy的ndarray:一种多维数组对象

    In [12]: import numpy as np
    
    # Generate some random data
    In [13]: data = np.random.randn(2, 3)
    
    In [14]: data
    Out[14]: 
    array([[-0.2047,  0.4789, -0.5194],
           [-0.5557,  1.9658,  1.3934]])
    
    
    In [15]: data * 10
    Out[15]: 
    array([[ -2.0471,   4.7894,  -5.1944],
           [ -5.5573,  19.6578,  13.9341]])
    
    In [16]: data + data
    Out[16]: 
    array([[-0.4094,  0.9579, -1.0389],
           [-1.1115,  3.9316,  2.7868]])
    
    
    #元素自身想运算
    

    ndarray是一个通用的同构数据多维容器,也就是说,其中的所有元素必须是相同类型的。每个数组都有一个shape(一个表示各维度大小的元组)和一个dtype(一个用于说明数组数据类型的对象)

    创建ndarray

    In [19]: data1 = [6, 7.5, 8, 0, 1]
    In [20]: arr1 = np.array(data1)
    In [21]: arr1
    Out[21]: array([ 6. ,  7.5,  8. ,  0. ,  1. ])
      
      
      ##或
    In [22]: data2 = [[1, 2, 3, 4], [5, 6, 7, 8]]
    In [23]: arr2 = np.array(data2)  
    

    除np.array之外,还有一些函数也可以新建数组。比如,zeros和ones分别可以创建指定长度或形状的全0或全1数组。empty可以创建一个没有任何具体值的数组。要用这些方法创建多维数组,只需传入一个表示形状的元组即可:

    In [29]: np.zeros(10)
    Out[29]: array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])
    
    In [30]: np.zeros((3, 6))
    Out[30]: 
    array([[ 0.,  0.,  0.,  0.,  0.,  0.],
           [ 0.,  0.,  0.,  0.,  0.,  0.],
           [ 0.,  0.,  0.,  0.,  0.,  0.]])
    
    In [31]: np.empty((2, 3, 2))
    Out[31]: 
    array([[[ 0.,  0.],
            [ 0.,  0.],
            [ 0.,  0.]],
           [[ 0.,  0.],
            [ 0.,  0.],
            [ 0.,  0.]]])
    

    arange是Python内置函数range的数组版:


    ndarray的数据类型

    In [33]: arr1 = np.array([1, 2, 3], dtype=np.float64)
    
    In [34]: arr2 = np.array([1, 2, 3], dtype=np.int32)
    
    In [35]: arr1.dtype
    Out[35]: dtype('float64')
    
    In [36]: arr2.dtype
    Out[36]: dtype('int32')
    

    数据类型转化

    In [37]: arr = np.array([1, 2, 3, 4, 5])
    
    In [38]: arr.dtype
    Out[38]: dtype('int64')
    
    In [39]: float_arr = arr.astype(np.float64)
    
    In [40]: float_arr.dtype
    Out[40]: dtype('float64')
    

    如果将浮点数转换成整数,则小数部分将会被截取删除

    如果某字符串数组表示的全是数字,也可以用astype将其转换为数值形式:

    In [44]: numeric_strings = np.array(['1.25', '-9.6', '42'], dtype=np.string_)
    
    In [45]: numeric_strings.astype(float)
    Out[45]: array([  1.25,  -9.6 ,  42.  ])
    

    注意:使用numpy.string_类型时,一定要小心,因为NumPy的字符串数据是大小固定的,发生截取时,不会发出警告。pandas提供了更多非数值数据的便利的处理方法。

    NumPy数组的运算

    不用编写循环即可对数据执行批量运算。NumPy用户称其为矢量化(vectorization)。大小相等的数组之间的任何算术运算都会将运算应用到元素级

    In [51]: arr = np.array([[1., 2., 3.], [4., 5., 6.]])
    
    In [52]: arr
    Out[52]: 
    array([[ 1.,  2.,  3.],
           [ 4.,  5.,  6.]])
    
    In [53]: arr * arr
    Out[53]: 
    array([[  1.,   4.,   9.],
           [ 16.,  25.,  36.]])
    
    In [54]: arr - arr
    Out[54]: 
    array([[ 0.,  0.,  0.],
           [ 0.,  0.,  0.]])
    

    数组与标量的算术运算会将标量值传播到各个元素: 计算动作会在每一个元素上执行

    大小相同的数组之间的比较会生成布尔值数组:

    不同大小的数组之间的运算叫做广播(broadcasting)

    In [57]: arr2 = np.array([[0., 4., 1.], [7., 2., 12.]])
    
    In [58]: arr2
    Out[58]: 
    array([[  0.,   4.,   1.],
           [  7.,   2.,  12.]])
    
    In [59]: arr2 > arr
    Out[59]:
    array([[False,  True, False],
           [ True, False,  True]], dtype=bool)
    

    基本的索引和切片

    当你将一个标量值赋值给一个切片时(如arr[5:8]=12),该值会自动传播(也就说后面将会讲到的“广播”)到整个选区。跟列表最重要的区别在于,数组切片是原始数组的视图。这意味着数据不会被复制,视图上的任何修改都会直接反映到源数组上。

    即: 对切片的操作会反应到源数据上,类似数据映射的关系

    注意:如果你想要得到的是ndarray切片的一份副本而非视图,就需要明确地进行复制操作,例如arr[5:8].copy()

    在多维数组中,如果省略了后面的索引,则返回对象会是一个维度低一点的ndarray(它含有高一级维度上的所有数据)

    In [76]: arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
    
    arr3d[0]   #一个2×3数组
    

    切片索引

    二维数组arr2d:沿着第0轴(即第一个轴)切片的。也就是说,切片是沿着一个轴向选取元素的。表达式arr2d[:2]可以被认为是“选取arr2d的前两行”

    In [90]: arr2d
    Out[90]: 
    array([[1, 2, 3],
           [4, 5, 6],
           [7, 8, 9]])
    
    In [91]: arr2d[:2]
    Out[91]: 
    array([[1, 2, 3],
           [4, 5, 6]])
    

    注意,“只有冒号”表示选取整个轴

    In [95]: arr2d[:, :1]
    Out[95]: 
    array([[1],
           [4],
           [7]])
    

    布尔型索引

    In [98]: names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
    
    In [99]: data = np.random.randn(7, 4)
    
    In [100]: names
    Out[100]: 
    array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'],
          dtype='<U4')
    
    In [101]: data
    Out[101]: 
    array([[ 0.0929,  0.2817,  0.769 ,  1.2464],
           [ 1.0072, -1.2962,  0.275 ,  0.2289],
           [ 1.3529,  0.8864, -2.0016, -0.3718],
           [ 1.669 , -0.4386, -0.5397,  0.477 ],
           [ 3.2489, -1.0212, -0.5771,  0.1241],
           [ 0.3026,  0.5238,  0.0009,  1.3438],
           [-0.7135, -0.8312, -2.3702, -1.8608]])
    
    
    In [102]: names == 'Bob'
    Out[102]: array([ True, False, False,  True, False, False, False], dtype=bool)
      
      
      
    In [103]: data[names == 'Bob']
    Out[103]: 
    array([[ 0.0929,  0.2817,  0.769 ,  1.2464],
           [ 1.669 , -0.4386, -0.5397,  0.477 ]])  
    

    布尔型数组的长度必须跟被索引的轴长度一致。此外,还可以将布尔型数组跟切片、整数(或整数序列,稍后将对此进行详细讲解)混合使用:

    In [103]: data[names == 'Bob']
    Out[103]: 
    array([[ 0.0929,  0.2817,  0.769 ,  1.2464],
           [ 1.669 , -0.4386, -0.5397,  0.477 ]])
           
           
    In [104]: data[names == 'Bob', 2:]
    Out[104]: 
    array([[ 0.769 ,  1.2464],
           [-0.5397,  0.477 ]])
    
    In [105]: data[names == 'Bob', 3]
    Out[105]: array([ 1.2464,  0.477 ])       
    

    要选择除"Bob"以外的其他值,既可以使用不等于符号(!=),也可以通过~对条件进行否定:

    data[~(names == 'Bob')]
    
    ##或
    cond = names == 'Bob'
    data[~cond]
    

    选取这三个名字中的两个需要组合应用多个布尔条件,使用&(和)、|(或)之类的布尔算术运算符即可

    mask = (names == 'Bob') | (names == 'Will')
    

    通过布尔型索引选取数组中的数据,将总是创建数据的副本,即使返回一模一样的数组也是如此。

    通过布尔型数组设置值是一种经常用到的手段。为了将data中的所有负值都设置为0,我们只需

    data[data < 0] = 0
    

    通过一维布尔数组设置整行或列的值也很简单:

    data[names != 'Joe'] = 7
    

    花式索引

    花式索引(Fancy indexing)是一个NumPy术语,它指的是利用整数数组进行索引。假设我们有一个8×4数组:

  • 相关阅读:
    CS224d lecture 16札记
    CS224d lecture 15札记
    CS224d lecture 14札记
    CS224d lecture 13札记
    将博客搬至CSDN
    三张图理解JavaScript原型链
    三道题理解软件流水
    网络安全密码学课程笔记
    “wuliao“(无聊)聊天软件
    大二小学期C#资产管理大作业小记
  • 原文地址:https://www.cnblogs.com/g2thend/p/12377656.html
Copyright © 2011-2022 走看看