pythonデータ解析-NumPy(二)

75325 ワード

1.NumPy配列基盤
pythonでのデータ操作はほぼNumPy配列操作と同等であり,もう一つの重要なツールパッケージpandasもNumpy配列の基礎の上に構築されている.
1.1 NumPy配列の属性
まず、3つのランダムな配列を定義します.1次元配列、2次元配列、3次元配列です.
In[1]: import numpy as np
	   np.random.seed(0) #        
	   x1 = np.random.randint(10,size=6) #     
	   x2 = np.random.randint(10,size=(3,4)) #     
	   x3 = np.random.randint(10,size=(3,4,5)) #     

各配列にはnidm(配列の次元)、shape(配列の各次元のサイズ)、size(配列の合計サイズ)属性があります.
In[2]: print("x3 ndim:",x3.ndim)
	   print("x3 shape:",x3.shape)
	   print("x3 size:",x3.size)
x3 ndim: 3
x3 shape: (3, 4, 5)
x3 size: 60

もう1つの有用な属性はdtypeであり、配列のデータ型である.
In[3]: print("dtype:",x3.dtype)
dtype: int64

その他の属性には、各配列要素のバイトサイズを表すitemsizeと、配列の合計バイトサイズを表す属性nbytesが含まれます.
In[4]: print("itemsize:",x3.itemsize,"bytes")
	   print("nbytes:",x3.nbytes,"bytes")
itemsize: 8 bytes
nbytes: 480 bytes

一般にitemsizeとsizeの積の大きさとnbytesは等しいと考えられる.
1.2配列インデックス:単一要素を取得する
単一要素のインデックスを取得する方法はpythonの標準リストインデックスと変わりません.1次元配列では、次のようになります.
  • 中括弧指定インデックスによりi番目の値(0からカウント)
  • を取得する.
  • 配列の末尾インデックスを取得し、負の値インデックス
  • を使用できます.
    多次元配列では、カンマで区切られた索引元祖を使用して要素を取得できます.
    In [5]: x2
    Out[5]: 
    array([[5, 0, 3, 3],
           [7, 9, 3, 5],
           [2, 4, 7, 6]])
    
    In [6]: x2[2,3]
    Out[6]: 6
    
    In [7]: x2[2,-1]
    Out[7]: 6
    

    要素の値は、上記のインデックスで変更することもできます.
    In [8]: x2[2,3] = 1
    
    In [9]: x2
    Out[9]: 
    array([[5, 0, 3, 3],
           [7, 9, 3, 5],
           [2, 4, 7, 1]])
    

    注意:Numpy配列は固定型であり、浮動小数点値を整数配列に挿入すると、浮動小数点値が整数に短縮されます.そして、このような短い時間で自動的に完成したものは、ヒントや警告を与えません.
    In [11]: x1[0] = 3.14159 #      
    
    In [12]: x1
    Out[12]: array([3, 8, 1, 6, 7, 7])
    

    1.3配列スライス:サブ配列を取得する
    NumPyスライス構文はpythonリストのマルチスタンダードスライス構文と同じで、配列xのスライスを取得するには、次のように使用できます.x[start:stop:step]
    以上の3つのパラメータが指定する場合、デフォルト値start=0、stop=次元のサイズ、step=1がそれぞれ設定される.
    1.3.1次元サブ配列
    In [18]: x = np.arange(10)
    
    In [19]: x
    Out[19]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    In [20]: x[:5] #  5   
    Out[20]: array([0, 1, 2, 3, 4])
    
    In [21]: x[5:] #  5     
    Out[21]: array([5, 6, 7, 8, 9])
    
    In [22]: x[4:7] #      
    Out[22]: array([4, 5, 6])
    
    In [23]: x[::2] #       
    Out[23]: array([0, 2, 4, 6, 8])
    
    In [24]: x[1::2] #      ,   1  
    Out[24]: array([1, 3, 5, 7, 9])
    

    ステップ値stepは負で、非常に便利な逆順序です.
    In [25]: x[::-1] #     ,  
    Out[25]: array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
    
    In [26]: x[5::-2] #    5  ,        
    Out[26]: array([5, 3, 1])
    

    1.3.2多次元サブ配列
    多次元スライスも同様に処理し,コロンで区切る.
    In [27]: x2
    Out[27]: 
    array([[5, 0, 3, 3],
           [7, 9, 3, 5],
           [2, 4, 7, 1]])
    
    In [28]: x2[:2,:3]  #  ,  
    Out[28]: 
    array([[5, 0, 3],
           [7, 9, 3]])
    
    In [29]: x2[:,::2]  #   ,    
    Out[29]: 
    array([[5, 3],
           [7, 3],
           [2, 7]])
    

    サブ配列は、同時に逆順序にすることもできます.
    In [30]: x2[::-1,::-1]
    Out[30]: 
    array([[1, 7, 4, 2],
           [5, 3, 9, 7],
           [3, 3, 0, 5]])
    

    1.3.3配列の行と列の取得
    1つの一般的な要件は、配列の1つの行と1つの列を取得し、インデックスとスライスを組み合わせて実現することです.
    In [27]: x2
    Out[27]: 
    array([[5, 0, 3, 3],
           [7, 9, 3, 5],
           [2, 4, 7, 1]])
    
    In [31]: print(x2[:,0]) # x2    
    [5 7 2]
    In [32]: print(x2[0,:]) # x2    
    [5 0 3 3]
    

    ローを取得するときは、構文の簡潔性のため、空のスライスを省略できます.
    In [33]: print(x2[0])
    [5 0 3 3]
    

    1.3.4非レプリカビューのサブ配列
    Numpy配列スライスは、pythonリストスライスのような値のコピーではなく、配列データのビューを返します.したがって,スライスしたサブ配列を直接修正すると,元の配列も修正される.
    In [43]: x2
    Out[43]: 
    array([[5, 0, 3, 3],
           [7, 9, 3, 5],
           [2, 4, 7, 1]])
    
    In [44]: x2_sub = x2[:2,:2]
    #   
    In [45]: print(x2_sub)
    [[5 0]
     [7 9]]
    #     
    In [46]: x2_sub[0,0] = 99
    
    In [47]: x2
    Out[47]: 
    array([[99,  0,  3,  3],
           [ 7,  9,  3,  5],
           [ 2,  4,  7,  1]])
    

    このデフォルトの処理は、最下位のデータキャッシュをコピーすることなく、非常に大きなデータセットを処理するときに、これらのデータセットのクリップを取得または処理できることを意味します.
    1.3.5配列のコピーの作成
    ビジネスによっては、配列内のデータやサブ配列のコピーも非常に有用であり、copy()の方法で実現される場合があります.
    In [47]: x2
    Out[47]: 
    array([[99,  0,  3,  3],
           [ 7,  9,  3,  5],
           [ 2,  4,  7,  1]])
    
    In [48]: x2_sub_copy = x2[:2,:2].copy()
    
    In [49]: print(x2_sub_copy)
    [[99  0]
     [ 7  9]]
    

    このサブ配列を変更すると、元の配列は変更されません.
    In [50]: x2_sub_copy[0,0] = 18
    
    In [51]: print(x2_sub_copy)
    [[18  0]
     [ 7  9]]
    
    In [52]: x2
    Out[52]: 
    array([[99,  0,  3,  3],
           [ 7,  9,  3,  5],
           [ 2,  4,  7,  1]])
    

    1.4配列の変形
    Numpy配列の変形の最も柔軟な実現方式はreshape()関数によって実現する.
    In [53]: grid = np.arange(1,10).reshape((3,3))
    
    In [54]: print(grid)
    [[1 2 3]
     [4 5 6]
     [7 8 9]]
    

    元の配列のサイズは、変形後の配列のサイズと一致する必要があります.
    この条件を満たすと、reshapeメソッドは元の配列の非レプリカビューを使用しますが、実際には、非連続データキャッシュの場合、非レプリカビューを返すことはできません.
    さらに一般的なモード:1次元配列を2次元の行または列のマトリクスに変換します.
    In [62]: x = np.array([1,2,3])
    #          
    In [63]: x.reshape((1,3))
    Out[63]: array([[1, 2, 3]])
    #  newaxis      
    In [64]: x[np.newaxis,:]
    Out[64]: array([[1, 2, 3]])
    
    #          
    In [66]: x.reshape((3,1))
    Out[66]: 
    array([[1],
           [2],
           [3]])
    #   newaxis      
    In [67]: x[:,np.newaxis]
    Out[67]: 
    array([[1],
           [2],
           [3]])
    

    1.4配列の接合と分裂
    1.4.1配列の接合
    NumPyの中の2つの配列をつなぎ合わせるか接続するのは主にnpである.concatenate、np.vstackとnp.hstack実現.np.concatenate配列タプルまたは配列リストを最初のパラメータとします.
    In [68]: x = np.array([1,2,3])
    
    In [69]: y = np.array([3,2,1])
    #   2   
    In [70]: np.concatenate([x,y])
    Out[70]: array([1, 2, 3, 3, 2, 1])
    
    In [71]: z = [6,6,6]
    #             
    In [72]: print(np.concatenate([x,y,z]))
    [1 2 3 3 2 1 6 6 6]
    
    np.concatenateは、2 D配列の接合にも使用できます.
    In [73]: grid = np.array([[1,2,3],
                              [4,5,6]])
                      
    #         
    In [74]: np.concatenate([grid,grid])
    Out[74]: 
    array([[1, 2, 3],
           [4, 5, 6],
           [1, 2, 3],
           [4, 5, 6]])
    #        ( 0    )
    In [75]: np.concatenate([grid,grid],axis=1)
    Out[75]: 
    array([[1, 2, 3, 1, 2, 3],
           [4, 5, 6, 4, 5, 6]])
    

    配列を固定次元に沿って処理する場合、np.vstack(垂直スタック)およびnp.hstack(水平スタック)関数を使用すると、より簡潔になります.
    In [76]: x = np.array([1,2,3])
    
    In [79]: grid = np.array([[9,8,7],
                              [6,5,4]])
                    
    #      
    In [80]: np.vstack([x,grid])
    Out[80]: 
    array([[1, 2, 3],
           [9, 8, 7],
           [6, 5, 4]])
    
    In [81]: y = np.array([[99],
                           [99]])              
    #      
    In [82]: np.hstack([grid,y])
    Out[82]: 
    array([[ 9,  8,  7, 99],
           [ 6,  5,  4, 99]])
    
    np.dstackは、第3の次元に沿って配列を接合する
    1.4.2配列の分裂
    分割は、パラメータとして、np.splitnp.hsplit、およびnp.vsplitの関数によって実現することができ、インデックスリストは、分割点位置を記録するインデックスリストを伝達することができる.
    In [83]: x = [1,2,3,99,99,3,2,1]
    
    In [84]: x1,x2,x3 = np.split(x,[3,5])
    
    In [85]: print(x1,x2,x3)
    [1 2 3] [99 99] [3 2 1]
    

    注意:N分裂点はN+1サブ配列を得る.
    In [86]: grid = np.arange(16).reshape((4,4))
    
    In [87]: grid
    Out[87]: 
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11],
           [12, 13, 14, 15]])
    #       
    In [88]: upper,lower = np.vsplit(grid,[2])
    
    In [90]: print(upper)
    [[0 1 2 3]
     [4 5 6 7]]
    
    In [91]: print(lower)
    [[ 8  9 10 11]
     [12 13 14 15]]
    #       
    In [92]: left,right = np.hsplit(grid,[3])
    
    In [93]: print(left)
    [[ 0  1  2]
     [ 4  5  6]
     [ 8  9 10]
     [12 13 14]]
    
    In [94]: print(right)
    [[ 3]
     [ 7]
     [11]
     [15]]
    

    同様に、np.dsplitは配列を第3の次元に沿って分裂させる.