目次
Numpyの基本構文や関数とかの抜粋/Python文法
Numpyをインポートしていることを前提にしています。
import numpy as np
初期化(Numpy配列の生成)
初期化に関するポイント抜粋です。
型(dtype指定)
Numpy配列は型を指定して生成できます。
データを与えて生成するとデータから適切な型を推定して生成します。
デフォルトはpythonのfloatと互換性のある「float_」型です。
dtype | 互換性 | コメント |
---|---|---|
float_ | Pythonの「float」 | Numpyのデフォルト |
uint | Pythonの「int」 | 符号なし |
int_ | Pythonの「int」 | 符号あり |
bool_ | Pythonの「bool」 | |
int8 | 8ビット整数 | 符号あり |
int16 | 16ビット整数 | 符号あり |
int32 | 32ビット整数 | 符号あり |
int64 | 64ビット整数 | 符号あり |
uint8 | 8ビット整数 | 符号なし |
uint16 | 16ビット整数 | 符号なし |
uint32 | 32ビット整数 | 符号なし |
uint64 | 64ビット整数 | 符号なし |
float16 | 16ビット浮動小数点数 | |
float32 | 32ビット浮動小数点数 | |
float64 | 64ビット浮動小数点数 |
これ以外が必要なら、こちらで。
すべてを0のNumpy配列を生成
np.zeros((2, 2), dtype=np.float32)
結果は
[[0. 0.] [0. 0.]]
すべてを1でNumpy配列を生成
np.ones((2, 2), dtype=np.float32)
結果は
[[1. 1.] [1. 1.]]
対角要素に1それ以外に0をセットしたNumpy配列生成
np.eye(3, dtype=np.float32)
結果は
[
[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]
]
指定の値ですべてを埋めて生成
np.full((2, 2), 3.14)
結果は
[[3.14 3.14] [3.14 3.14]]
乱数を使って生成
例 | 説明 | 結果 |
---|---|---|
np.random.random((2, 2)) |
一様分布の乱数で初期化 | [[0.83874852 0.25393169] [0.48973298 0.63288969]] |
np.random.normal(1, 2, (2, 2)) |
平均1標準偏差2の正規分布 | [[ 2.78714269 -1.10804489] [-0.13093131 1.58371071]] |
np.random.randint(0, 10, (2, 2)) |
指定範囲の一様分布の整数 | [[0 3] [5 2]] |
np.random.rand(2, 2) |
0.0以上1.0未満の乱数 | [[0.2219319 0.16752553] [0.53437944 0.76555056]] |
np.random.randn(2, 2) |
平均0分散1の乱数で初期化 | [[-2.27146338 -0.00306964] [-1.04215926 1.20743357]] |
np.random のバリエーションは沢山あります。
もっと調べたい時はこちら。
等差数列の生成
pythonのlistとNumpy配列の相互変換
pythonのlistからNumpy配列にしたり、戻したりします。
lstbase = [[1, 2, 3], [4, 5, 6]] # listからNumpy配列 al1 = np.array(lstbase, dtype="float64") # Numpy配列からlist lstafter = al1.tolist()
リストに戻す時は、Numpy配列のdtypeと互換性のあるpythonの型になります。
Numpy同士の計算・比較
算術演算子
Numpy配列同士の演算の例と計算結果を書いてます。
[[6 3]
[4 6]]
[[2 2]
[2 2]]
以下表の式の例は上の配列が「a」、下の配列を「b」と読み替えて結果を見てもらえるとわかりやすいです。
結果は
[[8 5] [6 8]]
のように行列になります。
算術演算子 | 説明 | 式の例 |
---|---|---|
+ | 加算 | a + b |
- | 減算 | a - b |
* | 乗算 | a * b |
/ | 除算(結果は少数) | a / b |
// | 整数除算 | a // b |
** | べき条 | a ** b |
% | 余剰(あまり) | a % b |
比較演算子
演算子だけだとイメージしづらいので、以下のデータを使って例と結果を書きます。
[[6 3 4]
[4 6 3]]
[[-6 3 8]
[-4 6 4]]
演算の結果は
[[False True False] [False True False]]
のような行列になります。
上を「a」、下を「c」として例と結果を書いています。
算術演算子・関数 | 説明 | 式の例 |
---|---|---|
== | 等しい | a == c |
!= | 等しくない | a != c |
< | より小さい | a < c |
<= | より小さいか等しい | a <= c |
> | より大きい | a > c |
>= | より大きいか等しい | a >= c |
np.any | 条件に一致するものがひとつでもあればTrue | np.any(a == 4) |
np.all | すべての値が条件に一致すればTrue | np.all(a == 4) |
Python3.5からはドット積「np.dot(A, B) 」を「A@B」と書ける行列積演算子も追加されました。
ドット積についてのリンクです。
属性確認
Numpy配列の形状やサイズなどの情報
Numpy配列の形状やサイズなどの情報を取り出します。
イメージしづらいので、こんな3行2列の配列の属性を取得する例を書きます。
[[6.32486041 1.82922998]
[1.91987168 0.40812655]
[2.4821602 1.54720082]]
上記配列の名前は「a12」としています。
書き方(配列をarとする) | 意味 | 結果 |
---|---|---|
a12.shape | 配列形状のタプル | (3, 2) |
a12.shape[0] | 2次元の場合なら「行」 | 3 |
a12.shape[1] | 2次元の場合なら「列」 | 2 |
a12.ndim | 配列の次元数 | 2 |
a12.dtype | 配列の型 | float64 |
a12.size | 配列の合計サイズ | 6 : 3×2だから |
a12.itemsize | 各要素のバイト数 | 8 (バイト) |
a12.nbytes | 配列の合計バイト数 | 48(バイト:size×itemsize) |
のように取得できます。
他にもありますが、それはこちらで。
Numpy配列のndimとaxis
ちなみに
- ndimは「次元数」
- axisは「軸」
です。
例えば、以下のような3行4列の配列は2次元配列なので、ndimは「2」です。
axis=0を指定すると列が軸、axis=1を指定すると行が軸です。
ループ
Numpy配列の値をとりだして、forループを回す例です。
こんな感じの3行2列のNumpy配列を使ってやってみます。
[[0.83751433 0.02594981]
[2.8441739 3.17256053]
[0.04499033 2.14228941]]
以下の例で「a12」という名前の変数が上記Numpy配列です。
データだけを取り出してループする
for x in np.nditer(a12): print(x)
出力結果はこんな感じでデータだけを順番に取得します。
0.8375143297961567
0.025949813102027264
2.8441738981495615
3.1725605261342964
0.04499033206824665
2.142289407822542
インデックスとデータを取り出してループする
インデックスは、multi_indexで参照できます。
it = np.nditer(a12, flags=['multi_index']) for x1 in it: print(it.multi_index, ":", x1)
出力結果はこんな感じになります。
(0, 0) : 0.8375143297961567
(0, 1) : 0.025949813102027264
(1, 0) : 2.8441738981495615
(1, 1) : 3.1725605261342964
(2, 0) : 0.04499033206824665
(2, 1) : 2.142289407822542
データの取り出し
Numpy配列もPythonのリストと同じように添え字で値を参照します。
上記例で使った配列「a12」をそのまま使うなら。
a12[1,0]
とすると
2.8441738981495615
が取得できる感じで。
スライス
同様に、スライスもできて、記述方法とルールも同じです。
anylist[start:end:stride]
start:指定した添え字を含む、省略すると「0」(つまり添え字の先頭)
end:指定した添え字を含まない。省略すると「最後の要素まで」
stride:カウントアップする幅、省略すると「1」。-1だと逆順になる。
こういう配列データを使って例(結果列)を書いてます。。
[[2 2 5 5]
[4 3 0 2]
[0 3 2 1]]
この配列を「a7」という名前で参照してます。
Numpy配列のスライスの例です。
書き方 | 意味 | 結果 |
---|---|---|
a7[2:, :] | 3行目から取り出し |
[ [0 3 2 1] ] |
a7[:, :2] | 2列目までとりだし | [[2 2] [4 3] [0 3]] |
a7[::2, ::2] | 行列共に1つおきに取り出し | [[2 5] [0 2]] |
a7[:, ::-1] | 列を逆順にソート | [[5 5 2 2] [2 0 3 4] [1 2 3 0]] |
a7[::-1, :] | 行を逆順にソート | [[0 3 2 1] [4 3 0 2] [2 2 5 5]] |
a7[::-1, ::-1] | 行と列を共に逆順にソート | [[1 2 3 0] [2 0 3 4] [5 5 2 2]] |
a7[:, 1] | 2列目をとりだす | [2 3 3] |
a7[1, :] | 2行目をとりだす | [4 3 0 2] |
ソート
ソート:配列の昇順(axisの指定無し)
スライスの応用の逆順ソートがでてきたので、続けて昇順にソートする方法です。
Numpyの昇順ソートは、np.sort()を使います。
ソート例の元にする配列は「a7」という変数名にします。
内容は以下です。
[[5 4 8 6]
[9 5 6 1]
[2 0 3 0]]
これをソートするのは
np.sort(a7)
この結果はこうです。
[[4 5 6 8]
[1 5 6 9]
[0 0 2 3]]
行単位で小さい数値が左から並ぶようにソートされています。
ソート:axis=0を指定
axis=0は列を軸にするイメージでした。
np.sort(a7, axis=0)
この結果はこうです。
[[2 0 3 0]
[5 4 6 1]
[9 5 8 6]]
列単位で小さい数値順に上から並び替えられているので、行でみるとシャッフルされたような感じになってます。
ソート:axis=1を指定
axis=1は行を軸にするソートです。
np.sort(a7, axis=1)
結果はこうです。
[[4 5 6 8]
[1 5 6 9]
[0 0 2 3]]
行単位で左から小さい数字がならんでます。
つまり」、無指定の場合と同じです。
Numpy配列を処理の都合にあわせて形状変更するのはよくあります。
それらの代表的なやり方だけまとめます。
形状変換
一次元から二次元行列へ
元になるNumpy配列はこんな1次元配列にします。
[1 2 3 4 5 6 7 8 9]
配列の名前は「aj1」としています。
これを「3×3」の二次元行列に変換するのは
aj33 = aj1.reshape((3, 3)) print(aj33)
返還後はこんな感じ
[[1 2 3]
[4 5 6]
[7 8 9]]
1次元から2次元の行へ
これも頻繁に使います。
[1 2 3 4 5 6 7 8 9]
を
[
[1 2 3 4 5 6 7 8 9]
]
にするわけです。
当然ながら、上と同じように「reshape(1, 9)」とやってもできます。
でも、スライスで「np.newaxis」を使った以下のやり方を良く見ます。
元になる1次元配列は「aj1」で参照しています。
ajg2 = aj1[np.newaxis, :] print(ajg2)
結果はreshape(1,3)とした場合と全く同じです。
[
[1 2 3 4 5 6 7 8 9]
]
1次元から列ベクトルへ
これは、ようするに。
[1 2 3 4 5 6 7 8 9]
を
[[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9]]
にすることです。
当然ながら「reshape(9, 1)」とやってもできます。
でも、こちらもスライスで「np.newaxis」を使ったパターンをよく見ます。
元になる1次元配列は「aj1」で参照しています。
ajg2 = aj1[:, np.newaxis] print(ajg2)
結果は「(9,1)でreshape()」した場合と同じです。
多次元から1次元に
ようするに、例えば
[[1 2 3]
[4 5 6]
[7 8 9]]
を
[1 2 3 4 5 6 7 8 9]
に戻すことです。
flatten()を使います。
以下に一旦3×3にして、1次元に戻す例をやってます。
元の3×3配列を「aj33」として参照しています。
af = aj33.flatten() print(af)
flatten()の結果はこんな感じ。
[1 2 3 4 5 6 7 8 9]
いけてます。
転置
転置とは、例えば「3×4」の配列を、「4×3」にするみたいに、行と列を入れ替えることです。
具体例でいえば
[[4 4 3 1]
[1 0 6 1]
[8 6 6 6]]
を
[[4 1 8]
[4 0 6]
[3 6 6]
[1 1 6]]
にする感じです。
これは、Numpy配列を「a7」とすると
転置後の配列 = a7.T
とすればいいです。
連結
垂直(行が下に追加される感じ)で連結
例えば。
[[4 3 5]
[2 5 9]
[0 1 8]]
と
[[5 2 3]
[4 1 6]
[3 5 5]]
という2つの3×3配列を連結します。
便宜上、上を「g1」、下を「g2」とします。
垂直の連結は、2つやり方があります。
結果はどちらも同じです。
# 方法1 cg1 = np.concatenate([g1, g2]) # 方法2 cg3 = np.vstack([g1, g2])
どちらも結果は以下のように行追加の形になります。
[[4 3 5]
[2 5 9]
[0 1 8]
[5 2 3]
[4 1 6]
[3 5 5]]
水平(列が後ろに追加される感じ)で連結
こちらも2通りのやり方があり、結果はどちらも同じです。
# 方法1 cg2 = np.concatenate([g1, g2], axis=1) # 方法2 cg4 = np.hstack([g1, g2])
結果は以下のように列が追加される感じになります。
[[4 3 5 5 2 3]
[2 5 9 4 1 6]
[0 1 8 3 5 5]]
連結があれば、分割がある・・ということで。
さきほどの最終結果の
[[8 7 6 4 9 9]
[7 7 1 5 7 5]
[9 4 3 6 0 0]]
を分割してみます。
分割
垂直方向(行単位でわかれていく感じ)に分割
とりあえず3つに分けます。
2つの方法があります。
# 方法1 d1, d2, d3 = np.vsplit(cg2, 3) # 方法2 ds1, ds2, ds3 = np.split(cg2, 3, axis=0)
どちらも結果は同じです。
注意するのは分割する数にあわせ、左辺の受取側を増やさないといけないところです。
3つを続けて表示すると。
[
[8 7 6 4 9 9]
]
[
[7 7 1 5 7 5]
]
[[9 4 3 6 0 0]
]
水平方向(列単位でわかれていく感じ)に分割
これも2つの方法があります。
# 方法1 h1, h2, h3 = np.hsplit(cg2, 3) # 方法2 hs1, hs2, hs3 = np.split(cg2, 3, axis=1)
結果はこんな感じで列方向に3つにわかれます。
[[8 7]
[7 7]
[9 4]]
[[6 4]
[1 5]
[3 6]]
[[9 9]
[7 5]
[0 0]]
左辺の受取側を分割する数にあわせて増やさないといけないのは同じです。
組み込み関数
主に集約や最大値・最小値を取得する関数です。
イメージしやすいように、以下の配列を引数にした結果を表に書いてます。
[[-6 3 8]
[-4 6 4]]
上記は「d」として表現しています。
組込み関数(例) | 説明 | 結果 |
---|---|---|
np.absolute(d) | 絶対値 | [[6 3 8] [4 6 4]] |
np.sum(d) | 配列全たの合計 | 11 |
d.sum(axis=0) | 列単位の合計 | [-10 9 12] |
d.sum(axis=1) | 行単位の合計 | [5 6] |
np.max(d) | 配列全体の最大値 | 8 |
d.max(axis=0) | 列単位の最大値 | [-4 6 8] |
d.max(axis=1) | 行単位の最大値 | [8 6] |
np.argmax(d) | 配列全体の最大値のインデックス | 2 |
d.argmax(axis=0) | 行単位の最大値のインデックス | [1 1 0] |
d.argmax(axis=1) | 列単位の最大値のインデックス | [2 1] |
np.min(d) | 配列全体の最小値 | -6 |
d.min(axis=0) | 列単位の最大値 | [-6 3 4] |
d.min(axis=1) | 行単位の最大値 | [-6 -4] |
np.prod(d) | 要素の籍を計算 | 13824 |
np.mean(d) | 要素の平均値を計算 | 1.83333333333333 |
np.median(d) | 要素の中央値を計算 | 3.5 |
np.dot(a, c) | ドット積 | [[-72 48 92] [-66 57 80] [-66 57 80]] |
他にも沢山あります。
Universal functions(ufunc)は、Numpyの配列(ndarray)に対して、要素ごとに演算等の処理を行い、結果をNumpyの配列(ndarray)で返す関数のことです。
とりあえず、このくらいです。