NumPy 練習ノート

NumPy (Numerical Python) は,フリーの Python ライブラリです.オンラインドキュメントから引用しつつ,まとめると,

このページでは,初心者向けのサンプルコードを材料として,API リファレンスでコードを確認しつつ,少しだけ HTML に書きながら勉強しています.
上記 Pandas については,ここと同じようなページを作成しました(Pandas 練習ノート). このページで「配列」といえば,ndarray 型オブジェクトやインスタンスを意味します.

インフォメーション

オンラインドキュメント

このページでは,NumPy 内に見つかる,下記ドキュメントを中心に勉強しています.

勉強が進んだら,NumPy user guide が読めるようになる,と期待します.

Debian パッケージ

このページは,Debian GNU/Linux バージョン 13 "trixie" で作成しました.
インストールしている主なパッケージを示します.

パッケージ名(バージョン)
python3 (3.13.5)高レベルオブジェクト指向言語(このページ改定開始時点でインストール済みでした)
python-numpy-doc (2.2.4)HTML ドキュメントが /usr/share/doc/python-numpy/html/reference/ 以下にインストールされました

"the absolute basics for beginners"("beginners") の内容と,このページ内のセクションへのリンク

"beginners" では,コマンドラインからの入力で import 文の書き方から Matplotlib を使うグラフの描き方までが解説されています.
このページでは,その一部について API リファレンスを参照しつつソースファイルの形のソースコードを作成しています.
目次として,"beginners" のパラグラフのタイトルと,このページのセクションへのリンクとを対応付けてみました.

  1. How to import NumPy:りあえず配列を作成してみる
  2. Reading the example code:りあえず配列を作成してみる
  3. Why use NumPy?
  4. What is an “array”?
  5. Array fundamentals
  6. Array attributes:配列の Attributes
  7. How to create a basic array:配列の作成法いろいろ
  8. Adding, removing, and sorting elements:要素のソート配列の連結
  9. How do you know the shape and size of an array?:配列の Attributes
  10. Can you reshape an array?
  11. How to convert a 1D array into a 2D array (how to add a new axis to an array)
  12. Indexing and slicing
  13. How to create an array from existing data
  14. Basic array operations
  15. Broadcasting
  16. More useful array operations
  17. Creating matrices
  18. Generating random numbers
  19. How to get unique items and counts
  20. Transposing and reshaping a matrix
  21. How to reverse an array
  22. Reshaping and flattening multidimensional arrays
  23. How to access the docstring for more information
  24. Working with mathematical formulas
  25. How to save and load NumPy objects
  26. Importing and exporting a CSV
  27. Plotting arrays with Matplotlib

りあえず配列を作成してみる

NumPy の配列 ndarray を作成します.
"How to import NumPy" と "Reading the example code" の例を組み合わせれば,下のソースコードが作成できます.

ソースコード

ここでは main.py という名前で保存します.


import numpy as np

a = np.array([[1, 2, 3], [4, 5, 6]])
print("a =", a)

NumPy のインポート

NumPy とそのメソッドにアクセスするには,Python コード内で numpy ライブラリをインポートする必要があります.
"beginners" には,「広く採用されている慣例で,NumPy を使ったコードを読みやすくするために,インポートする名前を np と短くします」とか,「常に import numpy as np を使用することをお勧めします」と書いてあります.
Web で目にする大抵のコードで "as np" となっている理由はこのあたりにあるようです.

配列

コードでは,配列の初期化に,Python の int 型二次元リスト [[1, 2, 3], [4, 5, 6]] を与えています.
配列の要素の型は dtype 型(数値を表現する型)なのですが,int 型が dtype 型にキャストされます.

実行してみる

main.py という Python スクリプトを実行するには,端末に,
$ python3 main.py
と入力するのでした.結果,次のように表示されました.

a = [[1 2 3]
 [4 5 6]]

配列生成メソッド np.array() は API リファレンスではどう記されているか

この時点で,NumPy の配列は np.array() メソッドを使えば作成できることが判りました.
API リファレンスで numpy.array をみると,このメソッドは,

numpy.array(object, dtype=None, *, copy=True, order='K', subok=False, ndmin=0, like=None)

と宣言されています.
第二パラメータ以降はデフォルト引数が宣言されています.上のソースコードでは,これらは省略されてデフォルト引数が利用されたのでした,
第二引数 dtype を省略しており,引数に整数しか記述していないので,引数は int 型の配列と判断されたということのようです.

NumPy の配列について:"beginners" での解説からの抜粋

配列は,NumPy ライブラリの中心となるデータ構造です.
配列には,生データ,要素の検索方法,要素の解釈方法に関する情報が含まれています.

NumPy の配列の要素はすべて同じ型であり,配列 dtype 型といいます.
NumPy の配列は,dtype 型からなる n 次元配列オブジェクトであり,NumPy ndarray クラスで実装されています.
「ndarray」は,「N 次元配列」の略称です.

配列には,非負の整数のタプル,ブール値,別の配列,または整数によってインデックスを付けることができます.

NumPy では,次元を軸と呼びます. 次のような二次元配列がある場合,
[[0., 0., 0.],
[1.,1.,1.]]
配列には 2 つの軸が存在することに成ります.最初の軸の長さは 2,2 番目の軸の長さは 3 です.
配列の次元数はランクともいいます. 配列の形状は,各次元に沿った配列のサイズを示す整数のタプルで表現できます.
上の配列でいうと,ランクは 2,形状は (2, 3).

Python のリストと NumPy の配列との比較

NumPy の配列は,他の Python コンテナ オブジェクトと同様,配列にインデックスを付けたりスライスしたりすることで配列の内容にアクセスして変更できます.

NumPy の配列は,一般的なコンテナ オブジェクトとは異なり,異なる配列が同じデータを共有できるため,ある配列で行われた変更が別の配列にも反映される可能性があります.
Python のリストは 1 つのリストの中に異なるデータ型を含むことができますが,NumPy の配列の要素はすべて同じ型であり,配列 dtype と呼ばれます.
dtype の宣言を利用すれば,異なる型の値を一つの配列に異なる型を共存させることは可能です.


配列の Attributes

このセクションでは,ndim,shape,size,および dtype が紹介されています.
Attributes の要素を取得するコードは単純です.配列にアクセス演算子を作用させると得られます.

ソースコード


import numpy as np

a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])

print("a =", a)
print()
print("a.ndim =", a.ndim)
print("a.shape =", a.shape)
print("a.size =", a.size)
#print("a.dtype =", a.dtype)  #API リファレンスによると,これは非推奨なのでコメントアウト

実行結果

a = [[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

a.ndim = 2
a.shape = (3, 4)
a.size = 12

Attributes について

上のコードの記したように,Attributes を取得するのに () 付のメソッドを使いません.例えば,a.dim() ではなくて a.dim です.
API リファレンスの Array objects を見ると,配列 ndarray というデータ型は大きく分けて 3 個の要素から構成されているということです.

です.
Attributes は aray_scaler の構成要素だそうです.配列にアクセス演算子を作用させると array_scale の値が得られるということのようです.
Attributes は,コードに記した以外にもあります.

Data type objects(dtype) について

API リファレンスの Array objects のサブページに,配列 ndarray 型の構成要素である Data type objects(dtype) の解説があります.その導入部分をまとめてみます.

配列に格納されるデータ型 dtype は,NumPy の組み込み スカラー型で,整数や浮動小数点数などのさまざまな精度に対応した型があります.
numpy.dtype クラスの オブジェクトをインスタンス化する際には,値以外に,メモリの固定サイズやブロック内のバイトをどのように解釈するかを記述します.
もっとも,パラメータにデフォルト値が設定されたり,型がキャストされたりするので,意識する必要がない場合も多そうです.
API リファレンスでは,以下のような項目が説明されています.

インデックス付け([] 演算子でのアクセス)などによって配列から抽出された項目は,配列のデータ型に関連付けられた Python オブジェクトになります.
NumPy でデータ型の指定が必要な場合は常にスカラー型を dtype オブジェクトの代わりに使用できますが,スカラー型は dtype オブジェクトではありません.

配列要素が,別の配列要素となることもできます. ただし,これらのサブ配列は固定サイズでなければなりません.
配列がサブ配列から作成される場合,作成時にサブ配列の次元が配列の形状に追加されます.

NumPy データ型 dtype の作成例

下は,Data type objects(dtype) ページの最初のサンプルコードです.
コードでは,32 ビット,ビッグエンディアン,int 型の dtype を作成して,そのアトリビュートを出力しています.


import numpy as np

dt = np.dtype('>i4')  #リトルエンディアンの場合は '<'.4 は 32 ビットを表す. 8 なら 64 ビット
print(dt.byteorder)
print(dt.itemsize)
print(dt.name)
print(dt.type is np.int32)

実行結果を下に示します.

>
4
int32
True

配列の作成法いろいろ

「りあえず配列を作成してみる」では,np.array() を使って配列を作成しました.
"beginners" の "How to create a basic array" では,他の配列生メソッドとして zeros(),ones(),empty(),arange(),linspace() が紹介されています.

ソースコード


import numpy as np

array0 = np.zeros(2)  #0 で埋められた要素数 2 の配列.パラメータのデフォルト値は dtype=float となっているので,浮動小数点型の値 0. が格納されます
array1 = np.ones(3)  #1 で埋められた要素数 3 の配列
array2 = np.empty(4)  #要素数 4 の空の配列.実行結果を見ると,ゴミの値で初期化されるようです
array3 = np.arange(5)  #要素の範囲を含む配列.API リファレンスを見ると,「dtype が与えられない場合は,他の入力値からデータ型を推測する」と書いてあります
array4 = np.arange(2, 9, 2)  #等間隔の範囲を含む配列.最初の数値,最後の数値,およびステップ サイズを指定
array5 = np.linspace(0, 10, num=5)  #指定した間隔で線形に配置された値を含む配列

print("array0 :", array0)
print("array1 :", array1)
print("array2 :", array2)
print("array3 :", array3)
print("array4 :", array4)
print("array5 :", array5)

実行結果

実行すると,次のようにいろいろな型の配列が生成しました.

array0 : [0. 0.]
array1 : [1. 1. 1.]
array2 : [1.1656627e-316 0.0000000e+000 0.0000000e+000 0.0000000e+000]
array3 : [0 1 2 3 4]
array4 : [2 4 6 8]
array5 : [ 0.   2.5  5.   7.5 10. ]

array0,array1,および array5 の各要素には小数点がついています.これらは float 型のようです.
array2 には変な値が格納されています.API リファレンス numpy.empty — NumPy v2.3 Manual を見ると,"Return a new array of given shape and type, without initializing entries." と書いてあります.empty() メソッドで空の配列を生成した場合は,各要素は初期化されていないということです.

dtype キーワードによるデータ型の指定

dtype キーワードを使えば,データ型を明示的に指定できたり,キャストできたりします.
一例として,デフォルトのデータ型が浮動小数点 (np.float64) となる np.ones() のデータ型を,64 ビット int 型に指定してみます.
np.ones() は,指定した要素数からなる,1.0 で埋められた配列を作成するのでした.


import numpy as np

array10 = np.ones(3)  #上のコードと同じもの
array11 = np.ones(3, dtype=np.int64)  #dtype を 64 ビット int 型に指定

print("array10 :", array10)
print("array10 type :", type(array10[0]))  #ドキュメントにはないが,type() メソッドを使って型を取得して出力
print("array11 :", array11)
print("array11 type :", type(array11[0]))  #同上

実行結果

array1 の dtype はデフォルトの float 型なので,小数点が表示されているのに対し,array2 の dtype は int 型なので小数点が表示されていません.

array10 : [1. 1. 1.]
array10 type : <class 'numpy.float64'>
array11 : [1 1 1]
array11 type : <class 'numpy.int64'>

要素のソート

"Adding, removing, and sorting elements" では,sort() メソッドがコード付きで紹介されています.
その他にソートされた配列を返すメソッドとして,argsort()lexsort()searchsorted()partition() メソッドの API リファレンスへのリンクが張られています.

"beginners" の例

ベクトル(1 次元配列)を昇順にソートする例が記載されています.
ソースファイルの形に改変したコードを示します.


import numpy as np

array = np.array([2, 1, 5, 3, 7, 4, 6, 8])
sorted = np.sort(array)
print("sorted =", sorted)

実行結果は,

sorted = [1 2 3 4 5 6 7 8]

API リファレンスでのメソッド宣言

numpy.sort に,メソッドの宣言とその解説があります.メソッド宣言は,

numpy.sort(a, axis=-1, kind=None, order=None, *, stable=None)

戻り値は,同じデータ型,同じ配列形のソート済み配列です.
したがって,上述の "beginners" の例は,第一パラメータが一次元配列であり,第二パラメータ以降が省略されている場合,ということになります.

パラメータ

API リファレンスの説明を要約してみました.

  1. a:ソートされるべき配列
  2. axis:ソートの軸.デフォルト値 -1 は,最後の軸に沿ってソートされることを意味する.省略すると,一次元配列に変換されてソートされる
  3. kind:ソートアルゴリズム.'quicksort’, ‘mergesort’, ‘heapsort’, ‘stable’ が可能で,デフォルトは quicksort
  4. order:a がフィールドを定義した配列である場合に,フィールドの優先順位を設定する,指定されていないフィールドは同値を判定するために使用される
  5. stable:ソートの安定性.True の場合,返される配列は,比較結果が等しいと判断された値の相対的な順序を維持する

これらのパラメータを利用する例が,API リファレンスのページに載っています.
最初の例をソースファイルの形にします.

API リファレンスの例


import numpy as np

array = np.array([[1,4],[3,1]])
sorted1 = np.sort(array, axis=0)  #最初の軸に沿ってソートされる
sorted2 = np.sort(array)  #最後の軸に沿ってソートされる
sorted3 = np.sort(array, axis=None)  #一次元配列になってソートされる.要素の範囲や大小関係を表示するのに使うのかも

print("array =\n", array)
print()
print("最初の軸に沿ってソート\n", sorted1)
print()
print("最後の軸に沿ってソート\n", sorted2)
print()
print("一次元配列になってソート\n", sorted3)

実行結果を示します.

array =
 [[1 4]
 [3 1]]

最初の軸に沿ってソート
 [[1 1]
 [3 4]]

最後の軸に沿ってソート
 [[1 4]
 [1 3]]

一次元配列になってソート
 [1 1 3 4]

配列の連結

"beginners" の例

"Adding, removing, and sorting elements" では,sort() に加え,配列を連結するメソッド concatenate() がコード付きで紹介されています.
ソースファイルの形に改変したものを記します.
配列 a と配列 b とを結合して配列 c としています.


import numpy as np

a = np.array([1, 2, 3, 4])
b = np.array([5, 6, 7, 8])
c = np.concatenate((a, b))
print(c))

実行結果を示します.

[1 2 3 4 5 6 7 8]

API リファレンスを見る

API リファレンスの concatenate() では,次のように宣言されています.

numpy.concatenate((a1, a2, ...), axis=0, out=None, dtype=None, casting="same_kind")

パラメータ

試訳してみました.

API リファレンスの最初の例

最初の例では,パラメータの axis を設定しています.
ソースファイルの形に改変すると,

ソースコード


import numpy as np

a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6]])

c = np.concatenate((a, b), axis=0)  #要素数 2 の横ベクトルが積み重なる
print("c =", c)

print()

d = np.concatenate((a, b.T), axis=1)  #b を転置して連結.行数 2 の横ベクトルの要素数が増えていく
print("d =", d)

print()

e = np.concatenate((a, b), axis=None)  #None を指定すると,一次元配列になって連結される
print("e =", e)

b.T という記述があって,転置であると想像できるのですが,API リファレンスで確認しました.
numpy.ndarray.T というページがあって,"Same as self.transpose()." と書いてあります.
ちなみに,"beginners" には,一次元の ndarray をベクトル,多次元の ndarray をテンソルとも言うと書いてあります.

実行結果

c = [[1 2]
 [3 4]
 [5 6]]

d = [[1 2 5]
 [3 4 6]]

e = [1 2 3 4 5 6]