pythonを用いると必ず出てくるnumpy
いったい何なのでしょうか。
早い話が配列を作成するライブラリです。
ただリストとは違いデータ型は1種類のみです。
つまり[1,2,3,4,5]や[“a”,”b”,”c”,”d”]はよいが
[1,”a”,2,”b”,3]のような配列は文字型となってしまいます。
それによって計算能力を高めているという特徴があります。
※実行環境:Python 3.8.8 win10 64bit
本記事は下記の書籍を参考に記述しています。
import numpy as np
numpyをインポートします。
as npとすることでnumpy を npで利用できるようになります。
a = np.array([1,2,3,4,5])によってnumpy配列を作成できます。
※array()は配列を作成する関数です。
配列のデータ型を確認します。
print(type(a))
配列要素のデータ型も調べてみましょう。
print(a.dtype)
a = np.array([1,2,3,4,5])
print(type(a))
<class 'numpy.ndarray'>
print(a.dtype)
int32
ちなみにリスト型はこんな感じです。
a = [1,2,3,4,5]
print(type(a))
<class 'list'>
文字列型も作ってみましょう。
b = np.array(["apple","beach","cook","do"])
print(type(b))
<class 'numpy.ndarray'>
print(b.dtype)
<U5
文字列の場合<Uです。
後ろの数字は文字列の最大文字数となっています。
浮動小数はどうなるでしょう。
c = np.array([1.0,2.34,3.0,4.11,5.0])
print(type(c))
<class 'numpy.ndarray'>
print(c.dtype)
float64
float64 これが浮動小数の場合のデフォルトのデータ型となります。
次に配列要素のデータ型を変更します。
a = np.array([1,2,3,4,5]
print(a.dtype)
int32
int32でも問題はないのですが
小さいデータでもint32になりますのでメモリを無駄にする可能性があります。
dtype = np.データ型としてデータ型を指定できます。
a = np.array([1,2,3,4,5],dtype = np.int16)
print(type(a))
<class 'numpy.ndarray'>
print(a.dtype)
int16
つまり16ビットとして扱うことになります。
2の16乗で65536通りの値を識別できます。
連続する整数値でndarrayを作りたい場合は
arange()も利用することができます。
d = np.arange(0,10)
print(d)
[0 1 2 3 4 5 6 7 8 9]
2次元配列をつくることもできます。
e = np.array([[1,2,3],[4,5,6]])
print(e)
[[1 2 3]
[4 5 6]]
print(e.shape)
(2, 3)
(2,3)から2行3列であることがわかります。
ここから変形(reshape)することも可能です。
※要素数が合わないとエラーとなります。
e = e.reshape(1,6)
print(e)
[[1 2 3 4 5 6]]
2次元配列を1次元にするにはravelメソッドもあります。
e = np.array([[1,2,3],[4,5,6]])
print(e)
[[1 2 3]
[4 5 6]]
e = e.ravel()
print(e)
[1 2 3 4 5 6]
乱数の配列を作成することもできます。
f = np.random.random((3,2))
print(f)
[[0.37844464 0.43652324]
[0.40321252 0.7053158 ]
[0.32793222 0.00464435]]
指定の値で埋めることもできます。
a = np.pi
print(a)
3.141592653589793
b = np.full((2,5),np.pi)
print(b)
[[3.14159265 3.14159265 3.14159265 3.14159265 3.14159265]
[3.14159265 3.14159265 3.14159265 3.14159265 3.14159265]]
欠損値の穴埋めに使われる特殊な数値であるnp.nanを解説します。
nanはnot a numberの略です。
数値でないということを宣言しています。
※nanはデータ型としてはfloatになりますので、それにあわせて1や2もfloat型(1. 2.)になっています。
a = np.array([1,2,np.nan])
print(a)
[ 1. 2. nan]
範囲指定で均等割り配列を作成することもできます。
a = np.linspace(0,100,11)
print(a)
[ 0. 10. 20. 30. 40. 50. 60. 70. 80. 90. 100.]
配列を連結します。
a = np.array([1,2,3])
b = np.array([4,5,6])
c = np.concatenate([a,b])
print(a)
print(b)
print(c)
[1 2 3]
[4 5 6]
[1 2 3 4 5 6]
インデックス値[2]の値2を5に書き換える処理です。
a = np.arange(0,3)
print(a)
[0 1 2]
a[2] = 5
print(a)
[0 1 5]
2次元配列の0行目を7に置き換えます。
e = np.array([[1,2,3],[4,5,6]])
print(e)
[[1 2 3]
[4 5 6]]
e[0,:] = 7
print(e)
[[7 7 7]
[4 5 6]]
配列に要素を追加します。
f = np.array([1,2,3])
f = np.append(f,4)
print(f)
[1 2 3 4]
appendは末端に追加します。
場所を指定したい場合はnp.insert()です。
f = np.array([1,2,3])
f = np.insert(f,3,4)
print(f)
[1 2 3 4]
0列目に0を入力してみましょう。
f = np.insert(f,0,0)
print(f)
[0 1 2 3 4]
多次元配列に追加する場合です。
行の追加です。
2つ目の引数の1は1行目を意味します。
4つ目の0は行追加を意味して、1にすると列追加となります。
g = np.array([[1,2,3],[4,5,6],[7,8,9]])
h = np.array([0,0,0])
g = np.insert(g,1,h,0)
print(g)
[[1 2 3]
[0 0 0]
[4 5 6]
[7 8 9]]
以下のように行追加も可能です。
vstackメソッドも利用できます。
最終行に追加されます。
g = np.array([[1,2,3],[4,5,6],[7,8,9]])
h = np.array([0,0,1])
g = np.vstack([g,h])
print(g)
[[1 2 3]
[4 5 6]
[7 8 9]
[0 0 1]]
列の追加です。
2つ目の引数の2は2行目を意味します。
4つ目の1は列追加を意味しています。
g = np.array([[1,2,3],[4,5,6],[7,8,9]])
h = [0,0,0]
g = np.insert(g,2,h,1)
print(g)
[[1 2 0 3]
[4 5 0 6]
[7 8 0 9]]
以下のように列追加も可能です。
hstackメソッドも利用できます。
最終列に追加されます。
g = np.array([[1,2,3],[4,5,6],[7,8,9]])
h = [[0],[0],[0]]
g = np.hstack([g,h])
print(g)
[[1 2 3 0]
[4 5 6 0]
[7 8 9 0]]
次は分割してみましょう。
列で分割します。
print(g)
[[1 2 3 0]
[4 5 6 0]
[7 8 9 0]]
first,second = np.hsplit(g,[3])
print(first)
[[1 2 3]
[4 5 6]
[7 8 9]]
print(second)
[[0]
[0]
[0]]
行で分割します。
print(g)
[[1 2 3 0]
[4 5 6 0]
[7 8 9 0]]
first,second = np.vsplit(g,[2])
print(first)
[[1 2 3 0]
[4 5 6 0]]
print(second)
[[7 8 9 0]]
2次元配列の行と列を入れ替えます。
転置といいます。
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a.T)
[[1 4 7]
[2 5 8]
[3 6 9]]
ドット積になります。
掛ける順番を逆にすると答えが変わることに注意しましょう。
※np.dot(a,b)はa@bという記述もできます。
a = np.array([[1,2,3],[1,1,1]])
b = np.array([[10,10],[1,1],[1,1]])
np.dot(a,b)
array([[15, 15],
[12, 12]])
a = np.array([[1,2,3],[1,1,1]])
b = np.array([[10,10],[1,1],[1,1]])
np.dot(b,a)
array([[20, 30, 40],
[ 2, 3, 4],
[ 2, 3, 4]])
np.deleteを用います。
i = np.arange(0,5)
print(i)
i = np.delete(i,0)
print(i)
[0 1 2 3 4]
[1 2 3 4]
多次元配列の削除をおこないます。
3つ目の引数0は行削除を意味します。
g = [[1,2,3],[4,5,6],[7,8,9]]
g = np.delete(g,0,0)
print(g)
[[4 5 6]
[7 8 9]]
3つ目の引数を1とすると列削除になります。
g = [[1,2,3],[4,5,6],[7,8,9]]
g = np.delete(g,0,1)
print(g)
[[2 3]
[5 6]
[8 9]]
fruits = np.array([“apple”,”orange”,”grapes”])
要素番号の指定で参照できます。
fruits = np.array(["apple","orange","grapes"])
print(fruits[0])
apple
print(fruits[0:])
['apple' 'orange' 'grapes']
print(fruits[-1])
grapes
次に多次元での参照をおこないます。
fruits_sports = np.array([[“apple”,”orange”,”grapes”],[“baseball”,”soccer”,”tennis”]])
fruits_sports = np.array([["apple","orange","grapes"],["baseball","soccer","tennis"]])
print(fruits_sports[1])
['baseball' 'soccer' 'tennis']
print(fruits_sports[1,2])
tennis
print(fruits_sports[:,[0,2]])
[['apple' 'grapes']
['baseball' 'tennis']]
判定・論理値になります。
count_nonzeroメソッドにて0でない要素数を返します。
sumメソッドは条件に一致した要素数を返します。
a = np.array([0,1,2,3,4,5,6])
b = np.count_nonzero(a)
c = np.sum(a > 3)
print(b)
print(c)
6
3
# sumは要素の合計を求めることができる。
np.sum(a)
21
# anyは条件に一致した要素があるかないかを返す。
np.any(a > 4)
True
np.any(a > 6)
False
ndarrayでは四則演算が可能です。
k = np.array([1,2,3])
print(k +1)
print(k -1)
print(k *2)
print(k / 2)
[2 3 4]
[0 1 2]
[2 4 6]
[0.5 1. 1.5]
また配列同士を演算することもできます。
k = np.array([1,2,3])
l = np.array([4,5,6])
print(k + l)
[5 7 9]
多次元配列の場合です。
m = np.array([[1,2,3],[4,5,6]])
n = np.array([[2,2,2],[2,2,2]])
print(m + n)
print(m * n)
[[3 4 5]
[6 7 8]]
[[ 2 4 6]
[ 8 10 12]]
全要素に対して計算処理を適用できる関数をユニバーサル関数と呼びます。
適当に配列をまず作ります。
o = np.array([1.23,3.98,4.556,3.0,9.5])
print(o)
この配列に対して全要素に切り捨てを行います。
o = np.floor(o)
print(o)
o = np.array([1.23,3.98,4.556,3.0,9.5])
print(o)
o = np.floor(o)
print(o)
[1.23 3.98 4.556 3. 9.5 ]
[1. 3. 4. 3. 9.]
切り上げ、四捨五入も可能です。
o = np.array([1.23,3.98,4.556,3.0,9.5])
p = np.ceil(o) ※切り上げ
print(p)
q = np.round(o) ※四捨五入
print(q)
o = np.array([1.23,3.98,4.556,3.0,9.5])
p = np.ceil(o)
print(p)
q = np.round(o)
print(q)
[ 2. 4. 5. 3. 10.]
[ 1. 4. 5. 3. 10.]
ここではコピーと参照の違いを解説します。
配列a[0,1,2]を作成します。
配列aを配列a1に代入します。
配列aに変更を加えた場合、その変更が配列a1にも適応されます。
これは配列a1は配列aを参照しているからになります。
a = np.arange(0,3)
a1 = a
print(a1)
[0 1 2]
a[2] = 5
print(a)
[0 1 5]
print(a1)
[0 1 5]
もしそれぞれを独立させたいのならばcopyメソッドを用います。
a1 = a.copy()にて作成します。
配列aと配列a1は別物になります。
補足としてravelメソッドは参照でflattenメソッドはコピーになります。