numpy.array()
numpy.array() はシーケンスを受け取って、配列 (ndarrayオブジェクト) を返します。
numpy.array(object, dtype=None, *, copy=True, order='K', subok=False, ndmin=0, like=None)
数値のリストを渡して配列を生成してみます。
# NUMPY_ARRAY # In[1] import numpy as np # ndarrayオブジェクトを生成 arr = np.array([0, 1, 2]) print(arr) print(type(arr)) # [0 1 2]
タプルを渡して配列を生成することもできます。
# In[2] # ndarrayオブジェクトを生成 arr = np.array((0, 1, 2)) print(arr) # [0 1 2]
range オブジェクトを渡せば連番配列を生成できます。
# In[3] # 連番配列を生成 arr = np.array(range(5)) print(arr) # [0 1 2 3 4]
NumPy の配列はすべての要素が同じ型でなければならないというルールがありますが、数値と文字列が混在したリストを渡すとどうなるでしょうか。
# In[4] # 数値と文字列が混在したリストを渡す arr = np.array([0, 1, "2"]) print(arr) # ['0' '1' '2']
エラーにはなりませんが、自動的に要素が文字列に統一されました。dtype 引数で任意のデータ型を指定できます。たとえば、要素を整数に統一したいときは、”int32″ や “int64” などを渡します。
# In[5] # 配列要素のデータ型を64ビット符号付き整数に統一する arr = np.array([0, 1, "2"], dtype="int64") print(arr) # [0 1 2]
データ型を文字列に統一したいときは、dtype に “str” を渡します。
# In[6] # 配列要素のデータ型をユニコード文字列に統一する arr = np.array([0, 1, "2"], dtype="str") print(arr) # ['0' '1' '2']
2 次元リスト (ネストされたリスト) を渡すと 2 次元配列が返ります。
# In[7] # 2次元配列を生成する arr = np.array([[0, 1], [2, 3]]) print(arr) # [[0 1] # [2 3]]
このように、渡したリストの形状によって戻ってくる配列の次元は自動的に決まるようになっていますが、ndmin で戻り値の最低次元数を設定しておくこともできます。たとえば、リスト [0, 1, 2] を渡して 2 次元配列を戻してほしいときには、ndmin=2 とします。
# In[8] # 戻り値の最低次元数を2に設定 arr = np.array([0, 1, 2], ndmin=2) print(arr) # [[0 1 2]]
ndmin で設定するのは戻り値の次元数ではなく「最低次元数」です。ndmin に渡した次元数よりも、第 1 引数で渡したリストの次元数が大きければ、リストの次元数が優先されます。
# In[9] # 3次元リスト my_list = [[[0, 1], [2, 3]], [[0, 1], [2, 3]]] arr = np.array(my_list, ndmin=2) print(arr) # [[[0 1] # [2 3]] # [[0 1] # [2 3]]]
numpy.arange()
numpy.arange() は連番または等差数列を生成する関数です。使い方は Python 本体の組み込み関数 range() とほとんど同じです。
numpy.arange([start,] stop [,step], dtype=None)
numpy.arange(n) は 0 から n-1 の数字が並ぶ配列を返します。
# NUMPY_ARRANGE # In[1] import numpy as np # 0~9の連番配列を作成 x = np.arange(10) print(x) # [0 1 2 3 4 5 6 7 8 9]
numpy.arange(m, n) は m から n-1 の連番配列を返します。
# In[2] # 3~8の連続数字配列を作成 x = np.arange(3, 9) print(x) # [3 4 5 6 7 8]
第3引数 step は数字同士の間隔です。numpy.arange(m, n, s) は m から始まって s 間隔で n-1 までの等差数列を生成します。
# In[3] # 1~9の奇数が並ぶ配列を作成 x = np.arange(1, 10, 2) print(x) # [1 3 5 7 9]
オプション引数 dtype には要素のデータ型を渡します(省略すると入力値から類推して自動的にデータ型が決定されます)。
# In[4] # 0~9のfloat型連続数字配列を作成 x = np.arange(10, dtype=float) print(x) # [0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
reshape()関数を使って連続数字の二次元配列を生成することもできます。
# In[5] # 1~9の連続数字配列を作成 x = np.arange(1, 10).reshape(3, 3) print(x) # [[1 2 3] # [4 5 6] # [7 8 9]]
numpy.zeros()
numpy.zeros() は 0 で埋め尽くされた配列を生成します。
numpy.zeros(shape, dtype=None, order="C")
numpy.zeros(9) は 9 個の 0.0 が並ぶ配列を生成します。
# NUMPY_ZEROS # In[1] import numpy as np # 0で埋め尽くされた要素数9の配列を生成 # データ型は整数(int) x = np.zeros(9) print(x) # [0. 0. 0. 0. 0. 0. 0. 0. 0.]
デフォルトでは要素のデータ型が float になっています。
データ型は dtype で指定することができます。
# In[2] # 0で埋め尽くされた要素数9の配列を生成 x = np.zeros(9, dtype=int) print(x) # [0 0 0 0 0 0 0 0 0]
shape にタプルを渡して配列の形を指定することができます。
# In[3] # 0で埋め尽くされた要素数9の配列を生成 # データ型は整数(int) x = np.zeros((3, 3), dtype=int) print(x) # [[0 0 0] # [0 0 0] # [0 0 0]]
numpy.zeros_like()
numpy.zeros_like() は与えられた引数と同じ形状の 0 で埋め尽くされた配列を生成します。
numpy.zeros_like(a, dtype=None, order='K', subok=True, shape=None)
たとえば a に 2 × 3 配列を渡すと、0 で埋め尽くされた 2 × 3 配列が生成されます。
# NUMPY_ZEROS_LIKE import numpy as np arr = np.array([[1, 2, 3], [4, 5, 6]]) # arrと同じ形状で全要素0の配列を生成 x = np.zeros_like(arr) print(x) # [[0 0 0] # [0 0 0]]
numpy.ones()
numpy.ones() は 1 で埋め尽くされた配列を生成します。
numpy.ones(shape, dtype=None, order="C")
たとえば、numpy.ones(9) は 9 個の 1 が並ぶ配列を生成します。
データ型は dtype で指定します (デフォルトは float)。
# NUMPY_ONES # In[1] import numpy as np # 1で埋め尽くされた要素数9の配列を生成 # データ型は整数(int) x = np.ones(9, dtype=int) print(x) # [1 1 1 1 1 1 1 1 1]
shape にタプルを渡して配列の形を指定することができます。
# In[2] # 1で埋め尽くされた要素数9の配列を生成 # 各要素のデータ型は整数(int) x = np.ones((3, 3), dtype=int) print(x) # [[1 1 1] # [1 1 1] # [1 1 1]]
numpy.ones_like()
numpy.ones_like() は与えられた引数と同じ形状で全ての要素を 1 とした配列を生成します。
numpy.ones_like(a, dtype=None, order='K', subok=True, shape=None)
たとえば a に 2 × 4 の配列を渡すと、1 で埋め尽くされた 2 × 4 の配列が生成されます。
# NUMPY_ONESLIKE import numpy as np arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]]) # arrと同じ形状で全要素が1の配列を生成 x = np.ones_like(arr) print(x) # [[1 1 1 1] # [1 1 1 1]]
numpy.full()
numpy.full() は同じ要素で埋め尽くされた配列を生成します。
numpy.full(shape, fill_value, dtype=None, order='C')
たとえば全ての要素が 5 である 2 × 3 の配列を作りたいときには、shape に (2, 3), fill_value に 5 を渡します。
# NUMPY_FULL import numpy as np # 全ての要素が 5 である 2 × 3 の配列を生成 x = np.full((2, 3), 5, dtype="int32") print(x) # [[5 5 5] # [5 5 5]]
numpy.full_like()
numpy.full_like() は受け取った配列 a と同じ形状をもつ、指定要素 (fill_value) で埋め尽くされた配列を返します。
numpy.full_like(a, fill_value, dtype=None, order='K', subok=True, shape=None)
# NUMPY_FULLLIKE arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]]) # arrと同じ形状をもち、9で埋め尽くされた配列を生成 x = np.full_like(arr, 9) print(x) # [[9 9 9 9] # [9 9 9 9]]
numpy.eye()
numpy.eye() は対角線上に 1 が並ぶ配列を生成します。
numpy.eye(N, M=None, k=0, dtype=None, order='C')
たとえば、3 × 3 の単位配列を作りたいときには引数 N に 3 を渡します。
# NUMPY_EYE # In[1] import numpy as np # 3 × 3 の単位配列を生成 x = np.eye(3, dtype="int32") print(x) # [[1 0 0] # [0 1 0] # [0 0 1]]
引数 M には配列の列数を指定します(省略すると M=N です)。引数 k には対角線左上隅の 1 の位置を渡します。列(右)方向にずらす場合は正の値を、行(下)方向にずらす場合は負の値を指定します。
# In[2] # 3 × 3 の単位配列を生成 x = np.eye(3, 4, k=1, dtype="int32") print(x) # [[0 1 0 0] # [0 0 1 0] # [0 0 0 1]]
numpy.identity()
numpy.identity() は任意サイズの 単位行列、すなわち主対角線上の成分が 1 に揃えられた正方行列を返します。
numpy.identity(n, dtype=None, *, like=None)
第1引数 n に行列のサイズを指定します。たとえば、2行2列の行列を生成する場合は、n=2 を指定します。
# NUMPY_IDENTITY # In[1] import numpy as np # 2×2の単位行列 # [[1 0] # [0 1]] I = np.identity(2) print(I) # [[1. 0.] # [0. 1.]]
各成分のデータ型 (dtype) はデフォルトで float に設定されています。成分を整数にしたい場合は、np.int8 や np.int16 などを指定しておきます。
# In[2] # 2×2の単位行列 # [[1 0] # [0 1]] I = np.identity(2, dtype=np.int16) print(I) # [[1 0] # [0 1]]
numpy.matrix()
numpy.matrix() は文字列から配列を生成する関数です。
numpy.matrix(data, dtype=None, copy=True)
この関数で配列を生成するときは、各行を “;” で区切って指定します。
# NUMPY_MATRIX # In[1] import numpy as np # 2次元配列を生成 x = np.matrix("1 2 3 ; 4 5 6 ; 7 8 9") print(x) # [[1 2 3] # [4 5 6] # [7 8 9]]
各要素のデータ型は dtype で指定します。
# In[2] # 2次元配列を生成 # データ型は複素数(complex) x = np.matrix("1 2 3 ; 4 5 6", dtype="complex") print(x) # [[1.+0.j 2.+0.j 3.+0.j] # [1.+0.j 2.+0.j 3.+0.j]]
numpy.linspace()
numpy.linspace() は開始値 (start) から終了値 (stop) まで均等間隔に数字を並べます(すなわち等差数列を生成します)。
numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
第 3 引数 num には要素数を指定します (デフォルトは 50)。たとえば、[10 20 30 40 50] という配列を作りたいときは次のようなコードを書きます。
# NUMPY_LINSPACE # In[1] import numpy as np # 開始値10,終了値50,要素数5の等差数列 # データ型(dtype)はintを指定 x = np.linspace(10, 50, 5, dtype=int) print(x) # [10 20 30 40 50]
endpoint を False にすると、stop に指定した数を含みません。
# In[2] x = np.linspace(10, 50, 5, dtype=int, endpoint=False) print(x) # [10 18 26 34 42]
retstep は配列のあとに公差を表示するか否かのオプションです。デフォルトでは False になっているので、表示したいときは True を指定します。
# In[3] # 開始値10,終了値3,要素数3の等差数列(公差を表示) x = np.linspace(10, 20, 3, retstep=True) print(x) # (array([10., 15., 20.]), 5.0)
numpy.logspace()
numpy.logspace() は対数スケールで等間隔の配列を生成します。
numpy.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
endpoint が True であるとき、配列の最初の要素は base ** start, 最後の要素は base ** stop です。要素の個数は num で指定します。たとえば、$10^2$ から $10^4$ まで 5 個の要素を対数スケールで等間隔に並べる場合は次のコードを記述します。
# NUMPY_LOGSPACE # In[1] import numpy as np # 10**2から10**4まで、10を底とする対数スケールで要素が等間隔に並ぶ配列 x = np.logspace(2.0, 4.0, num=5) # xの常用対数 y = np.log10(x) print("x = {}".format(x)) print("y = {}".format(y)) # x = [100. 316.22776602 1000. 3162.27766017 10000.] # y = [2. 2.5 3. 3.5 4.]
endpoint を False に設定すると、stop を含まない形で配列を生成します。
# In[2] # 10**2から、10を底とする対数スケールで要素が等間隔に5個並ぶ配列 x = np.logspace(2.0, 4.0, num=5, endpoint=False) # xの常用対数 y = np.log10(x) print("x = {}".format(x)) print("y = {}".format(y)) # x = [100. 251.18864315 630.95734448 1584.89319246 3981.07170553] # y = [2. 2.4 2.8 3.2 3.6]
numpy.geomspace()
numpy.geomspace() は等比数列 (geometric progression) を返します。
numpy.geomspace(start, stop, num=50, endpoint=True, dtype=None, axis=0)
たとえば、start=1, stop=10000, num=5 を指定すると、1 から 10000 まで公比 10 で 5 個の数が並びます。
# NUMPY_GEOMSPACE # In[1] # 1から10000までの等比数列 seq = np.geomspace(1, 10000, 5, dtype=np.int64) print(seq) # [1 10 100 1000 10000]
endpoint に False を渡すと、stop で指定した値を含まないように等比数列を生成します。
# In[2] seq = np.geomspace(1, 10000, 4, endpoint=False) print(seq) # [1. 10. 100. 1000.]
numpy.diag()
numpy.diag() は対角配列を生成、もしくは配列の対角成分を抜き出す関数です。
numpy.diag(v, k=0)
第1引数 v に 1次元配列を渡すと、渡した配列を右斜めの対角要素とする(それ以外の要素を 0 とする)2次元配列を返します。第2引数 k でオフセットを指定することができます(正ならば列方向、負ならば行方向にずらします)。
# NUMPY_DIAG # In[1] # 対角成分 v = np.array([1, 2, 3]) # 対角配列を作成 x1 = np.diag(v) x2 = np.diag(v, 2) x3 = np.diag(v, -2) print("{}\n".format(x1)) print("{}\n".format(x2)) print("{}".format(x3)) ''' [[1 0 0] [0 2 0] [0 0 3]] [[0 0 1 0 0] [0 0 0 2 0] [0 0 0 0 3] [0 0 0 0 0] [0 0 0 0 0]] [[0 0 0 0 0] [0 0 0 0 0] [1 0 0 0 0] [0 2 0 0 0] [0 0 3 0 0]] '''
第1引数 v に 2次元配列を渡すと、配列から右斜めの対角線に並ぶ要素を抜き出して 1 次元配列として返します。第2引数 k はオフセットです。
# In[2] # 配列xを定義 x = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # xの対角成分を抽出 v1 = np.diag(x) v2 = np.diag(x, 1) v3 = np.diag(x, -1) print("v1:{}".format(v1)) print("v2:{}".format(v2)) print("v3:{}".format(v3)) # v1:[1 5 9] # v2:[2 6] # v3:[4 8]
numpy.fromfunction()
numpy.fromfunction() は、第1引数に渡した関数を使って配列を生成します。
numpy.fromfunction(function, shape, **kwargs)
たとえば、2変数 i と j の関数を渡すと、2次元配列におけるインデックス (i, j) の要素をその関数にしたがって決定することになります。
# NUMPY_FROMFUNCTION # In[1] # インデックス(i,j)の要素がi+jとなる配列を生成 x = np.fromfunction(lambda i, j: i + j, (3, 4), dtype=np.int) print(x) # [[0 1 2 3] # [1 2 3 4] # [2 3 4 5]]
3変数 i, j, k の関数を渡すと、3次元配列を生成します。
# In[2] # インデックス(i,j,k)の要素がi*j+kとなる配列を生成 x = np.fromfunction(lambda i, j, k: i * j + k, (2, 3, 4), dtype=np.int) print(x) # [[[0 1 2 3] # [0 1 2 3] # [0 1 2 3]] # [[0 1 2 3] # [1 2 3 4] # [2 3 4 5]]]
コメント
配列生成では一番よく使う numpy.array( ) 関数が紹介されていないのは、なぜでしょうか。
あまりに普通に使う関数なので、うっかりしてました (・・;)
後で一番上に追加しておきます。
numpy.array( ) 関数の項目を追加していただき、ありがとうございました。
タプルも引数として渡せることは最近知りました。あまり使うことはないと思いますが、2 次元のタプルも試したら 2 次元の配列が返ってきました。
おお! 本当ですね。
[(0, 1), (2, 3)] や ([0, 1], [2, 3]) なども 2 次元配列に変換されました。NumPy の公式ドキュメントによると、__array__ メソッドを備えるオブジェクトを渡すと、1 次元以上の配列に変換してくれるようです。それ以外は渡したオブジェクトを 1 つの要素として格納した 0 次元配列を返すようです。試しに set オブジェクト {1, 2, 3} を入れてみたところ、array({1, 2, 3}, dtype=object)が返ってきました。
numpy.identity( ) の引数の中で、「 *, 」が出てきました。以前は「内容が細かすぎるのでなくてもよいのでは?」ということで削除していただいたことがあったのですが、Python 3.8以降では実際のコードの中でも記述できるようです。ルールを守らないと実際にエラーも出ます。
「関数の定義と呼び出し」の記事中の「必須引数とオプション引数」の項で、引数の途中の「 / 」と「 * 」について説明を追加していただければありがたいです。私もあちこち調べて結構時間がかかり、ようやく下記のページから明確な説明が得られました。
https://ja.stackoverflow.com/questions/51639/numpy%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9-%E9%96%A2%E6%95%B0%E3%81%AE%E5%BC%95%E6%95%B0%E3%81%AB%E3%81%82%E3%82%8B%E3%82%B9%E3%83%A9%E3%83%83%E3%82%B7%E3%83%A5%E4%BB%A5%E9%99%8D%E3%81%AE%E6%84%8F%E5%91%B3%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
申し訳ないです。
「*,」の意味については、私もよくわかっていませんでした。
教えてくださったリンク先の内容をよく読んで理解し、自分で色々コードを書いて試してから説明を追加しようと思います。
ついさきほど、ざっと目を通したのですが、とても興味深い内容でした。
「*,」を実際にコードに記述できる、ということには大変驚きました。私自身もまだまだ勉強不足であることを痛感しました。貴重な情報を教えてくださって、本当にありがとうございます。m(_ _)m