• 《利用Python进行数据分析》第4章 NumPy基础:数组与向量化计算 笔记


    4.1 NumPy ndarray:多维数组对象

    In [121]: data = np.random.randn(2,3)                                                                     
    
    In [122]: data                                                                                            
    Out[122]: 
    array([[ 0.54913133,  1.22840566, -0.2471307 ],
           [ 1.13488389, -0.94895987,  1.06972625]])
    
    In [123]: data * 10                                                                                       
    Out[123]: 
    array([[ 5.49131332, 12.28405661, -2.47130702],
           [11.34883889, -9.48959874, 10.69726254]])
    
    In [124]: data + data                                                                                     
    Out[124]: 
    array([[ 1.09826266,  2.45681132, -0.4942614 ],
           [ 2.26976778, -1.89791975,  2.13945251]])
    
    In [125]: data.shape                                                                                      
    Out[125]: (2, 3)
    
    In [126]: data.dtype                                                                                      
    Out[126]: dtype('float64')
    

    4.1.1 生成ndarray

    最简单的方法使用array函数,输入一个序列即可,比如list:

    除非主动声明,否则np.array会自动给data搭配适合的类型,并保存在dtype里:

    4.1.2 ndarray的数据类型

    可以通过.astype的方式修改数组的类型

    arr = np.array([1, 2, 3, 4, 5])
    arr.dtype
    
    float_arr = arr.astype(np.float64)
    float_arr.dtype
    float_arr
    
    array([1., 2., 3., 4., 5.])
    

    记住,astype总是会返回一个新的数组

    4.1.3 NumPy数组算术

    数组之所以重要,是因为不用写for循环就能表达很多操作,这种特性叫做vectorization(向量化)。任何两个大小相等的数组之间的运算,都是element-wise(点对点

    4.1.4基础索引于切片

    一维数组的切片跟列表切片操作一样,记住列表切片是浅拷贝,数组切片是视图。

    在一个多维数组中,你可以省略后续索引值,返回的对象将是降低一个维度的数组。

    In [138]: arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])                           
    
    In [139]: arr3d[0]                                                                                        
    Out[139]: 
    array([[1, 2, 3],
           [4, 5, 6]])
    
    In [140]: arr3d                                                                                           
    Out[140]: 
    array([[[ 1,  2,  3],
            [ 4,  5,  6]],
    
           [[ 7,  8,  9],
            [10, 11, 12]]])
    
    In [141]: arr3d[0] = 99                                                                                   
    
    In [142]: arr3d                                                                                           
    Out[142]: 
    array([[[99, 99, 99],
            [99, 99, 99]],
    
           [[ 7,  8,  9],
            [10, 11, 12]]])
    
    In [143]: 
    

     可以选出一个维度的数组通过数值给维度内所有的元素赋值。

    4.1.4.1 数组的切片索引

    可以结合索引于切片混合使用。

    切片通过:使用,单:就是包含所有

    4.1.5布尔索引

    In [149]: names                                                                                           
    Out[149]: array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'], dtype='<U4')
    
    In [150]: data                                                                                            
    Out[150]: 
    array([[-1.00710439, -1.69541524, -1.18684578,  0.09359326],
           [-1.28548156, -1.23123463,  2.15290595, -1.4515048 ],
           [-0.61391704,  0.65959513,  0.28808878,  0.58197308],
           [-0.73955125,  0.89556729,  0.99848676, -1.44457724],
           [ 0.44648024,  2.0481886 ,  0.01026874,  1.24072392],
           [-0.84346087, -1.41325766, -0.29533334,  0.89035935],
           [ 0.69944641, -0.74938503, -0.22261616,  1.42224533]])
    
    In [151]: 
    

     data的每一行对应每个人的信息

    In [152]: names == 'Bob'                                                                                  
    Out[152]: array([ True, False, False,  True, False, False, False])
    
    In [153]: data[names == 'Bob']                                                                            
    Out[153]: 
    array([[-1.00710439, -1.69541524, -1.18684578,  0.09359326],
           [-0.73955125,  0.89556729,  0.99848676, -1.44457724]])
    

     选取了'Bob'的数据之后,我们还可以通过索引于切片选择需要的信息

    In [157]: data[names == 'Bob', 2:]                                                                        
    Out[157]: 
    array([[-1.18684578,  0.09359326],
           [ 0.99848676, -1.44457724]])
    
    In [158]: data[names == 'Bob', 3]                                                                         
    Out[158]: array([ 0.09359326, -1.44457724])
    

     同!=于& | ~等操作符也可以进行一些多条件操作。

    使用布尔值索引选择数据时,总是生成数据的拷贝,即使返回的数据并没有发生任何变化。

    4.1.6神奇索引【魔术索引】

    就是用一个数组进行数据的索引。

    In [159]: arr = np.empty((8, 4)) 
         ...: for i in range(8): 
         ...:     arr[i] = i 
         ...: arr                                                                                             
    Out[159]: 
    array([[0., 0., 0., 0.],
           [1., 1., 1., 1.],
           [2., 2., 2., 2.],
           [3., 3., 3., 3.],
           [4., 4., 4., 4.],
           [5., 5., 5., 5.],
           [6., 6., 6., 6.],
           [7., 7., 7., 7.]])
    
    In [160]: arr[[4,3,0,6]]                                                                                  
    Out[160]: 
    array([[4., 4., 4., 4.],
           [3., 3., 3., 3.],
           [0., 0., 0., 0.],
           [6., 6., 6., 6.]])
    
    In [161]: arr[[-3,-5,-7]]                                                                                 
    Out[161]: 
    array([[5., 5., 5., 5.],
           [3., 3., 3., 3.],
           [1., 1., 1., 1.]])
    
    In [162]:  
    

    传递多个索引数组情况有些许不同,这样会根据每个索引元素对应的元素选出一个一个数组:

    In [162]: arr = np.arange(32).reshape((8, 4))                                                             
    
    In [163]: arr                                                                                             
    Out[163]: 
    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],
           [24, 25, 26, 27],
           [28, 29, 30, 31]])
    
    In [164]: arr[[1, 5, 7, 2], [0, 3, 1, 2]]                                                                 
    Out[164]: array([ 4, 23, 29, 10])
    
    In [165]: arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]]                                                              
    Out[165]: 
    array([[ 4,  7,  5,  6],
           [20, 23, 21, 22],
           [28, 31, 29, 30],
           [ 8, 11,  9, 10]])
    

     上面可以分成两步理解,第一步通过魔法索引取出需要的行,第二步,通过魔法索引调换列的位置。

    请牢记魔法索引于切片不同,它总是将数据复制到一个新的数组中。

    4.1.7数组转置和换轴

    可以通过T对二维数组进行转置

    In [184]: arr = np.arange(15).reshape((3, 5))                                                             
    
    In [185]: arr                                                                                             
    Out[185]: 
    array([[ 0,  1,  2,  3,  4],
           [ 5,  6,  7,  8,  9],
           [10, 11, 12, 13, 14]])
    
    In [186]: arr.T                                                                                           
    Out[186]: 
    array([[ 0,  5, 10],
           [ 1,  6, 11],
           [ 2,  7, 12],
           [ 3,  8, 13],
           [ 4,  9, 14]])
    

     np.dot会计算矩阵内积

    In [187]: arr = np.random.randn(6, 3)                                                                     
    
    In [188]: arr                                                                                             
    Out[188]: 
    array([[ 0.24976157,  0.31071076, -0.47578096],
           [-1.26412403, -0.43652115,  0.60267153],
           [-0.21745991,  1.73535988, -0.11671441],
           [ 0.86726475,  0.76131387,  0.80603824],
           [-1.59655193,  0.05412926,  0.04500314],
           [-0.55093819, -0.14713175,  1.3890123 ]])
    
    In [189]: np.dot(arr.T,arr)                                                                               
    Out[189]: 
    array([[ 5.31233831,  0.9069503 , -0.99336388],
           [ 0.9069503 ,  3.90274234, -0.20173437],
           [-0.99336388, -0.20173437,  3.18428085]])
    
    In [190]:      
    

     对于更高维度的数组,transpone方法可以接收包含轴编号的元祖,由于置换轴

    In [190]: arr = np.arange(16).reshape((2, 2, 4))                                                          
    
    In [191]: arr                                                                                             
    Out[191]: 
    array([[[ 0,  1,  2,  3],
            [ 4,  5,  6,  7]],
    
           [[ 8,  9, 10, 11],
            [12, 13, 14, 15]]])
    
    In [192]: arr.transpose((1,0,2))                                                                          
    Out[192]: 
    array([[[ 0,  1,  2,  3],
            [ 8,  9, 10, 11]],
    
           [[ 4,  5,  6,  7],
            [12, 13, 14, 15]]])
    
    In [193]:   
    

     看的有点晕,使用.T是进行转置换轴的一个特殊案例。ndarray有一个swapaxes方法,该方法接收一对轴编号作为参数,并对轴进行调整用于数据重组。

    In [199]: arr = np.arange(16).reshape((2, 2, 4))                                                          
    
    In [200]: arr                                                                                             
    Out[200]: 
    array([[[ 0,  1,  2,  3],
            [ 4,  5,  6,  7]],
    
           [[ 8,  9, 10, 11],
            [12, 13, 14, 15]]])
    
    In [201]: arr.swapaxes(1,2)                                                                               
    Out[201]: 
    array([[[ 0,  4],
            [ 1,  5],
            [ 2,  6],
            [ 3,  7]],
    
           [[ 8, 12],
            [ 9, 13],
            [10, 14],
            [11, 15]]])
    

     swapaxes返回的是数据的视图,二分没有数据进行复制。

    4.2通用函数:快速的逐元素数组函数

    通用函数,也可以称为ufunc,是一种是ndarray数据中进行逐元素操作的函数。某些简单函数接收一个或者多个标量数值,并产生一个或多个标量结果,而通用函数是对这些简单函数的向量化封装。

    简单的逐元素转换,也就是一元通用函数。

    In [202]: arr = np.arange(10)                                                                             
    
    In [203]: arr                                                                                             
    Out[203]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    In [204]: np.sqrt(arr)                                                                                    
    Out[204]: 
    array([0.        , 1.        , 1.41421356, 1.73205081, 2.        ,
           2.23606798, 2.44948974, 2.64575131, 2.82842712, 3.        ])
    
    In [205]: np.exp(arr)                                                                                     
    Out[205]: 
    array([1.00000000e+00, 2.71828183e+00, 7.38905610e+00, 2.00855369e+01,
           5.45981500e+01, 1.48413159e+02, 4.03428793e+02, 1.09663316e+03,
           2.98095799e+03, 8.10308393e+03])
    
    In [206]:  
    

     比如add或maximum则会接收两个数组并返回一个数组作为结果,称为二元通用函数:

    In [206]: x = np.random.randn(8)                                                                          
    
    In [207]: y = np.random.randn(8)                                                                          
    
    In [208]: np.maximum(x,y)                                                                                 
    Out[208]: 
    array([-0.38501671,  1.38583418,  1.58075387,  0.74666747, -0.61495016,
           -1.70572677,  0.55603417,  0.2539314 ])
    
    In [209]: x                                                                                               
    Out[209]: 
    array([-0.40859617, -2.57965322,  1.58075387,  0.74666747, -1.97264923,
           -1.70572677, -0.48024945,  0.2539314 ])
    
    In [210]: y                                                                                               
    Out[210]: 
    array([-0.38501671,  1.38583418, -2.23990722,  0.28165291, -0.61495016,
           -2.15174086,  0.55603417, -0.30538897])
    

     也有一些通用函数返回多个数组。比如modf,是Python内建函数divmod的向量化版本。它返回一个浮点值数组的小数部分和整数部分

    In [213]: arr = np.random.randn(7) * 5                                                                    
    
    In [214]: arr                                                                                             
    Out[214]: 
    array([ 0.77025919, -2.31969754,  3.19981579, -0.48684179, -1.1123567 ,
            5.08604258,  1.5711621 ])
    
    In [215]: remainder, whole_part = np.modf(arr)                                                            
    
    In [216]: remainder                                                                                       
    Out[216]: 
    array([ 0.77025919, -0.31969754,  0.19981579, -0.48684179, -0.1123567 ,
            0.08604258,  0.5711621 ])
    
    In [217]: whole_part                                                                                      
    Out[217]: array([ 0., -2.,  3., -0., -1.,  5.,  1.])
    

     通用函数独有一个可选参数out,进行输出

    In [245]: arr                                                                                             
    Out[245]: 
    array([ 0.77025919, -2.31969754,  3.19981579, -0.48684179, -1.1123567 ,
            5.08604258,  1.5711621 ])
    
    In [246]: np.sqrt(arr)                                                                                    
    /usr/local/bin/ipython:1: RuntimeWarning: invalid value encountered in sqrt
      #!/Library/Developer/CommandLineTools/usr/bin/python3
    Out[246]: 
    array([0.87764411,        nan, 1.78880289,        nan,        nan,
           2.25522562, 1.25346005])
    
    In [247]:                                                                                                 
    
    In [247]: np.sqrt(arr, arr)                                                                               
    /usr/local/bin/ipython:1: RuntimeWarning: invalid value encountered in sqrt
      #!/Library/Developer/CommandLineTools/usr/bin/python3
    Out[247]: 
    array([0.87764411,        nan, 1.78880289,        nan,        nan,
           2.25522562, 1.25346005])
    
    In [248]: arr                                                                                             
    Out[248]: 
    array([0.87764411,        nan, 1.78880289,        nan,        nan,
           2.25522562, 1.25346005])
    

    4.3使用数组进行面向数组编程

     4.3.1 将条件逻辑作为数组操作

    numpy.where函数是三元逼到事x if condition else y的向量化版本

    In [15]: xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
        ...: yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
        ...: cond = np.array([True, False, True, True, False])
    
    In [16]: result = [(x if c else y) for x, y, c in zip(xarr,yarr,cond)]
    
    In [17]: result
    Out[17]: [1.1, 2.2, 1.3, 1.4, 2.5]
    

     其实这个已经写的很不错了。

    但用numpy.where更快加

    In [15]: xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
        ...: yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
        ...: cond = np.array([True, False, True, True, False])
    
    In [16]: result = [(x if c else y) for x, y, c in zip(xarr,yarr,cond)]
    
    In [17]: result
    Out[17]: [1.1, 2.2, 1.3, 1.4, 2.5]
    
    In [18]: result = np.where(cond, xarr, yarr)
        ...: result
    Out[18]: array([1.1, 2.2, 1.3, 1.4, 2.5])
    
    In [19]: %timeit  [(x if c else y) for x, y, c in zip(xarr,yarr,cond)]
    1.83 µs ± 8.83 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    
    
    In [21]: %timeit  np.where(cond, xarr, yarr)
    1.26 µs ± 4.16 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    

    np.where的第二个和第三个参数并不需要是数组,它们可以是标量。where在数据分析的一个典型用法是根据一个数组来生成一个新的数据.

    In [22]: arr = np.random.randn(4,4,)
    
    In [23]: arr
    Out[23]: 
    array([[-0.97648403,  1.02798534, -0.93480427,  1.374078  ],
           [-1.84431231,  1.93422431,  0.00659856,  1.86583238],
           [ 1.08911163, -1.73644384, -0.45355162,  0.39349842],
           [ 0.10746774,  0.59731332,  0.72120852,  0.95930772]])
    
    In [24]: arr > 0
    Out[24]: 
    array([[False,  True, False,  True],
           [False,  True,  True,  True],
           [ True, False, False,  True],
           [ True,  True,  True,  True]])
    
    In [25]: np.where(arr>0,2,-2)
    Out[25]: 
    array([[-2,  2, -2,  2],
           [-2,  2,  2,  2],
           [ 2, -2, -2,  2],
           [ 2,  2,  2,  2]])
    
    In [26]: 
    

    4.3.2数学和统计方法

    聚合函数,比如sum,mean,std

    In [40]: arr = np.random.randn(5, 4)
    
    In [41]: arr
    Out[41]: 
    array([[ 0.56675129,  1.9773117 , -0.85703968,  1.52822419],
           [ 0.90498759,  0.54164539,  0.7010517 , -0.05463528],
           [ 0.08180353, -1.28173057,  0.15845745,  0.47208329],
           [-0.57725913, -0.70663686, -0.72830859,  1.22866412],
           [ 2.29306912, -0.75646038, -3.47690011, -0.58694743]])
    
    In [42]: arr.mean()
    Out[42]: 0.07140656664970654
    
    In [43]: np.mean(arr)
    Out[43]: 0.07140656664970654
    
    In [44]: arr.sum()
    Out[44]: 1.428131332994131
    
    In [45]: arr.mean(axis=1)
    Out[45]: array([ 0.80381187,  0.52326235, -0.14234658, -0.19588512, -0.6318097 ])
    
    In [46]: arr.mean(1)
    Out[46]: array([ 0.80381187,  0.52326235, -0.14234658, -0.19588512, -0.6318097 ])
    

     axis就是把该维度合并了,所以axis=1,表示把列维度合并了。

    In [48]: arr
    Out[48]: array([0, 1, 2, 3, 4, 5, 6, 7])
    
    In [49]: arr.cumsum()
    Out[49]: array([ 0,  1,  3,  6, 10, 15, 21, 28])
    
    In [50]: 
    
    In [52]: arr = np.arange(9).reshape(3,3,)
    
    In [53]: arr
    Out[53]: 
    array([[0, 1, 2],
           [3, 4, 5],
           [6, 7, 8]])
    
    In [54]: arr.cumsum(axis=0)
    Out[54]: 
    array([[ 0,  1,  2],
           [ 3,  5,  7],
           [ 9, 12, 15]])
    
    In [55]: arr.cumprod(1)
    Out[55]: 
    array([[  0,   0,   0],
           [  3,  12,  60],
           [  6,  42, 336]])
    
    In [56]: 
    

    4.3.3布尔值数组的方法

    In [58]: arr = np.random.randn(10000)
    
    In [59]: (arr>0).sum()
    Out[59]: 4923
    
    In [60]: np.count_nonzero(arr>0)
    Out[60]: 4923
    
    In [61]: 
    
    In [62]: arr.all()
    Out[62]: True
    
    In [63]: np.all(arr)
    Out[63]: True
    
    In [64]: arr.any()
    Out[64]: True
    

    4.3.4 排序

    和Python的内建列表类似,NumPy数组可以使用sort方法按位置排序

    In [72]: arr
    Out[72]: 
    array([ 0.21161757,  0.14908061, -0.60250355,  0.21311908, -0.97577853,
           -0.80022333])
    
    In [73]: arr.sort()
    
    In [74]: arr
    Out[74]: 
    array([-0.97577853, -0.80022333, -0.60250355,  0.14908061,  0.21161757,
            0.21311908])
    
    In [75]: arr = np.random.randn(5, 3)
    
    In [76]: arr
    Out[76]: 
    array([[ 1.0852479 , -0.1907266 , -1.31399142],
           [ 0.1200116 , -0.99438789, -0.52340313],
           [-0.72657845,  0.67799928,  0.0685691 ],
           [-1.20275342,  0.65808226, -0.09704002],
           [ 0.99616396,  0.96444138, -0.81331213]])
    
    In [77]: arr.sort(1)
    
    In [78]: arr
    Out[78]: 
    array([[-1.31399142, -0.1907266 ,  1.0852479 ],
           [-0.99438789, -0.52340313,  0.1200116 ],
           [-0.72657845,  0.0685691 ,  0.67799928],
           [-1.20275342, -0.09704002,  0.65808226],
           [-0.81331213,  0.96444138,  0.99616396]])
    
    In [79]: 
    

    4.3.5 唯一值与其他集合逻辑

    np.unique返回的是排好序的唯一值

    In [94]: names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])
    
    In [95]: np.unique(names)
    Out[95]: array(['Bob', 'Joe', 'Will'], dtype='<U4')
    
    In [96]: ints = np.array([3, 3, 3, 2, 2, 1, 1, 4, 4])
    
    In [97]: np.unique(ints)
    Out[97]: array([1, 2, 3, 4])
    

     返回一维数组的元素是否在另外一个元素内

    In [98]: values = np.array([6, 0, 0, 3, 2, 5, 6])
    
    In [99]: np.in1d(values,[2,3,4])
    Out[99]: array([False, False, False,  True,  True, False, False])
    

    4.4 使用数组进行文件输入和输出

    NumPy可以在硬盘中将数据以文本或二进制文件的形式进行存入硬盘或者硬盘载入。【一般用pandas】

    In [101]: arr = np.arange(10)
    
    In [102]: np.save('some_array', arr)
    
    In [103]: np.load('some_array.npy')
    Out[103]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    In [104]: 
    

    如果多个数据,可以通过np.savez的方式,后面通过关键字传参

    n [101]: arr = np.arange(10)
    
    In [102]: np.save('some_array', arr)
    
    In [103]: np.load('some_array.npy')
    Out[103]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    In [104]: np.savez('array_archive.npz',a=arr,b=arr)
    
    In [105]: arch = np.load('array_archive.npz')
    
    
    In [107]: arch['a']
    Out[107]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    In [108]: np.savez_compressed('arrays_compressed.npz',a=arr,b=arr)
    
    In [109]: arch = np.load('arrays_compressed.npz')
    
    In [110]: arch['b']
    Out[110]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    In [111]: ll *.npz
    -rw-r--r--  1 shijianzhong  staff  650 10 12 22:14 array_archive.npz
    -rw-r--r--  1 shijianzhong  staff  424 10 12 22:16 arrays_compressed.npz
    

    4.5 线性代数

    x.dot(y)点乘积可以用x@y表示。

    4.6伪随机数生成

    In [123]: samples = np.random.normal(size=(4,4))
    
    In [124]: samples
    Out[124]: 
    array([[ 1.22048664,  0.32098404, -0.03541593,  1.25904642],
           [-1.24029633,  1.31176221, -0.46916461, -0.18168937],
           [ 1.55699043,  0.49925716, -0.71558119,  1.60975006],
           [ 0.84303413, -0.86610878, -0.92012729, -1.17054933]])
    

    np.random.seed可以更改NumPy的随机数种子

    random.RandomState创建一个随机数生成器,使数据独立于其他随机数状态。

    4.7 示例:随机漫步

    In [125]: import random
         ...: position = 0
         ...: walk = [position]
         ...: steps = 1000
         ...: for i in range(steps):
         ...:     step = 1 if random.randint(0, 1) else -1
         ...:     position += step
         ...:     walk.append(position)
         ...: 
    
    In [126]: import matplotlib.pyplot as plt
    
    In [127]: plt.figure()
    Out[127]: <Figure size 640x480 with 0 Axes>
    
    In [128]: plt.plot(walk[:100])
    Out[128]: [<matplotlib.lines.Line2D at 0x121389320>]
    

     好无聊的试验。

    4.7.1一次性模拟多次随机漫步

    模拟多次5000次的情况,也就使多行数据

    In [5]: nwalks = 5000
       ...: nsteps = 1000
       ...: draws = np.random.randint(0, 2, size=(nwalks, nsteps)) # 0 or 1
       ...: steps = np.where(draws > 0, 1, -1)
       ...: walks = steps.cumsum(1)
       ...: walks
    Out[5]: 
    array([[ -1,  -2,  -1, ..., -58, -57, -58],
           [  1,   2,   3, ...,  34,  33,  32],
           [ -1,  -2,  -3, ..., -16, -17, -16],
           ...,
           [  1,   0,  -1, ...,  44,  43,  44],
           [  1,   2,   1, ...,  18,  17,  16],
           [  1,   0,  -1, ...,  40,  39,  40]])
    

    计算这些随机满足的最大值于最小值

    In [28]: walks.max()
    Out[28]: 102
    
    In [29]: walks.min()
    Out[29]: -121
    

     统计有达到累计30的

    In [30]: hits30 = (np.abs(walks)>30).any(1)
    
    
    In [33]: hits30
    Out[33]: array([ True,  True,  True, ...,  True, False,  True])
    
    In [34]: hits30.sum()
    Out[34]: 3238
    

     通过any生成生成结果,并通过sum对结果进行求和

    开始求穿越花费的时间。

    # 选出走到了30步以上的行,再次通过>=0转换成bool索引,通过argmax(1),选出首次出现索引。
    In [35]: crossing_times = (np.abs(walks[hits30]) >=30).argmax(1)
    
    In [36]: crossing_times
    Out[36]: array([569, 923, 429, ..., 743, 523, 809])
    
    In [37]: crossing_times.mean()
    Out[37]: 496.17850525015444
    
    In [38]: 
    
  • 相关阅读:
    BZOJ3105: [cqoi2013]新Nim游戏 博弈论+线性基
    BZOJ3759: Hungergame 博弈论+线性基
    NOI模拟赛Day2
    期望dp BZOJ3450+BZOJ4318
    NOI模拟赛 Day1
    NOI模拟 热身赛T1
    【BZOJ4260】 Codechef REBXOR 可持久化Trie
    【BZOJ3673】&&【BZOJ3674】: 可持久化并查集 by zky 可持久化线段树
    【BZOJ3207】花神的嘲讽计划I 可持久化线段树/莫队
    【bzoj3527】[Zjoi2014]力 FFT
  • 原文地址:https://www.cnblogs.com/sidianok/p/13800918.html
Copyright © 2020-2023  润新知