Skip to content

DNET_NumPy

nishi_74322014 edited this page Sep 11, 2026 · 1 revision

NumPy

概要

多次元配列における数値計算を効率的に行うことをサポートする数学関数ライブラリ

  • 効率的な数値計算を行うための型付きの多次元配列のサポートをPythonに加える。
  • 多次元配列を操作するための大規模な高水準の数学関数ライブラリを提供する。
  • NumPy自体はC言語で書かれているため、Pythonのリストと比べると高速な処理が可能。

準備

インストール

> pip install numpy

インポート

>>>import numpy as np

ファースト・ステップ

NumPyの配列

1次元配列はベクトルとも言う。

生成(配列)

  • array

    >>>np.array([1.0,2.0,3.0])
    array([1., 2., 3.])
    
  • arange

    >>>np.arange(10)
    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
  • ones(1埋め)

    >>>np.ones(10)
    array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
    
  • zeros(0埋め)

    >>>np.zeros(10)
    array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
    
  • ランダム

    • empty

      >>>np.empty(5)
      array([2.12199579e-314, 6.36598737e-314, 1.06099790e-313, 1.48539705e-313,
            1.90979621e-313])
      
    • random.randn(標準正規分布)

      >>>np.random.randn(10)
      array([ 1.33385073, -0.61769365,  1.41045502, -0.18429257, -0.00662791,
             -0.09483573, -2.26232104,  0.95660959, -1.02715574, -1.02119134])
      
  • コピー

    >>>a=np.array([1.0,2.0,3.0])
    
    • 以下は参照渡し

      >>>b=a
      
    • コピーする場合は以下

      >>>b=a.copy()
      

確認(配列)

>>>a=np.array([1.0,2.0,3.0])
  • >>>a
    array([1., 2., 3.])
    
  • print

    >>>print(a)
    [1. 2. 3.]
    
  • データ型

    >>>type(a)
    <class 'numpy.ndarray'>
    
  • 要素のデータ型

    >>>a.dtype
    dtype('float64')
    
  • 配列の次元

    >>>np.ndim(a)
    1
    
  • 次元の形状

    >>>a.shape
    (3,)
    
  • 次元の要素数

    >>>a.shape[0]
    3
    

算術計算(配列)

  • 四則演算
    2つのNumPy配列を算術計算で処理する。

    • 同じ数の要素を持つ配列の要素ごとの計算

      >>>x=np.array([1.0,2.0,3.0])
      >>>y=np.array([2.0,4.0,6.0])
      
      • 要素ごとの足し算

        >>>x+y
        array([ 3.,  6.,  9.])
        
      • 要素ごとの引き算

        >>>x-y
        array([-1., -2., -3.])
        
      • 要素ごとの掛け算

        >>>x*y
        array([  2.,   8.,  18.])
        
      • 要素ごとの割り算

        >>>x/y
        array([ 0.5,  0.5,  0.5])
        
    • ブロード・キャストによる計算

      >>>x/2.0
      array([0.5, 1. , 1.5])
      
  • その他の計算

    >>>x=np.arange(10)
    >>>x
    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    • 平方根の計算

      >>>np.sqrt(x)
      array([0.        , 1.        , 1.41421356, 1.73205081, 2.        ,
             2.23606798, 2.44948974, 2.64575131, 2.82842712, 3.        ])
      
    • ネイピア数(DS:数学的基礎 - 微分・偏微分の該当節を参照)(自然対数の底)e を底とする累乗

      >>>np.exp(x)
      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])
      

統計計算(配列)

標準正規分布

>>>x=np.random.randn(10)
  • 符号

    >>>np.sign(x)
    array([ 1.,  1., -1., -1., -1., -1.,  1.,  1.,  1.,  1.])
    
  • 平均
    (標準正規分布で要素数を増やすと0に近づく)

    >>>x.mean()
    0.02713878708811851
    
  • 標準偏差
    (標準正規分布で要素数を増やすと1に近づく)

    >>>x.std()
    1.2305510107988773
    

NumPyのN次配列

行列

行列とは?

  • 2次元配列は行列とも言う。
  • 行が、1つの添字で表される1つのべクトル
  • 列は、ベクトルのn番目の要素をグループ化したもの。
    列↓
  ┌      ┐
行│○  ○│
→│      │
  │○  ○│
  └      ┘

テンソル

テンソルとは?

  • ベクトルや行列を一般化したものをテンソルと呼ぶ。

  • 3次元以上の配列を、テンソル / 多次元配列と呼ぶ。

  • 任意の次元の配列

    • 3次元の配列は3階テンソル
    • 4次元の配列は4階テンソル
  • 特別な呼び方

    • 0階テンソルをスカラー
    • 1階テンソルをベクトル
    • 2階テンソルのことを行列

生成(N次配列)

  • 通常

    >>> a=np.array([[1,2],[3,4],[5,6]])
    
  • 型指定

    >>> a=np.array([[1,2],[3,4],[5,6]],dtype=np.int32)
    
  • コピー

    >>>a=np.array([[1,2],[3,4],[5,6]])
    
    • 以下は参照渡し

      >>>b=a
      
    • コピーする場合は以下

      >>>b=a.copy()
      

確認(N次配列)

  • >>>a
    
  • print

    >>> print(a)
    [[1 2]
     [3 4]
     [5 6]]
    
  • データ型

    >>>type(a)
    <class 'numpy.ndarray'>
    
  • 行列要素のデータ型

    >>>a.dtype
    dtype('int32')
    
  • 行列の次元

    >>>np.ndim(a)
    2
    
  • 行列の形状(行数・列数)

    >>>a.shape
    (3, 2)
    
  • 次元の要素数

    >>>a.shape[0]
    3
    

算術計算(行列)

  • 四則演算
    2つのNumPy行列を算術計算で処理する。

    • 要素ごとの足し算

      • 行列の要素数が同じ

        >>>x=np.array([[1, 2], [3, 4]])
        >>>y=np.array([[3, 0], [0, 6]])
        >>>x+y
        array([[ 4,  2],
               [ 3, 10]])
        
      • 行列の要素数が異なる
        (ブロード・キャスト)

        >>>x=np.array([[1, 2], [3, 4]])
        >>>y=np.array([10,20])
        >>>x+y
        array([[11, 22],
               [13, 24]])
        
    • 要素ごとの掛け算
      行列の積でないことに注意

      • 行列の要素数が同じ

        >>>x=np.array([[1, 2], [3, 4]])
        >>>y=np.array([[3, 0], [0, 6]])
        >>>x*y
        array([[ 3,  0],
               [ 0, 24]])
        
      • 行列の要素数が異なる
        (ブロード・キャスト)

        >>>x=np.array([[1, 2], [3, 4]])
        >>>y=np.array([10,20])
        >>>x*y
        array([[10, 40],
               [30, 80]])
        
  • その他の計算
    ベクトルと同じ方法で計算できる。

統計計算(行列)

セカンド・ステップ

要素へのアクセス

  • 配列

    >>> a=np.arange(10)
    >>> print(a)
    [0 1 2 3 4 5 6 7 8 9]
    
  • 行列

    >>> b=np.array([[51, 55], [14, 19], [0, 4]])
    >>> print(b)
    [[51 55]
     [14 19]
     [ 0  4]]
    

インデックス

  • 配列

    >>>a[1]
    1
    
  • 行列

    • N次配列にN個のインデックスを指定すると要素が取り出せる。

      >>>b[0][1]
      55
      
    • N次配列にX個のインデックスを指定するとN-X次配列が取り出せる。

      >>>b[0]
      array([51, 55])
      

抽出

  • 配列

    • スライシング

      >>>a[3:7]
      
    • 配列でインデックスを指定

      >>>a[np.array([3,4,5,6])]
      
    • 比較演算
      比較の結果boolの配列が生成されて指定されている。

      • 条件に合う値を抽出

        >>>a[a==5]
        
      • 5より大きい値を抽出。

        >>>a[a>5]
        
  • 行列

    • スライシング

      >>>b[0,1:2]
      array([55])
      >>>b[1:2,0]
      array([14])
      
    • 配列でインデックスを指定

      • 行インデックス

        >>>b[np.array([0,1])]
        array([[51, 55],
              [14, 19]])
        
      • 行&列インデックス

        >>>b[np.array([0,1]),np.array([1])]
        array([55, 19])
        
    • 比較演算
      比較の結果boolの配列とか行列などが生成されて指定されている。

      • 15より大きい値を抽出。

        >>>b[b>15]
        array([51, 55, 19])
        
      • 列値が条件に合う行を抽出

        >>>b[b[:,1]==19]
        array([[14, 19]])
        

ベクトル編集

置換(ベクトル)

  • 比較演算

    • 5より大きい値を調査。

      >>>a>5
      array([False, False, False, False, False, False,  True,  True,  True, True])
      
    • 特定の値を変換

      >>>a[a==5]=0
      >>>a
      array([0, 1, 2, 3, 4, 0, 6, 7, 8, 9])
      
  • 型の置換

    >>>b=np.array(b,dtype=np.int64) # 要素の型をint64に変換
    

要素の追加(ベクトル)

...

行列編集

置換(行列)

  • 比較演算

    • 15より大きい値を調査。

      >>>b>15
      array([[ True,  True],
             [False,  True],
             [False, False]])
      
    • 特定の値を変換

      >>>b[b==55]=99
      array([[51, 99],
             [14, 19],
             [ 0,  4]])
      
  • 型の置換

    >>>b=np.array(b,dtype=np.int64) # 要素の型をint64に変換
    

行追加

  • vstack
    2次元で言うと、垂直方向=行追加方向

    np.vstack([a, a])
    
  • concatenate
    0次元目(行追加)方向に結合

    np.concatenate([a, a])
    np.concatenate([a, a], 0)
    

列追加

  • hstack
    2次元でいうと、水平方向=列追加方向にスタック

    np.hstack([a, a])
    
  • concatenate
    1次元目(列追加)方向に結合

    np.concatenate([a, a], 1)
    

行削除

スライシング

列の削除

スライシング

要素の追加(行列)

stackで新規次元を追加してスタックする。

  • 新規次元を追加してスタック

    • ベクトル要素が新規次元で(行追加方向に)スタックして新規次元を追加

      >>>np.stack([a.flatten(), a.flatten()])
      >>>np.stack([a.flatten(), a.flatten()], 0)
      array([[51, 55, 14, 19,  0,  4],
             [51, 55, 14, 19,  0,  4]])
      
    • 行列の要素が新規次元でスタックして新規次元を追加

      >>>np.stack([a, a])
      >>>np.stack([a, a], 0)
      array([[[51, 55],
              [14, 19],
              [ 0,  4]],
             [[51, 55],
              [14, 19],
              [ 0,  4]]])
      
  • 既存の次元でスタックして次元を追加

    • ベクトル要素が列の次元で(列追加方向に)スタックして新規次元を追加

      >>>np.stack([a.flatten(), a.flatten()], 1)
      array([[51, 51],
             [55, 55],
             [14, 14],
             [19, 19],
             [ 0,  0],
             [ 4,  4]])
      
    • 行列の要素が行の次元でスタックして新規次元を追加

      >>>np.stack([a, a], 1)
      array([[[51, 55],
              [51, 55]],
             [[14, 19],
              [14, 19]],
             [[ 0,  4],
              [ 0,  4]]])
      
    • 行列の要素が列の次元でスタックして新規次元を追加

      >>>np.stack([a, a], 2)
      array([[[51, 51],
              [55, 55]],
             [[14, 14],
              [19, 19]],
             [[ 0,  0],
              [ 4,  4]]])
      

サード・ステップ

型の変換

要素の型の変換

配列でも、行列でも。

>>> b=np.array(a,dtype=np.int32)

LIST ⇔ NP型変換

  • LIST → NP
    コレについては、生成の所で既出(np.arrayを使う)。

  • LIST ← NP
    ndarray.tolist()メソッドが使える。

    np_arr.tolist()
    

NP ⇔ DF型変換

Pandasの該当節を参照。

配列・行列変換

行列の配列化

(機械学習ライブラリ入力用)

  • 平坦化

    • flatten

      >>> b=a.flatten()
      >>> print(b)
      [51 55 14 19  0  4]
      
    • reshape

      >>>c.reshape(-1)
      
  • 行ベクトル、列ベクトル

    • 行ベクトル(横ベクトル)化

      b=a[0,:] # 1行目、全列スライス
      
    • 列ベクトル(縦ベクトル)化

      b=a[:,0] # 1列目、全行スライス
      

配列の行列化

(機械学習ライブラリ入力用)

  • 1行n列化

    • reshape

      >>>c=b.reshape(1, -1)
      
    • np.newaxis

      >>>c=b[np.newaxis, :]
      
  • n行1列化

    • reshape

      >>>c=b.reshape(-1, 1)
      
    • np.newaxis

      >>>c=b[:, np.newaxis]
      

行列の変換

転置行列

>>> a=np.array([[51, 55], [14, 19], [0, 4]])
>>> print(a)
[[51 55]
 [14 19]
 [ 0  4]]
  • Tプロパティ

    >>>print(a.T)
    [[51 14  0]
     [55 19  4]]
    
  • transposeメソッド

    >>>print(a.transpose())
    [[51 14  0]
     [55 19  4]]
    

次元の入れ替え

行(0)と列(1)が入れ替わる。
転置と同じだが、2次元以上のn次元行列にも適用可能。

>>> a=np.array([[51, 55], [14, 19], [0, 4]])
>>> print(a)
>>> a=a.transpose([1, 0])
>>> print(a)

再構成

>>>a=np.arange(0, 12)
  • numpy.reshape

    >>>np.reshape(a,[4,3])
    array([[ 0,  1,  2],
           [ 3,  4,  5],
           [ 6,  7,  8],
           [ 9, 10, 11]])
    
    >>>np.reshape(a,[3,2,2])
    array([[[ 0,  1],
            [ 2,  3]],
           [[ 4,  5],
            [ 6,  7]],
           [[ 8,  9],
            [10, 11]]])
    
  • ndarray.reshape

    >>>a.reshape([4,3])
    array([[ 0,  1,  2],
           [ 3,  4,  5],
           [ 6,  7,  8],
           [ 9, 10, 11]])
    
    >>>a.reshape([3,2,2])
    array([[[ 0,  1],
            [ 2,  3]],
           [[ 4,  5],
            [ 6,  7]],
           [[ 8,  9],
            [10, 11]]])
    

One-Hotエンコーディング

>>> a=np.array([[0,1,2,3,4,5,6,7,8,9]])
>>> print(a)
[[0 1 2 3 4 5 6 7 8 9]]

エンコーディング

  • np_utils.to_categoricalを使う。

    b = np_utils.to_categorical(a, num_classes=10).astype('i')
    
  • np.identityを使う。

    b = np.identity(10)[a].astype('i')
    

デコーディング

  • np.argmaxを使う。

    b.argmax(axis=1)
    
  • チェック

    print((b.argmax(axis=1) == a).all())
    

4thステップ

ベクトルの積算(ドット積 = 内積)

>>>a=np.array([1,2,3,4])
>>>b=np.array([10,20,30,40])

データの生成

ベクトルを行列化する。

>>> a=a.reshape(1, -1)
>>> b=b.reshape(1, -1).T # 転置行列に

計算方法(ベクトルの積算)

  • 演算子

    >>>a@b
    
  • メソッド

    >>>np.dot(a,b)
    

交換法則が成立

行列では、交換法則の不成立になるが、
ベクトルの場合は成立する(ただし転置が必要)。

>>>a@b
>>>b.T@a.T
>>>np.dot(a,b)
>>>np.dot(b.T,a.T)

行列の積算(ドット積 ≠ 内積)

A行列 * B行列 = C行列

  • A行列の列数とB行列の行数が一致している必要がある。
  • 計算後のC行列は、A行列の行数 * B行列の列数の行列になる。

2行2列の場合

┌      ┐┌      ┐   ┌                    ┐
│a1  b1││a2  b2│   │a1a2+b1c2  a1b2+b1d2│
│      ││      │ = │                    │
│c1  d1││c2  d2│   │c1a2+d1c2  c1b2+d1d2│
└      ┘└      ┘   └                    ┘
  A行列    B行列              C行列
  2行2列    2行2列              2行2列

x行y列の場合

計算後のC行列は、A行列の行数 * B行列の列数の行列になる。

  • ベクトルと行列との計算では、
    ベクトルが行列形状に拡張され計算される。
┌     ┐┌  ┐   ┌     ┐┌    ┐  ┌         ┐
│a1 b1││a2│   │a1 b1││a2 0│  │a1a2+b1b2│
│     ││  │ = │     ││    │ =│         │
│c1 d1││b2│   │c1 d1││b2 0│  │c1a2+d1b2│
└     ┘└  ┘   └     ┘└    ┘  └         ┘
  A行列   B行列                    C行列
  2行2列   2行1列                    2行1列
  • A行列の列数とB行列の行数が一致している必要がある。
┌      ┐┌              ┐   ┌                                          ┐
│a1  b1││a2  b2  c2  d2│   │a1a2+b1e2  a1b2+b1f2  a1c2+b1g2  a1d2+b1h2│
│      ││              │   │                                          │
│c1  d1││e2  f2  g2  h2│ = │c1a2+d1e2  c1b2+d1f2  c1c2+d1g2  c1d2+d1h2│
│      │└              ┘   │                                          │
│e1  f1│                    │e1a2+f1e2  e1b2+f1f2  e1c2+f1g2  e1d2+f1h2│
└      ┘                    └                                          ┘
  A行列        B行列                       C行列
  3行2列        2行4列                       3行4列

計算方法(行列の積算)

要素ごとの掛け算でないことに注意

  • データ生成

    >>>a=np.array([[1,2,3],[4,5,6]])
    >>>b=np.array([[1,2],[3,4],[5,6]])
    >>>c=np.array([[1,2],[3,4]])
    >>>d=np.array([7,8])
    
    >>>a
    array([[1, 2, 3],
           [4, 5, 6]])
    >>>b
    array([[1, 2],
           [3, 4],
           [5, 6]])
    >>>c
    array([[1, 2],
           [3, 4]])
    >>>d
    array([7, 8])
    
  • 演算子
    @(ドット積)演算子を使用する。

    >>>a@b
    array([[22, 28],
           [49, 64]])
    
    >>>b@c
    array([[ 7, 10],
           [15, 22],
           [23, 34]])
    
    >>>b@d
    array([23, 53, 83])
    
    >>>a@c # A行列の列数とB行列の行数が一致しない。
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 2 is different from 3)
    
  • メソッド
    dot(ドット積)メソッドを使用する。

    >>>np.dot(a,b)
    array([[22, 28],
           [49, 64]])
    
    >>>np.dot(b,c)
    array([[ 7, 10],
           [15, 22],
           [23, 34]])
    
    >>>np.dot(b,d)
    array([23, 53, 83])
    
    >>>np.dot(a,c) # A行列の列数とB行列の行数が一致しない。
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: shapes (2,3) and (2,2) not aligned: 3 (dim 1) != 2 (dim 0)
    

信号処理

...

参考

移行メモ

  • 「A行列の列数とB行列の行数が一致ししている」(2 箇所)を 「一致している」に修正した。
  • 「信号処理」配下の本文の無い見出し「...」は除去し、本文の「...」だけを残した。
  • 同名の見出し(「生成」「確認」「算術計算」「統計計算」「置換」「要素の追加」 「計算方法」)が複数あり、GitHub Wiki ではアンカが衝突するため、 括弧で文脈を補って一意にした。
  • 元 Wiki の「戻る」の並びで NumPy が HTML 実体参照(&#78;umPy)で 書かれていたが、PukiWiki のページ内リンク自動生成を避けるための記法と 思われるため、通常の文字列に戻した。

Tags: 移行, NumPy, Python, 多次元配列, ndarray, ベクトル, 行列, テンソル, ドット積, One-Hot

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally