読者です 読者をやめる 読者になる 読者になる

どらちゃんのポッケ

R・統計・技術メモなど勉強ログ置き場

pythonによるデータ分析入門を写経していく(numpyの使い方)

  • この本

numpyの配列の生成

  • pythonの配列を np.array()に渡して上げる

      In [337]: data1 = [1,2,3,4,5]
    
      In [338]: a = np.array(data1)
    
      In [339]: a
      Out[339]: array([1, 2, 3, 4, 5])
    

配列の計算

  • Rと同じ感じ

      In [332]: data = array([[1,2,3],[4,5,6]])
    
      In [333]: data
      Out[333]:
      array([[1, 2, 3],
             [4, 5, 6]])
    
      In [334]: data * 10
      Out[334]:
      array([[10, 20, 30],
             [40, 50, 60]])
    

配列の構造とデータ型の取得

  • array.shapeで構造、array.dtypeで型を取得できる

      In [335]: data.shape
      Out[335]: (2, 3)
    
      In [336]: data.dtype
      Out[336]: dtype('int64')
    

配列の初期化

  • numpy.zeros()でゼロ埋めの初期化

    • 単一の数字で渡すと、その数分だけ生成される
    • タプルで渡すと、多次元配列が可能

        In [349]: np.zeros(10)
        Out[349]: array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])
      
        In [350]: np.zeros((2,3))
        Out[350]:
        array([[ 0.,  0.,  0.],
               [ 0.,  0.,  0.]])
      
  • numpy.ones()で1埋め

      In [352]: np.ones((2,3))
      Out[352]:
      array([[ 1.,  1.,  1.],
             [ 1.,  1.,  1.]])
    
  • numpy.empty()で何かしらの数字埋め

      In [353]: np.empty((2,3))
      Out[353]:
      array([[ -2.00000000e+000,   1.49457443e-154,   2.13643686e-314],
             [  2.13643937e-314,   2.13643940e-314,   4.21536564e-309]])
    
  • numpy.arange()で等差数列

      In [354]: np.arange(10)
      Out[354]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
      In [355]: a = np.array([[1,2,3], [2,3,4]])
    
  • np.zeros_like()である配列と同じ行列のフォーマットで0埋めした別の配列を生成する

      In [356]: np.zeros_like(a)
      Out[356]:
      array([[0, 0, 0],
             [0, 0, 0]])
    
  • np.identity(n)でN×Nの行列を生成する(正方形となる行列)

     In [357]: np.identity(3)
      Out[357]:
      array([[ 1.,  0.,  0.],
             [ 0.,  1.,  0.],
             [ 0.,  0.,  1.]])
    

型変換

  • astype()でキャストして型変換することが可能

      In [358]: a
      Out[358]:
      array([[1, 2, 3],
             [2, 3, 4]])
    
      In [359]: a.dtype
      Out[359]: dtype('int64')
    
    
    
    
      In [366]: a.astype(unicode_)
      Out[366]:
      array([['1', '2', '3'],
             ['2', '3', '4']],
            dtype='<U24')
    

スライシング

    In [369]: arry = np.arange(20)

    In [370]: arry
    Out[370]:
    array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
           17, 18, 19])
  • ndarrayのデータアクセス方法

    • arry[]
    • Rと同じ感じ

        In [371]: arry[4]
        Out[371]: 4
      
        In [372]: arry[4:10]
        Out[372]: array([4, 5, 6, 7, 8, 9])
      
  • ndarrayから一部を切り出したものに値を代入することができる

      //4~10を100に代入する
      In [373]: arry[4:10] = 100
    
      In [374]: arry
      Out[374]:
      array([  0,   1,   2,   3, 100, 100, 100, 100, 100, 100,  10,  11,  12,
              13,  14,  15,  16,  17,  18,  19])
    
  • ndarrayからスライスしたものの値を変更すると、スライス元のndarrayも変更される

    • コピーでなく、参照なので、オリジナルが書き変わってしまうので注意

        In [375]: slice = arry[1:10]
      
        In [376]: slice
        Out[376]: array([  1,   2,   3, 100, 100, 100, 100, 100, 100])
      
        In [377]: slice[0] = 10000
      
        In [378]: arry
        Out[378]:
        array([    0, 10000,     2,     3,   100,   100,   100,   100,   100,
                 100,    10,    11,    12,    13,    14,    15,    16,    17,
                  18,    19])
      

boolインデックス参照

  • 参照元・参照先の要素数が一緒であれば、異なる配列のBool値を渡して、値を取り出すことができる

      In [385]: names = np.array(['A','B','C','A','B','D','E'])
    
      In [381]: data = np.random.randn(7,4)
    
      In [382]: data
      Out[382]:
      array([[-0.4017517 ,  0.1419749 ,  2.6240324 , -0.44037342],
             [-0.18664907,  0.51251524, -0.30868358, -1.11172428],
             [-1.00609678, -0.64364957,  1.57684002, -2.52900976],
             [-0.22742879, -0.94647345,  1.00702104, -0.32474363],
             [ 1.67767647,  0.08669149,  0.99823391, -0.45566197],
             [ 1.19013211,  0.58920002,  0.34461962,  1.49732534],
             [ 1.05829828,  0.15391459,  0.71491311, -0.02964348]])
    
      //この配列を別の配列に渡して、データを取り出すことできる       
      In [386]: names == 'A'
      Out[386]: array([ True, False, False,  True, False, False, False], dtype=bool)
    
      //nameがAのものを取り出す
      In [387]: data[names == 'A']
      Out[387]:
      array([[-0.4017517 ,  0.1419749 ,  2.6240324 , -0.44037342],
             [-0.22742879, -0.94647345,  1.00702104, -0.32474363]])
    
      //nameがA以外のものを取り出す       
      In [388]: data[names != 'A']
      Out[388]:
      array([[-0.18664907,  0.51251524, -0.30868358, -1.11172428],
             [-1.00609678, -0.64364957,  1.57684002, -2.52900976],
             [ 1.67767647,  0.08669149,  0.99823391, -0.45566197],
             [ 1.19013211,  0.58920002,  0.34461962,  1.49732534],
             [ 1.05829828,  0.15391459,  0.71491311, -0.02964348]])
    
  • 複数条件を取り出すことも可能

    • ただし、取り出したものの値を変更した場合、オリジナルの値が変更されてしまうので注意!
    • コピーではない

      In [391]: mask = (names == 'A') | (names == 'D')

      In [392]: mask Out[392]: array([ True, False, False, True, False, True, False], dtype=bool)

      In [393]: data[mask] Out[393]: array([[-0.4017517 , 0.1419749 , 2.6240324 , -0.44037342], [-0.22742879, -0.94647345, 1.00702104, -0.32474363], [ 1.19013211, 0.58920002, 0.34461962, 1.49732534]])

特定条件による値の取り出し

  • 特定の値より小さいかどうかを返す

      In [395]: [data < 0]
      Out[395]:
      [array([[ True, False, False,  True],
             [ True, False,  True,  True],
             [ True,  True, False,  True],
             [ True,  True, False,  True],
             [False, False, False,  True],
             [False, False, False, False],
             [False, False, False,  True]], dtype=bool)]
    
      In [394]: data[data < 0]
      Out[394]:
      array([-0.4017517 , -0.44037342, -0.18664907, -0.30868358, -1.11172428,
             -1.00609678, -0.64364957, -2.52900976, -0.22742879, -0.94647345,
             -0.32474363, -0.45566197, -0.02964348])
    
      In [396]: data[data < 0] = 0
    
      In [397]: data
      Out[397]:
      array([[ 0.        ,  0.1419749 ,  2.6240324 ,  0.        ],
             [ 0.        ,  0.51251524,  0.        ,  0.        ],
             [ 0.        ,  0.        ,  1.57684002,  0.        ],
             [ 0.        ,  0.        ,  1.00702104,  0.        ],
             [ 1.67767647,  0.08669149,  0.99823391,  0.        ],
             [ 1.19013211,  0.58920002,  0.34461962,  1.49732534],
             [ 1.05829828,  0.15391459,  0.71491311,  0.        ]])
    

ファンシーインデックス

  • 特定の順序で行を抽出するには、その順序を配列で渡せばよい

      In [404]: data
      Out[404]:
      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 [405]: data[1]
      Out[405]: array([ 1.,  1.,  1.,  1.])
    
      //上と同じようなことを配列で渡せばよい
      In [407]: data[[2,1,3]]
      Out[407]:
      array([[ 2.,  2.,  2.,  2.],
             [ 1.,  1.,  1.,  1.],
             [ 3.,  3.,  3.,  3.]])
    

行列の入れ替え

  • data.Tで行列変換
  • これもコピーではなく、ビューを返すので、値の書き換えを実行してしまうとオリジナルが変更されるので注意S

      In [408]: data
      Out[408]:
      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 [409]: data.T
      Out[409]:
      array([[ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.],
             [ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.],
             [ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.],
             [ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.]])
    

- 内積を求める時に便利

    In [410]: np.dot(data.T,data)
    Out[410]:
    array([[ 140.,  140.,  140.,  140.],
           [ 140.,  140.,  140.,  140.],
           [ 140.,  140.,  140.,  140.],
           [ 140.,  140.,  140.,  140.]])
  • 高次元の配列の場合もtransposeメソッドで入れ替え可能

      In [411]: data = np.arange(16).reshape((2,2,4))
    
      In [412]: data
      Out[412]:
      array([[[ 0,  1,  2,  3],
              [ 4,  5,  6,  7]],
    
             [[ 8,  9, 10, 11],
              [12, 13, 14, 15]]])
    
      In [413]: data.tra
      data.trace      data.transpose
    
      In [413]: data.transpose((1,0,2))
      Out[413]:
      array([[[ 0,  1,  2,  3],
              [ 8,  9, 10, 11]],
    
             [[ 4,  5,  6,  7],
              [12, 13, 14, 15]]])
    

ラムダ

  • 単項func

      In [417]: arry
      Out[417]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
      In [418]: result = np.sq
      np.sqrt     np.square   np.squeeze
    
      In [418]: result = np.sqrt(arry)
    
      In [419]: resu
      result       result_type  results
    
      In [419]: result
      Out[419]:
      array([ 0.        ,  1.        ,  1.41421356,  1.73205081,  2.        ,
              2.23606798,  2.44948974,  2.64575131,  2.82842712,  3.        ])
    
  • 二項func

      In [421]: x = np.arange(10)
    
      In [422]: y = np.arange(10) *10
    
      In [423]: x
      Out[423]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
      In [424]: y
      Out[424]: array([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
    
      In [426]: np.add(x,y)
      Out[426]: array([ 0, 11, 22, 33, 44, 55, 66, 77, 88, 99])
    

特定の条件に合致するものの個数を調べる

  • True=1/False=0として計算されるので、条件でTFの列を返して、それのsum()をとる

      In [428]: x
      Out[428]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
      In [429]: (x >5)
      Out[429]: array([False, False, False, False, False, False,  True,  True,  True,  True], dtype=bool)
    
      In [430]: (x >5).sum()
      Out[430]: 4     
    

その他使いそうなもの

  • 配列の重複をのぞいたものを返す numpy.unique
  • ソート numpy.sort