NumPy は、今、話題の科学技術計算や、機械学習でよく利用されるライブラリです。これは Python の標準ライブラリではありませんが、 anaconda で Python をインストールしたら自動的についてきます。
ここでは、科学技術計算や機械学習の必須のスキルである NumPy を使った配列の作り方を解説していきます。
1. NumPy で簡単な配列を作る
NumPy で配列を作るには、array() 関数を使います。関数の引数にはリストかタプルを渡します。引数については「Pythonの関数の基礎知識と使い方と一覧まとめ」をご覧ください。
それでは、早速見ていきましょう。
1.1. リストやタプルから NumPy の配列を作る
1.1.1. リストから配列を作る
次のコードは、リスト [1, 2, 3] から NumPy の配列を作ったものです。
'''numpy モジュールを np という名前でインストールします。'''
import numpy as np #numpy は np としてインストールすることが慣例です。
'''array()関数で配列を作ります。'''
array1 = np.array([1, 2, 3]) #配列の要素はリストかタプルで指定します。
'''確認してみましょう。'''
array1
作成した配列 array1 をそのまま出力すると、array([1, 2, 3]) と表示されていますね。これを print() 関数で出力すると、要素がカンマではなく、半角空白区切りで表示されます。
'''配列をprint()関数で出力すると、要素が半角で区切られて出力されます。'''
print(array1)
1.1.2. タプルから配列を作る
次のコードは、タプルから配列を作ったものです。
'''タプルから配列を作ることもできます。'''
tuple = (1, 2, 3)
array2 = np.array(tuple)
print(array2)
1.1.3. NumPy の配列の型は numpy.ndarray
NumPy で作った配列のオブジェクトの型を調べてみると、numpy.ndarray と返ってきます。
'''NumPyの配列の型は numpy.ndarray です。'''
type(array1)
この型のオブジェクトには、科学技術計算や機械学習に便利なメソッドやプロパティを使うことができます。
オブジェクトの型については「Pythonの型とは | 確認と変換の方法」で、プロパティについては「Pythonの@propertyによるプロパティへのアクセス制御のまとめ」でご確認ください。
1.2. Numpy の配列を作るときのルール
NumPy の配列には、要素の型が混在できないというルールがあります。そこで、ここでは、
- 要素に異なる型が存在する場合の処理のパターン
- 要素の型の確認方法
- 要素の型を指定する方法
- 配列の型を変換する方法
をそれぞれ見ていきましょう。
1.2.1. NumPy の配列に要素の型は混在できない
NumPy の配列は、リストやタプルと違って、型が異なる要素が混在することはできません。数値だけの配列なら数値だけ、文字列だけの配列なら文字列だけと、要素の型を揃えておく必要があります。
なお 整数 (int) 型と浮動小数点数 (float) 型が混在している時は、int は float に変換されます。文字列と数値が混在する時は、数値は文字列に変換されます。
試しに、要素が混ざっている配列を作って見ましょう。まずは、int と float が混在している配列です。
import numpy as np
'''int と float が混在しているリスト'''
array1 = np.array([1, 1.8, 2])
array1
このように、int は float に変換されます。次に、文字列と数値が混在している配列です。
'''文字列と数値が混在しているリスト'''
array2 = np.array(["1", 2, 3])
array2
数値は、文字列型に変換されていますね。dtype = ‘<U1’ とありますが、これについては、すぐ後で解説します。
それでは、論理値と数値が混在している場合はどうでしょうか。
'''論理値と数値が混在しているリスト'''
array3 = np.array([True, False, 2])
array3 #True = 1, False = 0 です。
このように、論理値が数値に変換されます。なお、Python の内部では、論理値の True は 1, False は 0 と処理されます。これについては、「Pythonの演算子の一覧表とわかりやすい解説」でご確認ください。
1.2.2. NumPy の配列の要素の型の確認方法
NumPy の配列の要素の型を確認するには、dtype プロパティを使います。「Pythonの@propertyによるプロパティへのアクセス制御のまとめ」で解説している通り、プロパティを使うときには、括弧や引数は不要です。
以下をご覧ください。
'''配列の要素の型は dtype プロパティで確認することができます。'''
array1.dtype
このように、要素の型を確認することができます。整数 (int) 型なら ‘int64’ と表示されますし、文字列型なら ‘<U’ と表示されます。
1.2.3. NumPy の配列の要素の型を指定する方法
array() 関数の第二引数で、”dtype =” を入力すると型を指定することができます。早速見ていきましょう。
import numpy as np
array1 = np.array([1, 1.8, 2], dtype = int) # int 型を指定。
array1
通常 int 型と float 型が混在していると、float 型に変換されますが、今回は、第二引数で int 型に統一することを指定しています。
次のコードは、float 型を指定したものです。
array2 = np.array([1, 2, 3], dtype = float) # float 型を指定。
array2
数値には、複素数 (complex) 型もありますね。詳しくは「初心者のためのPythonの数値計算の基礎知識」をご確認ください。以下は、その complex 型を指定したものです。
array3 = np.array([1, 1.8, 2], dtype = complex) # complex (複素数)型を指定。
array3
文字列 (str) 型を指定するには、 dtype = “<U” と指定します。
array4 = np.array([1, 1.8, 2], dtype="<U") # str (文字列)型を指定。
array4
“<U4” というように末尾に数値を入れると、次のように、要素の文字数を指定することができます。
'''str 型を示す <U の横に数値を入れると要素の文字数を指定することができます。 '''
array5 = np.array([1.2345, 2.3456, 3.4567], dtype = "<U4")
array5
小数点も 1 文字としてカウントされている点にご注意ください。
1.2.4. 配列の型を変換して新しい配列を作る方法
array() 関数の第一引数に、別の配列を渡して、第二引数で “dtype = ” で型を渡すと、既存の配列の型を変換した新しい配列を作ることができます。
次のコードをご覧ください。
import numpy as np
'''int型の配列を作ります。'''
array_int = np.array([1, 2, 3, 4, 5])
'''array_int を float に変換します。'''
array_float = np.array(array_int, dtype=float) # float 型に変換
'''確認してみましょう。'''
print(array_int)
print(array_float)
2. NumPy で多次元配列を作る
ここまでは簡単な配列の作り方でした。ここからは、NumPy が優れている点である多次元の配列の作り方について見ていきましょう。下図は、3行 × 3 列の多次元配列です。
このような多次元配列は、多次元リストや多次元タプルから作ることができます。多次元リストは「Pythonのリストの要素を置換する方法」の中で解説しています。
2.1. 多次元配列の作り方
それでは、多次元配列の作り方を見ていきましょう。次のコードをご覧ください。
import numpy as np
'''多次元配列を作るには、array()関数に多次元リストを渡します。'''
array1 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(array1)
異なるリストを組み合わせて、次のように書くこともできます。
'''次のように書くこともできます。'''
line1 = [10, 20, 30]
line2 = [40, 50, 60]
line3 = [70, 80, 90]
array2 = np.array([line1, line2, line3])
print(array2)
2.2. 一次元配列を多次元配列に変換する
numpy モジュールの reshape() メソッドを使うと、一次元の配列を多次元配列に変換することができます。メソッドの第一引数に行数、第二引数に列数を渡します。ただし、例えば、2 行 × 3 行の配列を作りたいなら、もとの一次元配列に 6 個の要素が存在する必要があります。
次のコードをご覧ください。最初に、9 個の要素がある一次元配列を作り、それを 3 行 × 3 列の多次元配列に変換しています。
import numpy as np
'''一次元配列を作ります。'''
array1 = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
'''3行 × 3 列の多次元配列に変換します。'''
array2 = array1.reshape(3, 3) # 3 行 × 3 列
array2
array() 関数と reshape() メソッドを続けて書くこともできます。
'''既に存在するデータからワンステップで多次元配列を作ることもできます。'''
data = [1, 2, 3, 4, 5, 6, 7, 8, 9]
array3 = np.array(data).reshape(3, 3)
array3
2.3. 多次元配列を一次元配列に変換する
逆に、多次元配列を一次元配列に変換するには、ravel() メソッド、または flatten() メソッドを使います。
以下は ravel() メソッドです。
'''ravel()メソッドで多次元配列を一次元配列に変換します。'''
array2.ravel()
続いて、flatten() メソッドです。
'''flatten()メソッドでも可能です。'''
array3.flatten()
2.4. 多次元配列の構造を調べる
次に、多次元配列の構造を調べる方法を見ていきましょう。構造とは、以下の 3 つのことです。
- 多次元配列の行数と列数
- 多次元配列の次元数
- 多次元配列の要素の個数
それぞれ解説していきます。
2.4.1. 多次元配列の行数と列数を調べる
多次元配列が、何行 × 何列なのかを調べるには、shape プロパティを使います。プロパティを使う時は、括弧や引数は不要です。次のように、タプル型で、(行数, 列数) と返ってきます。
import numpy as np
array1 = np.array([[1, 2, 3], [4, 5, 6]])
array1.shape
2.4.2. 多次元配列の次元数を調べる
多次元配列の次元数を調べるには ndim プロパティを使います。次の例をご覧ください。
import numpy as np
array1 = np.array([[1, 2, 3], [4, 5, 6]])
array1.ndim
二次元配列なので 2 が返ってきていますね。三次元配列の場合は 3 と返ってきます。
array2 = np.array([[[1, 2, 3], [4, 5, 6], [7, 8, 9]],[[1, 2, 3], [4, 5, 6], [7, 8, 9]],[[1, 2, 3], [4,5,6], [7, 8, 9]]])
array2.ndim
三次元配列は、二次元配列の行と列(縦と横)に、奥行きが加わった配列です。Java での解説ですが、「三次元配列とは」を見ると分かりやすいでしょう。
2.4.3. 多次元配列の要素数を調べる
多次元配列の要素の個数は、size プロパティで調べます。次のコードをご覧ください。
import numpy as np
array1 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
array1.size
len() 関数を使うと、一次元配列の要素数(行数)を調べることができます。
len(array1)
行と列の扱いに慣れる必要はありますが、一度慣れてしまえば簡単です。
3. 配列を効率よく作る
配列を作るときに、いちいち全ての数字を手入力していたら時間がかかりますね。そこで、ここでは配列を効率よく作る方法を解説します。
- arange() 関数で数値の範囲を指定して配列を作る方法
- linspace() 関数で指定した数値の範囲を等分割した配列を作る方法
- empty() 関数でゼロ行列を作る方法
がありますので、それぞれ見ていきましょう。
3.1. 数値の範囲を指定して配列を作る
NumPy ライブラリの arange() 関数を使うと、range() 関数と同じように効率よく配列を作ることができます。range() 関数は「Pythonのforを使った繰り返しのまとめ」でも解説しているので確認してみてください。
それと同じように arange() 関数も、第一引数に開始値、第二引数に終了値、第三引数にステップを渡します。また上で解説している dtype を渡すこともできます。引数で省略できないのは、終了値だけです。
引数については、「Pythonの関数の基礎知識と使い方と一覧まとめ」で解説しているのでおさらいして見ても良いでしょう。
それでは早速見て見ましょう。
import numpy as np
np.arange(10) # 0 ~ 9 の一次元配列を作る。
この通り、range() 関数と似ていますね。
多次元配列は、reshape() メソッドと組み合わせると作ることができます。
np.arange(1, 21).reshape(4, 5) #reshape() メソッドを併用した二次元配列の作成。
第三引数まで渡した例も見てみましょう。
np.arange(10, 21, 2) #開始値、終了値、ステップを渡す。
簡単ですね。
3.2. 指定の範囲の数値を等分割した配列を作る
linspace() 関数を使えば、指定の範囲の数値の中で、指定の数値で等分割した配列を作ることができます。まずは、linspace() 関数の書式から解説します。
linspace() の第一引数には開始値、第二引数には終了値、第三引数には分割数を渡します。オプション引数で dtype を渡すと型を指定することができます。
それでは見ていきましょう。
import numpy as np
array = np.linspace(0, 120, 16, dtype=int) # 0以上120以下の数値を16分割した配列。
print(array)
linspace() 関数の利点は、ある範囲の数値を等分割した場合、要素が何個になるかが、すぐに分かることにあります。上記配列を、len() 関数で調べると、要素の数は 16 個であることが分かりますね。
len(array) #要素は16個あります。
要素の個数が分かると、多次元配列化を素早く行うことができます。
array.reshape(4, 4) #個数が分かると二次元配列化も素早く行えます。
3.3. ゼロ行列の配列を作る
全ての要素が 0 のゼロ行列は、zeros() 関数で作ります。第一引数で要素の個数を、オプション引数で dtype を渡します。
import numpy as np
array0 = np.zeros(12).reshape(3, 4)
print(array)
同様に、全ての要素が 1 の行列は、ones() 関数で作ります。使い方は zeros() 関数と同じです。
array1 = np.ones(12).reshape(3, 4)
print(array1)
3.4. 単位行列を作る
単位行列とは、対角線上の要素に 1 が入り、それ以外は 0 の配列です。これは、identity() 関数または eye() 関数で作ります。どちらも、引数に行列のサイズを指定します。オプション引数で dtype を渡します。
import numpy as np
array1 = np.identity(4)
print(array1)
以下は、eye() 関数です。行と列を指定し、オプション引数で型指定も行なっています。identity() 関数も全く同じように利用できます。
array2 = np.eye(4, 5 ,dtype=int)
print(array2)
3.5. ある要素の並びを繰り返した配列を作る
すでにある要素の並びを繰り返した配列を作るには repeat() 関数を使います。引数には繰り返したい数を渡します。
import numpy as np
array1 = np.array([1, 2, 3])
array1.repeat(4)
このように、([1, 2, 3, 1, 2, 3]) となっていないことに注目しましょう。これに reshape() メソッドを組み合わせると、行の要素が同じ値の配列を素早く作ることができます。
array1.repeat(4).reshape(3, 4)
二次元配列の場合、repeat() 関数のオプション引数で axis = を渡すと、行の要素の繰り返し、列の要素の繰り返しを指定することができます。
array2 = np.arange(6).reshape(2, 3)
array2.repeat(2, axis=0) #axis=0 で行を繰り返します。
array2.repeat(2, axis=1) #axix=1で列を繰り返します。
4. ファイルから配列を読み込む
配列はファイルからデータを読み込んで作ることもできます。ここでは、
- テキストファイルからデータを読み込んで配列を作る方法
- csv ファイルからデータを読み込んで配列を作る方法
を解説します。
4.1. テキストファイルから配列を読み込む
NumPy ライブラリの loadtxt() 関数を使うと、テキストファイルを読みこんで配列を作ることができます。
その際、もしテキストファイルに書いている要素の一つ一つが、カンマで区切られているなら、オプション引数で delimiter =”,” を渡す必要があります。空白で区切られている時は不要です。
また、配列の要素に複数の型が混在することはできないので、もしヘッダ行がある場合は、オプション引数 skipows = 1 を入力します。
import numpy as np
array = np.loadtxt("numpy_array.txt", delimiter=",", skiprows=1)
print(array)
4.2. csv ファイルから配列を読み込む
Anaconda をインストールしたら、最初から含まれている pandas モジュールの read.csv() 関数を使うと、csv ファイルを読み込んで配列を作ることができます。
この関数の戻り値は、DataFrame 型です。この型のオブジェクトに対して、.values プロパティを使うとデータを取り出すことができます。ヘッダー行を取り出したい時は .columns.values プロパティを使います。
import pandas as pd
array = pd.read_csv("sample_array.csv")
header = array.columns.values
data = array.values
print(header)
print(data)
5. 配列の転置(行と列の入れ替え)とシャッフル
ここでは、配列の転置とシャッフルの方法をそれぞれ見ていきましょう。
5.1. 配列の転置
配列の行と列を入れ替えた配列を作るには、
- transpose() 関数を使う方法
- T プロパティを使う方法
の 2 つあります。それぞれ見ていきましょう。
5.1.1. transpose() 関数で配列を転置する
まずは、numpy モジュールの transpose() 関数を使う方法です。これを使うと、元の配列を転置した新しい配列を作ることができます。
以下が元となる配列です。
'''元となる配列を作ります。'''
import numpy as np
array1 = np.array([[1, 2], [3, 4], [5, 6]]) #二次元配列
print(array1)
これを transpose() 関数で転置したものが以下です。
'''transpose() 関数で配列を転置します。'''
array2 = np.transpose(array1)
print(array2)
行と列が入れ替わっていることが分かりますね。
5.1.2. T プロパティで転置する
T プロパティを使っても同様の結果になります。
'''T プロパティを使う方法も同様の結果になります。'''
array3 = array1.T
print(array3)
こちらも抑えておきましょう。
5.2. 配列のシャッフル
random.shuffle() 関数で配列の要素をシャッフルすることができます。
import numpy as np
array = np.arange(9).reshape(3, 3)
np.random.shuffle(array)
array
6. 乱数の配列
NumPy には乱数の配列を作る関数が複数あります。例えば、
- 通常の乱数配列:random.rand() 関数
- 正規分布の乱数配列:random.randn() 関数
- 二項分布の乱数配列:random.binomial() 関数
- ポアゾン分布の乱数配列:random.poisson() 関数
- 全く同じ乱数の配列:random.seed() 関数
それぞれ見ていきましょう。
6.1. 通常の乱数配列を作る
乱数の配列を作るには、random.rand() 関数を使います。引数には作りたい乱数 (0.0 ~ 1.0) の個数を渡します。
次のコードをご覧ください。
import numpy as np
x = np.random.rand(10) #X軸:乱数の配列
y = np.random.rand(10) #Y軸:乱数の配列
print(x)
10 個の乱数を持つ配列を 2 つ作っています。 print() 関数で出力しているのは x だけです。例として、これの散布図を作ってみましょう。
それが以下です。
import matplotlib.pyplot as plt #作図モジュール
plt.scatter(x, y) #散布図の作成
plt.show()
6.2. 正規分布の乱数の配列を作る
正規分布の乱数配列を作るには、random.randn() 関数を使います。引数には、作る乱数の個数を渡します。多次元配列にしたい場合は、行、列、奥行きとカンマ区切りで渡します。
次の例では、正規分布の二次元配列を作っています。
import numpy as np
nd = 3.0 + np.random.randn(2, 3) + 50 #正規分布の乱数 = 分散 + 乱数 + 平均
print(nd)
6.3. 二項分布の乱数の配列を作る
二項分布の乱数の配列を作るには、random.binomial() 関数を使います。引数に渡す n は試行回数、 p は確率、 size は行と列です。size を省略すると、作られる乱数は 1 個になります。
import numpy as np
bd = np.random.binomial(n=100, p=0.2, size=(2, 3))
print(bd)
6.4. ポアゾン分布の配列を作る
ポアゾン分布は、random.poisson() 関数を使います。引数の lam は平均値、size は配列の行と列の数を渡します。
import numpy as np
pd = np.random.poisson(lam=10, size=(3, 2))
print(pd)
6.5. 同じ乱数の配列を作る
全く同じ乱数の配列を、もう一度使いたい可能性がある場合は、乱数の関数を実行する前に、random.seed() を設定します。この関数の引数は任意の数値です。
import numpy as np
np.random.seed(1) # ランダムシード 1 を設定する。
np.random.randn(3) #ランダムシード設定後に乱数を作ります。
次に乱数を作る時に、random.seed() 関数の引数に同じ数値を渡せば、同じ乱数を作ることができます。
np.random.seed(1) #次に乱数を作る時に、同じ引数番号のランダムシードを呼び出します。
np.random.randn(3)
7. まとめ
Python で配列を作るには、科学技術計算や機械学習に便利な numpy モジュールを利用します。NumPy は、anaconda で Python をインストールしている場合は、デフォルトで付属しています。もし、anaconda をインストールしていない方は、この機会にやっておきましょう。
多次元配列になると、最初は、戸惑うことも少なくないと思います。
これを使いこなせるようになれば、様々な解析を行うことができるようになるので、一つずつじっくりと抑えていきましょう。
コメント