Python NumPyチュートリアル

11781 ワード

基礎編
NumPyの主なオブジェクトは同種要素の多次元配列である.これは、すべての要素がタイプで、正の整数メタグループインデックスを通過する要素テーブルです(通常、要素は数値です).NumPyでは次元(dimensions)を軸(axes)と呼び,軸の個数をランク(rank)と呼ぶ.
例えば、3 D空間における1点の座標[1,2,3]は、軸が1つしかないため、1ランクの配列である.その軸の長さは3である.また、例えば、以下の例では、配列のランクは2(2次元)である.1番目の次元の長さは2で、2番目の次元の長さは3です.
[[ 1., 0., 0.],
 [ 0., 1., 2.]] 

NumPyの配列クラスをndarrayと呼ぶ.通常は配列と呼ばれます.気をつけてArrayと標準Pythonライブラリクラスarray.arrayは異なり,後者は1次元配列のみを処理し,少量の機能を提供する.さらに重要なndarrayオブジェクトのプロパティは、次のとおりです.
  • ndarray.ndim配列軸の個数pythonの世界では軸の個数をランク
  • と呼ぶ.
  • ndarray.shape配列の次元.これは、配列の各次元のサイズを示す整数メタグループです.例えば、n列m列のマトリクスは、shape属性が(2,3)であり、このメタグループの長さは明らかにランク、すなわち次元またはndim属性
  • である.
  • ndarray.size配列要素の合計個数は、shape属性のメタグループ要素の積に等しい.
  • ndarray.dtype配列内の要素タイプを記述するオブジェクトで、dtypeが標準Pythonタイプを使用することを作成または指定できます.また、NumPyは独自のデータ型を提供します.
  • ndarray.itemsize配列の各要素のバイトサイズ.例えば、1つの要素タイプがfloat 64の配列itemsiz属性値は8(=64/8)である、また、1つの要素タイプがcomplex 32の配列item属性は4(=32/8)である.
  • ndarray.dataには実際の配列要素のバッファが含まれています.通常、この属性を使用する必要はありません.なぜなら、配列内の要素は常にインデックスによって使用されるからです.

  • 栗:
    In [2]: from  numpy  import * 
    
    In [3]: a = arange(15).reshape(3,5)
    
    In [4]: a
    Out[4]: 
    array([[ 0,  1,  2,  3,  4],
           [ 5,  6,  7,  8,  9],
           [10, 11, 12, 13, 14]])
    
    In [5]: a.shape 
    Out[5]: (3, 5)
    
    In [6]: a.ndim
    Out[6]: 2
    
    In [7]: a.dtype.name 
    Out[7]: 'int64'
    
    In [8]: a.itemsize
    Out[8]: 8
    
    In [9]: a.size
    Out[9]: 15
    
    In [10]: type(a) 
    Out[10]: numpy.ndarray
    
    In [11]: b = array([6,7,8])
    
    In [12]: b
    Out[12]: array([6, 7, 8])
    
    In [13]: type(b) 
    Out[13]: numpy.ndarray
    

    配列の作成
    配列を作成する方法はいくつかあります.たとえば、array関数を使用して、通常のPythonリストのメタグループから配列を作成できます.作成された配列タイプは、元のシーケンスの要素タイプから導出されます.
    In [14]: from  numpy import * 
    
    In [15]: a = array([2,3,4])
    
    In [16]: a
    Out[16]: array([2, 3, 4])
    
    In [17]: a.dtype
    Out[17]: dtype('int64')
    
    In [18]: b = array([1.2,3.5,5.1]) 
    
    In [19]: b.dtype
    Out[19]: dtype('float64')
    

    一般的なエラーには、数値からなるリストをパラメータとして提供するのではなく、arrayを複数の数値パラメータで呼び出すことが含まれます.
    In [20]: a = array(1,2,3,4) 
    ---------------------------------------------------------------------------
    ValueError                                Traceback (most recent call last)
     in ()
    ----> 1 a = array(1,2,3,4)
    
    ValueError: only 2 non-keyword arguments accepted
    
    In [21]: a = array([1,2,3,4]) 
    

    配列は、配列を含む配列を2次元の配列に変換し、配列を含む配列は、配列を含む配列を含む3次元の配列に変換するなどします.
    In [22]: b = array([(1.5,2,3),(4,5,6)]) 
    
    In [23]: b
    Out[23]: 
    array([[ 1.5,  2. ,  3. ],
           [ 4. ,  5. ,  6. ]])
    

    配列タイプは、作成時に指定を表示できます.
    In [24]: c = array([[1,2],[3,4]],dtype=complex)
    
    In [25]: c
    Out[25]: 
    array([[ 1.+0.j,  2.+0.j],
           [ 3.+0.j,  4.+0.j]])
    

    通常、配列の要素の開始は不明ですが、そのサイズは既知です.したがって、NumPyは、プレースホルダを使用して配列を作成する関数をいくつか提供します.これは拡張配列の必要性と高い演算コストを最小化する.
    関数functionは全0の配列を作成し、関数onesは全1の配列を作成し、関数emptyは内容がランダムでメモリ状態に依存する配列を作成します.デフォルトで作成される配列タイプ(dtype)はfloat 64です.
    In [26]: zeros( (3,4) )
    Out[26]: 
    array([[ 0.,  0.,  0.,  0.],
           [ 0.,  0.,  0.,  0.],
           [ 0.,  0.,  0.,  0.]])
    
    In [27]: ones( (2,3,4), dtype=int16 ) 
    Out[27]: 
    array([[[1, 1, 1, 1],
            [1, 1, 1, 1],
            [1, 1, 1, 1]],
    
           [[1, 1, 1, 1],
            [1, 1, 1, 1],
            [1, 1, 1, 1]]], dtype=int16)
    
    In [28]: empty( (2,3) )
    Out[28]: 
    array([[ 0.,  0.,  0.],
           [ 0.,  0.,  0.]])
    

    数列を作成するには、NumPyはaranggeのような関数を提供し、リストではなく配列を返します.
    In [29]: arange(10,30,5) 
    Out[29]: array([10, 15, 20, 25])
    
    In [30]: arange(0,2,0.3)    # it accepts float arguments
    Out[30]: array([ 0. ,  0.3,  0.6,  0.9,  1.2,  1.5,  1.8])
    

    arangが浮動小数点数パラメータを使用する場合、有限な浮動小数点数精度のため、通常、得られる要素個数を予測することはできない.したがって、rangeでステップ長を指定する代わりに、関数linspaceを使用して、目的の要素の個数を受信することが望ましい.
    プリント配列
    配列を印刷すると、NumPyはネストされたリストのように表示されますが、次のレイアウトになります.
  • 最後の軸左から右へ
  • を印刷する.
  • 回後の軸を上から下へ
  • 印刷する.
  • 残りの軸は、上から下に印刷する、各スライスは、1つの空白行を介して次の
  • から離間する.
    1次元配列は行に印刷され,2次元数は行列を構成し,3次元数は行列リストを構成する.
    In [31]: a = arange(6) 
    
    In [32]: print(a) 
    [0 1 2 3 4 5]
    
    In [33]: b = arange(12).reshape(4,3) 
    
    In [34]: print(b) 
    [[ 0  1  2]
     [ 3  4  5]
     [ 6  7  8]
     [ 9 10 11]]
    
    In [35]: c = arange(24).reshape(2,3,4) 
    
    In [36]: print(c) 
    [[[ 0  1  2  3]
      [ 4  5  6  7]
      [ 8  9 10 11]]
    
     [[12 13 14 15]
      [16 17 18 19]
      [20 21 22 23]]]
    

    配列が大きすぎると、NumPyは自動的に中間部分を省略し、隅だけを印刷します.
    In [37]: print(arange(10000))
    [   0    1    2 ..., 9997 9998 9999]
    
    In [38]: print(arange(10000).reshape(100,100))
    [[   0    1    2 ...,   97   98   99]
     [ 100  101  102 ...,  197  198  199]
     [ 200  201  202 ...,  297  298  299]
     ..., 
     [9700 9701 9702 ..., 9797 9798 9799]
     [9800 9801 9802 ..., 9897 9898 9899]
     [9900 9901 9902 ..., 9997 9998 9999]]
    

    NumPyのこの動作を無効にし、配列全体を強制的に印刷すると、printoptionsパラメータを設定して印刷オプションを変更できます.
    >>> set_printoptions(threshold='nan') 
    

    きほんえんざん
    配列の演算は要素別です.新しい配列が作成され、結果が埋め込まれます.
    In [1]: from numpy import  * 
    
    In [2]: a = array([20,30,40,50]) 
    
    In [3]: b = arange(4) 
    
    In [4]: b 
    Out[4]: array([0, 1, 2, 3])
    
    In [5]: c = a - b 
    
    In [6]: c 
    Out[6]: array([20, 29, 38, 47])
    
    In [7]: b**2
    Out[7]: array([0, 1, 4, 9])
    
    In [8]: 10*sin(a) 
    Out[8]: array([ 9.12945251, -9.88031624,  7.4511316 , -2.62374854])
    
    In [9]: a<35
    Out[9]: array([ True,  True, False, False], dtype=bool)
    

    多くの行列言語とは異なり、NumPyの乗算演算子*は要素で計算されることを示し、行列乗算はdot関数を使用するか、行列オブジェクトを作成して実装することができます.
    In [10]: A = array([[1,1],[0,1]]) 
    
    In [11]: B = array([[2,0],[3,4]]) 
    
    In [12]: A*B
    Out[12]: 
    array([[2, 0],
           [0, 4]])
    
    In [13]: dot(A,B) 
    Out[13]: 
    array([[5, 4],
           [3, 4]])
    

    一部のオペレータは、新しい配列を作成するのではなく、既存の配列を変更するために+=と*=のように使用されます.
    In [14]: a = ones((2,3),dtype=int)
    
    In [15]: a
    Out[15]: 
    array([[1, 1, 1],
           [1, 1, 1]])
    
    In [16]: b = random.random((2,3))
    
    In [17]: b
    Out[17]: 
    array([[ 0.59203579,  0.33035089,  0.77216489],
           [ 0.57561703,  0.73380547,  0.10118917]])
    
    In [18]: a *=3
    
    In [19]: a
    Out[19]: 
    array([[3, 3, 3],
           [3, 3, 3]])
    
    In [20]: b += a 
    
    In [21]: b
    Out[21]: 
    array([[ 3.59203579,  3.33035089,  3.77216489],
           [ 3.57561703,  3.73380547,  3.10118917]])
    
    In [22]: a += b 
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
     in ()
    ----> 1 a += b
    
    TypeError: Cannot cast ufunc add output from dtype('float64') to dtype('int64') with casting rule 'same_kind'
    

    異なるタイプの配列を演算する場合、結果配列とより一般的で正確な既知(upcastと呼ばれる)がある.
    In [24]: a = ones(3,dtype=int32)
    
    In [25]: b = linspace(0,pi,3)
    
    In [26]: b.dtype.name
    Out[26]: 'float64'
    
    In [27]: c = a + b 
    
    In [28]: c 
    Out[28]: array([ 1.        ,  2.57079633,  4.14159265])
    
    In [29]: c.dtype.name
    Out[29]: 'float64'
    
    In [30]: d = exp(c*1j) 
    
    In [31]: d 
    Out[31]: 
    array([ 0.54030231+0.84147098j, -0.84147098+0.54030231j,
           -0.54030231-0.84147098j])
    
    In [32]: d.dtype.name
    Out[32]: 'complex128'
    'complex128'        ,           ,   ndarray      
    
    In [33]: a = random.random((2,3))
    
    In [34]: a
    Out[34]: 
    array([[ 0.47405377,  0.3554812 ,  0.77247355],
           [ 0.28015991,  0.28447145,  0.27666715]])
    
    In [35]: a.sum()
    Out[35]: 2.4433070197253133
    
    In [36]: a.min()
    Out[36]: 0.27666714728871389
    
    In [37]: a.max()
    Out[37]: 0.77247354602573004
    

    これらの演算は、配列の形状に関係なく、数値からなるリストのように配列にデフォルトで適用されます.しかし、axisパラメータを指定すると、配列が指定した軸に演算を適用できます.
    In [38]: b = arange(12).reshape(3,4) 
    
    In [39]: b
    Out[39]: 
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    
    In [40]: b.sum(axis=0)   # sum of each column
    Out[40]: array([12, 15, 18, 21])
    
    In [41]: b.min(axis=1)   # min of each row
    Out[41]: array([0, 4, 8])
    
    In [42]: b.cumsum(axis=1)   # cumulative sum along each rowOut[42]: 
    array([[ 0,  1,  3,  6],
           [ 4,  9, 15, 22],
           [ 8, 17, 27, 38]])
    
    

    汎用関数(ufunc)
    NumPyはsin,cos,expのような一般的な数学関数を提供する.NumPyでは、これらを「汎用関数」(ufunc)と呼ぶ.NumPyではこれらの関数が配列の要素で演算され,出力として配列が生成される.
    In [43]: B = arange(3) 
    
    In [44]: B 
    Out[44]: array([0, 1, 2])
    
    In [45]: exp(B) 
    Out[45]: array([ 1.        ,  2.71828183,  7.3890561 ])
    
    In [46]: sqrt(B) 
    Out[46]: array([ 0.        ,  1.        ,  1.41421356])
    
    In [47]: C = array([2.,-1,4.]) 
    
    In [48]: add(B,c) 
    Out[48]: array([ 1.        ,  3.57079633,  6.14159265])
    

    より多くの関数all,alltrue,any,apply along axis,argmax,argmax,argmin,argsort,average,bincount,ceil,clip,conj,conjugate, corcoef,cov,cross,cumprod,cumsum,diff,dot,floor,inner,inv,lexsort,max,maximum,mean,mean,median,min,minimum,nonzero,outer,prod,re,round d,sum,trace,transpose,var,vdot,vectorize,where参照:[NumPy例]
    索引、スライス、反復
    1次元配列は、リストや他のPythonシーケンスのようにインデックス、スライス、反復することができます.
    In [49]: a = arange(10)**3 
    
    In [50]: a 
    Out[50]: array([  0,   1,   8,  27,  64, 125, 216, 343, 512, 729])
    
    In [51]: a[2] 
    Out[51]: 8
    
    In [52]: a[2:5] 
    Out[52]: array([ 8, 27, 64])
    
    In [53]: a[:6:2] = -1000 
    
    In [54]: a 
    Out[54]: array([-1000,     1, -1000,    27, -1000,   125,   216,   343,   512,   729])
    
    In [55]: a[::-1]
    Out[55]: array([  729,   512,   343,   216,   125, -1000,    27, -1000,     1, -1000])
    
    In [56]: for i in a:
        ...:     print(i**(1/3.),)
        ...:     
    /usr/local/bin/ipython:2: RuntimeWarning: invalid value encountered in power
      
    nan
    1.0
    nan
    3.0
    nan
    5.0
    6.0
    7.0
    8.0
    9.0
    

    多次元データは、各軸にインデックスを付けることができます.これらのインデックスは、カンマで分割されたメタグループによって与えられます.
    In [57]: def f(x,y):
        ...:     return 10*x + y 
        ...: 
    
    In [58]: b = fromfunction(f,(5,4),dtype=int)
    
    In [59]: b
    Out[59]: 
    array([[ 0,  1,  2,  3],
           [10, 11, 12, 13],
           [20, 21, 22, 23],
           [30, 31, 32, 33],
           [40, 41, 42, 43]])
    
    In [60]: b[2,3] 
    Out[60]: 23
    
    In [61]: b[0:5,1]      # each row in the second column of b
    Out[61]: array([ 1, 11, 21, 31, 41])
    
    In [62]: b[ : ,1]     # equivalent to the previous example
    Out[62]: array([ 1, 11, 21, 31, 41])
    
    In [63]: b[1:3,:]    # each column in the second and third row of b
    Out[63]: 
    array([[10, 11, 12, 13],
           [20, 21, 22, 23]])
    

    軸数より少ないインデックスが提供されると、失われたインデックスはスライス全体とみなされます.
    In [64]: b[-1]      # the last row. Equivalent to b[-1,:]
    Out[64]: array([40, 41, 42, 43])
    

    b[i]中括弧の式は、残りの軸を表すiと一連として扱われる.NumPyでは、b[i,...]のような「点」も使用できます.
    ポイント(...)は、完全なインデックスメタグループを生成するために必要な多くのセミコロンを表します.xがランク5の配列(すなわち、5つの軸)である場合、
  • x[1,2,...]はx[1,2,:,:,:],
  • に等しい
  • x[...,3]はx[:,:,:,:,3]
  • に等しい
  • x[4,...,5,:]同等x[4,:,:,5,:].
  •  >>> c = array( [ [[ 0, 1, 2], # a 3D array (two stacked 2D arrays) ... [ 10, 12, 13]], ... ... [[100,101,102], ... [110,112,113]] ] ) >>> c.shape (2, 2, 3) >>> c[1,...] # same as c[1,:,:] or c[1] array([[100, 101, 102], [110, 112, 113]]) >>> c[...,2] # same as c[:,:,2] array([[ 2, 13], [102, 113]]) 
    

    反復多次元配列は、第1の軸についてです.
    In [65]: for row in b:
        ...:     print(row) 
        ...:     
    [0 1 2 3]
    [10 11 12 13]
    [20 21 22 23]
    [30 31 32 33]
    [40 41 42 43]
    

    ただし、各配列の要素を演算したい場合は、flat属性を使用します.この属性は配列要素の反復器です.
    In [67]: for element in b.flat:
        ...:     print(element)
        ...:      
    0
    1
    2
    3
    10
    11
    12
    13
    20
    21
    22
    23
    30
    31
    32
    33
    40
    41
    42
    43
    

    詳細[],...,newaxis,ndenumerate,indices,index exp参照[NumPy例]
    シェイプ操作
    配列の変更