ラベル Numpy の投稿を表示しています。 すべての投稿を表示
ラベル Numpy の投稿を表示しています。 すべての投稿を表示

2024年4月21日日曜日

【Numpy】numpy.T/numpy.transpose/ndarray.transposeによる二次元行列の転置

 Pythonの数値計算ライブラリNumPyの配列型データ構造であるndarrayを転置(行と列の入れ替え)する場合、numpy.Tnumpy.transposeまたはndarray.transposeを用いる。

Numpyを使う際にはimportが必要。しばしばnpと略さてインポートされる。

import numpy as np



1. numpy.T属性、numpy.transposeメソッド、ndarray.transpose関数による二次元ndarrayの転置

 二次元ndarrayに対してnumpy.T属性をとると、行と列が入れ替わった転置行列が返される。
2行3列のndarrayのnumpy.T属性を取り転置行列を得る例。

import numpy as np

a = np.array([[-1, 2, 5], [3, 1, 7]])
a.T

実行結果

array([[-1,  3],
       [ 2,  1],
       [ 5,  7]])


 numpy.transpose()により同様の転置操作ができる。

import numpy as np

a = np.array([[-1, 2, 5], [3, 1, 7]])
np.transpose(a)

実行結果

array([[-1,  3],
       [ 2,  1],
       [ 5,  7]])


 また、ndarray.transpose()でも同様の転置操作ができる。

import numpy as np

a = np.array([[-1, 2, 5], [3, 1, 7]])
a.transpose()

実行結果

array([[-1,  3],
       [ 2,  1],
       [ 5,  7]])


2. リファレンス

NumPy > numpy.ndarray.T
NumPy > numpy.transpose
NumPy > numpy.ndarray.transpose

使用バージョン:Python 3.10.4/numpy 1.26.4

2022年5月6日金曜日

【Numpy】whereによる条件に合う要素に対する演算

 Pythonの数値計算ライブラリNumPyの配列型データ構造であるndarrayの要素に対して、条件に合うもののみ演算を行う場合whereを用いる。

Numpyを使う際にはimportが必要。しばしば次のようにnpと略されてインポートされる。

import numpy as np



1. whereの書式

 whereの書式は以下。conditionに条件式を書き、条件が適合する要素に対して処理xが実行され、それ以外に対しては処理yが実行される。condition, x, yいずれも必須の引数。

numpy.where(condition, [x, y, ]/)


2. whereの例

 一次元ndarrayの要素が5以上の場合、値を10倍する例。

import numpy as np

a = np.arange(10)
b = np.where(a < 5, a, 10*a)

print(b)

実行結果

[ 0  1  2  3  4 50 60 70 80 90]


 二次元ndarrayの場合。conditionTrueの場合、xFalseの場合、yの値が用いられる。

import numpy as np

a = np.array([[True, False], [True, True]])
print(np.where(a, 
               [[1, 2], [3, 4]],
               [[9, 8], [7, 6]]))

実行結果

[[1 8]
 [3 4]]


3. リファレンス

NumPy > numpy.where

使用バージョン:Python 3.10.4/numpy 1.22.3

2022年2月3日木曜日

【Numpy】appendによる値やlist, ndarrayの追加

 Pythonの数値計算ライブラリNumPyの配列型データ構造であるndarrayに値や別のndarrayを追加する際には、numpy.appendを用いる。

Numpyを使う際にはimportが必要。しばしば次のようにnpと略されてインポートされる。

import numpy as np



1. appendの書式

 appendの書式は以下。appendでは元のndarrayに追加されるのではなくコピーが生成される。

numpy.append(arr, values, axis=None)
引数 意味
arr 追記されるndarrayまたはlist
values 追記するndarrayまたはlist。arrと
axis オプション。指定しなければarr、valusの値が一次元ndarrayにコピーされる。指定した場合指定した軸方向に追加される。


2. 一次元ndarrayへのappend

 

一次元ndarray[10, 11, 12]に13を追記する例。

import numpy as np

x = np.array([10, 11, 12])
print(np.append(x, 13))

実行結果

[10 11 12 13]


list[13, 14]を追記する例。

import numpy as np

x = np.array([10, 11, 12])
print(np.append(x, [13, 14]))

実行結果

[10 11 12 13 14]


arrvaluesの順番を入れ替えると追記後の順番を変えられる。

import numpy as np

x = np.array([10, 11, 12])
print(np.append([13, 14], x))

実行結果

[13 14 10 11 12]


3. 二次元以上のndarrayへのappend

 

二次元以上のndarrayへのappendではaxisを指定することで次元を維持して追記できる。
axisを指定しないで二次元ndarrayappendする場合。一次元に変換される。

import numpy as np

x = np.array([[10, 11, 12], [13, 14, 15]])
print(np.append(x, [[16, 17, 18]]))

実行結果

[10 11 12 13 14 15 16 17 18]


二次元ndarrayへのappendaxis=0を指定した場合。

import numpy as np

x = np.array([[10, 11, 12], [13, 14, 15]])
print(np.append(x, [[16, 17, 18]], axis=0))

実行結果

[[10 11 12]
 [13 14 15]
 [16 17 18]]


 

三次元ndarrayへのappendaxis=1を指定した場合。

import numpy as np

x = np.array([[[10, 11, 12], [13, 14, 15]]])
print(np.append(x, [[[16, 17, 18]]], axis=1))

実行結果

[[[10 11 12]
  [13 14 15]
  [16 17 18]]]


4. リファレンス

NumPy > numpy.append

使用バージョン:Python 3.8.12/numpy 1.21.5

2021年12月20日月曜日

【Numpy】ndarrayの変形(reshape)

 Pythonの数値計算ライブラリNumPyの配列型データ構造であるndarrayを変形する際には、numpy.reshapeまたはndarray.reshapeを用いる。

Numpyを使う際にはimportが必要。しばしばnpと略さてインポートされる。

import numpy as np



1. reshapeによるndarrayの変形

 numpy.reshapeでは引数に変換するndarrayおよび変換後の形状を数字またはタプルで与える。
1行6列のndarrayをnumpy.reshapeにより3行2列に変形する例。

import numpy as np

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

実行結果

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


 1行6列のndarrayをndarray.reshapeにより3行2列に変形する例。引数に変換後の形状を与える。

import numpy as np

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

実行結果

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


2. リファレンス

NumPy > numpy.reshape
NumPy > numpy.ndarray.reshape

使用バージョン:Python 3.8.8/numpy 1.20.1

2021年9月12日日曜日

【Numpy】ndarrayと数値の演算・ndarray同士の演算

 Pythonの数値計算モジュールNumPyの配列型データ構造であるndarrayと数値の演算、ndarrayndarrayの演算について説明する。

Numpyを使う際にはimportが必要。しばしばnpと略される。

import numpy as np



1. ndarrayと数値の計算

 要素が数値であるndarrayと数値を演算した場合、ndarrayの全要素に対して同じ演算が適用される。
数字の加算の例。各要素に2が足される。

import numpy as np

y = np.array([[10, 11, 12],[13, 14, 15]])
print(y + 2)

実行結果

[[12 13 14]
 [15 16 17]]


 べき乗の例。各要素が二乗される。

import numpy as np

y = np.array([[10, 11, 12],[13, 14, 15]])
print(y ** 2)

実行結果

[[100 121 144]
 [169 196 225]]


 要素が文字のndarrayは演算できない

import numpy as np

y = np.array([['10', '11', '12'],['13', '14', '15']])
print(y * 2)

実行結果

UFuncTypeError: ufunc 'multiply' did not contain a loop with signature matching typesnumpy.core._exceptions._UFuncNoLoopError: ufunc 'multiply' did not contain a loop with signature matching types


2. ndarray同士の計算

 同じ形状のndarray同士の演算では同じ位置の要素同士が演算される

import numpy as np

x = np.array([[1, 1, 1], [2, 2, 2]])
y = np.array([[10, 11, 12], [13, 14, 15]])
print(x * y)

実行結果

[[10 11 12]
 [26 28 30]]


 1行n列のndarrayとm行1列のndarrayの演算では、それぞれのndarrayがm行n列のndarrayに展開され要素同士が演算される。結果はm行n列のndarrayとなる。
1行4列のndarrayと3行1列のndarrayの演算。それぞれのndarrayが3行4列に展開され要素同士が演算される。

import numpy as np

x = np.array([1, 2, 3, 4])
y = np.array([[10], [11], [12]])
print(x * y)

実行結果

[[10 20 30 40]
 [11 22 33 44]
 [12 24 36 48]]


 m行n列のndarrayとm行1列のndarrayの演算では、後者がm行n列に展開され要素同士が演算される。結果はm行n列のndarrayとなる。
2行3列のndarrayと2行1列のndarrayの演算。後者が2行3列に展開され要素同士が演算される。

import numpy as np

x = np.array([[1, 1, 1], [2, 2, 2]])
y = np.array([[10],[11]])
print(x / y)

実行結果

[[0.1        0.1        0.1       ]
 [0.18181818 0.18181818 0.18181818]]


 m行n列のndarrayと1行n列のndarrayの演算では、後者がm行n列に展開され要素同士が演算される。結果はm行n列のndarrayとなる。
2行3列のndarrayと1行3列のndarrayの演算。後者が2行3列に展開され要素同士が演算される。

import numpy as np

x = np.array([[1, 1, 1], [2, 2, 2]])
y = np.array([10, 11, 12])
print(x / y)

実行結果

[[0.1        0.09090909 0.08333333]
 [0.2        0.18181818 0.16666667]]


3. リファレンス

NumPy > Basic Operations

使用バージョン:Python 3.8.8/numpy 1.20.1

2021年8月8日日曜日

【Numpy】numpy.dot/ndarray.dotによる行列の積

 Pythonの数値計算ライブラリNumpyの配列型データ構造ndarrayで行列の積を計算する場合numpy.dot/ndarray.dotを用いる。

Numpyを使う際にはimportが必要。しばしばnpと略される。

import numpy as np


1. numpy.dotによる行列の積

 2X2行列同士の積は以下のようにあらわされる。

\[ A = \begin{pmatrix} a_{11} & a_{12} \\ a_{21} & a_{22} \end{pmatrix} \] \[ B = \begin{pmatrix} b_{11} & b_{12} \\ b_{21} & b_{22} \end{pmatrix} \] \[ A \cdot B = \begin{pmatrix} a_{11}*b_{11}+a_{12}*b_{21} & a_{11}*b_{12}+a_{12}*b_{22} \\ a_{21}*b_{11}+a_{22}*b_{21} & a_{21}*b_{12}+a_{22}*b_{22} \end{pmatrix} \]

 numpy.dotにより行列の積が求められる。
2つのndarray、aとbの積を求める場合。

import numpy as np

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

print(np.dot(a, b))

実行結果

[[ 0  3]
 [14  5]]


2. ndarray.dotによる行列の積

ndarray.dotでも同様に行列の積が求まる。

import numpy as np

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

print(a.dot(b))

実行結果

[[ 0  3]
 [14  5]]


3. リファレンス

Scipy.org > Numpy > numpy.dot
Scipy.org > Numpy > numpy.ndarray.dot

使用バージョン:Python 3.8.8/numpy 1.20.1

2021年6月27日日曜日

【Numpy】ndarray任意の行・列の合計、平均

外部モジュールNumPyの配列型データ構造であるndarrayで特定の軸の要素の合計、平均の求め方について説明する。

Numpyを使う際にはimportが必要。しばしばnpと略される。

import numpy as np


1. numpy.sumによる要素の合計

sumは1つのndarray内の要素の最大値を求める。引数にaxisを指定すると行ごと、列ごとの合計が求まる。
書式は以下。

numpy.sum(a, axis=None, dtype=None, out=None, keepdims=<no value>, initial=<no value>, where=<no value>)

1次元のndarrayの場合。全要素の合計が求まる。戻り値はスカラー。1軸しかないのでaxisは指定しない。

import numpy as np

np.sum([2, 3, 4])

実行結果

9


2行3列の2次元のndarrayの場合。axisを指定しない場合、全要素の合計が求まる。

import numpy as np

np.sum([[2,3,4],[6,5,1]])

実行結果

21


2行3列の2次元のndarrayaxis=0を指定した場合。各列の合計が求まる(行方向、つまり縦に足される)。

import numpy as np

np.sum([[2,3,4],[6,5,1]], axis=0)

実行結果

array([8, 8, 5])


2行3列の2次元のndarrayaxis=1を指定した場合。各行の合計が求まる(列方向、つまり横に足される)。

import numpy as np

np.sum([[2,3,4],[6,5,1]], axis=1)

実行結果

array([ 9, 12])


initialに値を与えると、その値が加算された結果となる。

import numpy as np

np.sum([[2,3,4],[6,5,1]], axis=1, initial=100)

実行結果

array([109, 112])


whereは要素の採用/不採用を決める。Trueの要素は加算され、Falseの要素は無視される。
各行の1つ目の要素(2,6)はFalseなので無視され、Trueである2つ目、3つ目の要素が合計される。

import numpy as np

np.sum([[2,3,4],[6,5,1]], axis=1, where=[False, True, True])

実行結果

array([7, 6])


2. numpy.ndarray.sumによる要素の合計

ndarray.sumsumと同じ結果が得れる。

ndarray.sum(axis=None, dtype=None, out=None, keepdims=False, initial=0, where=True)


2行3列の2次元のndarrayaxis=1を指定した場合。各行の合計が求まる(列方向、つまり横に足される)。

import numpy as np

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

実行結果

array([ 9, 12])


3. numpy.meanによる要素の平均

meanは1つのndarray内の要素の平均を求める。引数にaxisを指定すると行ごと、列ごとの平均が求まる。
書式は以下。

numpy.mean(a, axis=None, dtype=None, out=None, keepdims=<no value>, *, where=<no value>)


2行3列の2次元のndarray全要素の平均を求める場合。axisを指定しない。

import numpy as np

np.mean([[2,3,4],[6,5,1]])

実行結果

3.5


2行3列の2次元のndarrayaxis=0を指定、各列の平均が求まる(行方向の平均)

import numpy as np

np.mean([[2,3,4],[6,5,1]], axis=0)

実行結果

array([4. , 4. , 2.5])


2行3列の2次元のndarrayaxis=1を指定、各行の平均が求まる(列方向の平均)

import numpy as np

np.mean([[2,3,4],[6,5,1]], axis=1)

実行結果

array([3., 4.])


4. numpy.averageによる要素の平均

averagemean同様に1つのndarray内の要素の平均を求める。meanと異なる点は、引数にweightsを指定することでウエイトを掛けた平均が求められる点。
書式は以下。

numpy.average(a, axis=None, weights=None, returned=False)


2行3列の2次元のndarrayaxis=0を指定、各列の平均が求まる(行方向の平均)。meanと同じ結果となる

import numpy as np

np.average([[2,3,4],[6,5,1]], axis=0)

実行結果

array([4. , 4. , 2.5])


引数weightsを指定すると要素にそれを掛けた平均が求まる
以下の計算式で計算される。

avg = sum(a * weights) / sum(weights)

次の例ではweightsとして0.5と2を指定している。これにより計算は
(2*0.5+6*2)/(0.5+2)
(3*0.5+5*2)/(0.5+2)
(4*0.5+1*2)/(0.5+2)
となりweightsの掛かった平均が求められる。

import numpy as np

np.average([[2,3,4],[6,5,1]], axis=0, weights=[0.5,2])

実行結果

array([5.2, 4.6, 1.6])


5. リファレンス

NumPy > numpy.sum
NumPy > numpy.ndarray.sum
NumPy > numpy.mean
NumPy > numpy.average

使用バージョン:Python 3.7.0/numpy 1.18.4

2021年6月25日金曜日

【Numpy】ndarrayの分割

Numpyの配列型データ構造であるndarrayを分割する方法について説明する。

Numpyを使う際にはimportが必要。しばしばnpと略される。

import numpy as np


1. splitによる分割

splitによりndarrayが分割される。書式は以下の通り。

numpy.split(ary, indices_or_sections, axis=0)
引数 意味
ary:ndarray 分割するndarray
indices_or_sections:int or 1-D array 整数の場合その個数のndarrayに等分される。昇順の数字からなる1次元のリストを指定した場合その数字をインデックスとして分割される
axis:int, optional 分割する向きの指定。指定が無い場合はデフォルトの0となる。

0~8の9個の要素からなる1次元のndarrayを三等分する場合。indices_or_sectionsに3を指定する。
分割前のndarray

import numpy as np

x = np.arange(9)
x

実行結果

array([0, 1, 2, 3, 4, 5, 6, 7, 8])

3分割後

import numpy as np

x = np.arange(9)
np.split(x, 3)

実行結果

[array([0., 1., 2.]), array([3., 4., 5.]), array([6., 7., 8.])]


分割後の要素を取り出すには分割数分の変数で受け取る。

import numpy as np

x = np.arange(9)
y1, y2, y3 = np.split(x, 3)
y1

実行結果

array([0, 1, 2])


スライスしても良い。

import numpy as np

x = np.arange(9)
y = np.split(x, 3)[0]
y

実行結果

array([0, 1, 2])


等分割できない数を指定するとエラーとなる。0~8の9個の要素からなる1次元のndarrayに対してindices_or_sectionsに2を指定した場合、2等分できないためエラーとなる。

import numpy as np

x = np.arange(9)
np.split(x, 2)

実行結果

ValueError: array split does not result in an equal division


indices_or_sectionsにリストを指定するとその数字をインデックスとして分割される。3,5,9を指定した場合、3つ目の要素まで、4つ目から5つ目の要素まで、6つ目から9つ目の要素までの3つに分割される。

import numpy as np

x = np.arange(9)
np.split(x, [3,5,9])

実行結果


[array([0, 1, 2]), array([3, 4]), array([5, 6, 7, 8]), array([], dtype=int32)]


2次元のndarrayを分割する例。3行3列の2次元ndarrayが、3つの1行3列の2次元ndarrayに等分される。
分割前のndarray

import numpy as np

x = np.arange(9).reshape(3, 3)
x

実行結果

array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

分割後

import numpy as np

x = np.arange(9).reshape(3, 3)
np.split(x, 3)

実行結果

[array([[0, 1, 2]]), array([[3, 4, 5]]), array([[6, 7, 8]])]


2次元のndarray分割の際に向きを指定した場合。向きをaxis=1と指定するとデフォルト(axis=0)に対して直行した方向に分割される。

import numpy as np

x = np.arange(9).reshape(3, 3)
np.split(x, 3)

実行結果

[array([[0],
        [3],
        [6]]), 
 array([[1],
        [4],
        [7]]), 
 array([[2],
        [5],
        [8]])]


2. array_splitによる分割

array_splitによりndarrayが分割される。要素数が分割数で割り切れなくてもエラーとならない点がsplitと異なる。書式は以下の通りでsplitと同じ。

numpy.array_split(ary, indices_or_sections, axis=0)

要素数9のndarrayを2つに分割する場合。要素数5、要素数4の2つに分割される。

import numpy as np

x = np.arange(9)
np.array_split(x, 2)

実行結果


[array([0, 1, 2, 3, 4]), array([5, 6, 7, 8])]


要素数9のndarrayを5つに分割する場合。要素数2のarray4つと要素数1のarray1つに分割される。

import numpy as np

x = np.arange(9)
np.array_split(x, 5)

実行結果

[array([0, 1]), array([2, 3]), array([4, 5]), array([6, 7]), array([8])]


3. hsplitによる水平方向分割

hsplitによりndarrayが水平方向に分割される。splitaxis = 1とした場合と同じ。

要素数16の4行4列のndarrayを2つに分割する場合。2つの4行2列のndarrayに分割される。
分割前

import numpy as np

x = np.arange(16).reshape(4, 4)
x

実行結果

array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

分割後

import numpy as np

x = np.arange(16).reshape(4, 4)
np.hsplit(x,2)

実行結果

[array([[ 0,  1],
        [ 4,  5],
        [ 8,  9],
        [12, 13]]), array([[ 2,  3],
        [ 6,  7],
        [10, 11],
        [14, 15]])]


4. vsplitによる垂直方向分割

vsplitによりndarrayが垂直方向に分割される。splitaxis = 0とした場合と同じ。

要素数16の4行4列のndarrayを2つに分割する場合。2つの2行4列のndarrayに分割される。
分割前

import numpy as np

x = np.arange(16).reshape(4, 4)
x

実行結果

array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

分割後

import numpy as np

x = np.arange(16).reshape(4, 4)
np.vsplit(x,2)

実行結果

[array([[0, 1, 2, 3],
        [4, 5, 6, 7]]), array([[ 8,  9, 10, 11],
        [12, 13, 14, 15]])]


5. dsplitによる深さ方向分割

dsplitにより3かそれ以上の次元を持つndarrayが深さ方向に分割される。splitaxis = 2とした場合と同じ。

要素数12の3x2x2のndarrayを深さ方向に2つに分割する場合。
分割前

import numpy as np

x = np.arange(12).reshape(3, 2, 2)
x

実行結果

array([[[ 0,  1],
        [ 2,  3]],

       [[ 4,  5],
        [ 6,  7]],

       [[ 8,  9],
        [10, 11]]])

分割後

import numpy as np

x = np.arange(12).reshape(3, 2, 2)
np.dsplit(x, 2)

実行結果

[array([[[ 0],
         [ 2]],
 
        [[ 4],
         [ 6]],
 
        [[ 8],
         [10]]]), array([[[ 1],
         [ 3]],
 
        [[ 5],
         [ 7]],
 
        [[ 9],
         [11]]])]


6. リファレンス

Scipy.org > Numpy > numpy.split
Scipy.org > Numpy > numpy.array_split
Scipy.org > Numpy > numpy.hsplit
Scipy.org > Numpy > numpy.vsplit
Scipy.org > Numpy > numpy.dsplit

使用バージョン:Python 3.7.0/numpy 1.18.4

2020年7月13日月曜日

【Numpy】ndarrayの複製

ndarrayをコピーする場合、そのやり方によってコピー元・先のオブジェクトが束縛される場合と別のオブジェクトとなる場合があり注意が必要。代入演算子で複製すると参照渡しとなり同じメモリ領域を参照するためコピー先のオブジェクトとコピー元のオブジェクトに互いに影響される。コピー先のオブジェクトをコピー元のオブジェクトとリンクさせたくない場合はndarray.copynumpy.copycopyモジュールを使う。


1. 代入演算子=によるリストのコピー

ndarrayを代入演算子で複製すると参照渡しとなり、コピー先のオブジェクトとコピー元のオブジェクトが同じメモリ領域を参照することになる。このためどちらかの値を変更するともう一方の値も変更されてしまう。

代入演算子=によりyにndarray xを代入した場合。代入後にxの値を変更するとyの値も変更される。関数id()によりidを確認するとx,yが同じidとなっている、つまり同じオブジェクトとして取り扱われていることが分かる。

import numpy as np

x = np.array([1,2,3])
y = x

print(x, y)

x[0] = 4

print(x, y)

print(id(x), id(y))

実行結果

[1 2 3] [1 2 3]
[4 2 3] [4 2 3]
1616122140032 1616122140032


2. スライスによるndarrayのコピー

コピー元のndarrayの要素をスライシングにより取り出してコピー先のndarrayに代入すると、ndarrayidは別になるが要素の変更の影響を受ける。これは要素が参照渡しとなっているため。(要素のidは同じ)

import numpy as np

x = np.array([1,2,3])
y = x[:]

print(x, y)

x[0] = 4

print(x, y)

print(id(x), id(y))
print(id(x[0]), id(y[0]))

実行結果

[1 2 3] [1 2 3]
[4 2 3] [4 2 3]
1616227256800 1616227256320
1616225748576 1616225748576


3. ndarray.copy()メソッドによるndarrayのコピー

ndarray.copyによりコピーするとコピー元、コピー先は別のオブジェクトとなるためお互いに値を変更した際に影響を受けない。

import numpy as np

x = np.array([1,2,3])
y = x.copy()

print(x, y)

x[0] = 4

print(x, y)

print(id(x), id(y))

実行結果

[1 2 3] [1 2 3]
[4 2 3] [1 2 3]
1616227255680 1616227254560

ただし、ndarrayが要素としてリストをやndarrayを含む場合、copyによりコピーした場合も要素となっているリストやndarrayを変更するとコピー先、コピー元両方のリストが影響を受ける。コピーしたリスト自体は参照されていないが、その要素であるリストは参照渡しとなっているためである。(浅いコピー)
ndarray a, bを要素として持つndarray xをcopyでyにコピーし、aの要素を変更した場合。x, yのidは異なりx, yは参照関係に無いが、aは参照が維持されているためx, y両方の要素が変更される。これを避けるためにはnumpy.deepcopyにより「深いコピー」を行う必要がある。

import numpy as np

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

x = np.array([a, b])
y = x.copy()

print(x, y)

a[0] = 4

print(x, y)

print(id(x), id(y))

実行結果


[array([1, 2]) array([3])] [array([1, 2]) array([3])]
[array([4, 2]) array([3])] [array([4, 2]) array([3])]
1616227256320 1616227256160



4. 関数numpy.copy()によるリストのコピー

numpy.copyを用いるとcopy同様のコピーができる。

import numpy as np

x = np.array([1,2,3])
y = np.copy(x)

print(x, y)

x[0] = 4

print(x, y)

print(id(x), id(y))

実行結果

[1 2 3] [1 2 3]
[4 2 3] [1 2 3]
2230028332208 2230028332368

関数numpy.copyによるコピーは浅いコピーであり、要素としてndarrayやリストを含むリストを複製した際の挙動はndarray.copy同様に互いの要素の変更の影響を受ける

import numpy as np

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

x = np.array([a, b])
y = np.copy(x)

print(x, y)

a[0] = 4

print(x, y)

print(id(x), id(y))

実行結果


[array([1, 2]) array([3])] [array([1, 2]) array([3])]
[array([4, 2]) array([3])] [array([4, 2]) array([3])]
1616227255840 1616227256400

5. 関数copy.deepcopy()によるリストのコピー(深いコピー)

ndarrayが要素としてndarrayやリストを含む場合、ndarray.copynumpy.copyでコピーした場合、要素であるndarrayやリストは参照渡しとなる。コピー先とコピー元をリンクさせたくない場合は、標準ライブラリcopycopy.deepcopyにより「深いコピー」を行う。標準ライブラリcopyはimportが必要。
copy.deepcopy()ndarray xをndarray yにコピーしたのち、xの要素であるndarray aに値を追加する。xの要素は変更されるが、yは参照関係が切れており要素が変更されない。

import numpy as np
import copy

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

x = np.array([a, b])
y = copy.deepcopy(x)

print(x, y)

a[0] = 4

print(x, y)

print(id(x), id(y))

実行結果


[array([1, 2]) array([3])] [array([1, 2]) array([3])]
[array([4, 2]) array([3])] [array([1, 2]) array([3])]
1616227863648 1616227257440


6. リファレンス

NumPy > numpy.copy
NumPy > numpy.ndarray.copy
NumPy > numpy.copy
Python 標準ライブラリ > データ型 > copy --- 浅いコピーおよび深いコピー操作

使用バージョン:Python 3.7.0/numpy 1.18.4

2020年6月13日土曜日

【Numpy】ndarray要素の最大値・最小値取得

 Pythonの数値計算ライブラリNumPyの配列型データ構造であるndarrayの要素の最大値・最小値を取得する方法ついて説明する。

Numpyを使う際にはimportが必要。しばしばnpと略される。

import numpy as np



1. max/min(amax/amin)によるndarray内の最大値・最小値取得

 maxは1つのndarray内の要素の最大値を求める。引数にaxisを指定すると行ごと、列ごとの最大値を求めることができる。maxamaxの別名であり同じ関数(どちらを使っても同じ結果となる)。

axisを指定しない場合、全要素の最大値が求まる。戻り値はスカラー。

import numpy as np

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

実行結果

6


 axis=0を指定した場合。第1軸方向に各々の要素の最大値が求まる。戻り値はndarrayになる。

import numpy as np

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

実行結果

[6, 5, 4]


 axis=1を指定すると第2軸方向に各々の要素の最大値が求まる。戻り値はndarrayになる。

import numpy as np

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

実行結果

[4, 6]


 要素の最小値はmin(または別名のamin)により求まる。
軸を指定せず全要素の最小値を求める場合。

import numpy as np

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

実行結果

1


 axis=0を指定した場合。第1軸方向に各々の要素の最小値が求まり戻り値はndarrayになる。

import numpy as np

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

実行結果

[2, 3, 1]


 axis=1を指定した場合。第2軸方向に各々の要素の最小値が求まり戻り値はndarrayになる。

import numpy as np

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

実行結果

[2, 1]


2. maximum/minumumによる2つのndarray間の最大値・最小値取得

 max/minでは一つのndarray内の最大最小が求まるが、2つのndarrayの最大最小を求めるにはmaximum/minumumを用いる。
numpy.maximumで2つのndarrayの同じインデックスの要素同士を比較し大きい方を抽出する。

import numpy as np

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

print(np.maximum(a,b))

実行結果

[[2, 3, 8],
 [6, 5, 4]]


 比較するndarrayの形状は同じでないとエラーになる。

import numpy as np

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

print(np.maximum(a,b))

実行結果

ValueError: operands could not be broadcast together with shapes (2,4) (2,3) 


 numpy.minimumで2つのndarrayの同じインデックスの要素同士を比較し小さい方を抽出する。

import numpy as np

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

print(np.minimum(a,b))

実行結果

[[0, 1, 4],
 [2, 3, 1]]


3. リファレンス

NumPy > numpy.amax
NumPy > numpy.amin
NumPy > numpy.maximum
NumPy > numpy.minimum

使用バージョン:Python 3.7.0/numpy 1.18.4

2020年5月17日日曜日

【Numpy】インデックス・スライスによるndarray要素の取得

 多次元配列計算を効率よく実行できる数値計算ライブラリNumPyの配列型データ構造であるndarrayはリストやタプルと同様にインデックス・スライスによって要素を取得できる。

NumPyを使う際にはimportが必要。しばしばnpと略される。

import numpy as np


1. 1次元ndarrayの場合

 要素が一列に並んだ形の1次元ndarrayに対しては、後ろに[]で囲ったインデックスを付けることで要素を取得できる。最初の要素がインデックス0となり順番に0,1,2とインデックス番号が付く。
イデックス1つまり2番目の要素を指定した場合。

import numpy as np

x = np.array([10, 20, 30, 40, 50, 60])
print(x[1])

実行結果

20


 インデックス番号に-(マイナス)を付けるとndarrayの後ろからの位置指定となる。一番最後の要素が-1、先頭方向に-2,-3となる。
イデックス-3つまり後ろから3番目の要素を指定した場合。

import numpy as np

x = np.array([10, 20, 30, 40, 50, 60])
print(x[-3])

実行結果

40


 インデックスではなくスライスを用いると範囲指定ができる。スライスの書式は[開始位置:終了位置:step]となる。stepを省略した場合は範囲の全ての要素を指定することとなる。またスライスによって取得した要素はndarrayとなる。
2つまり3番目から4つまり5番目までの要素を指定した場合。

import numpy as np

x = np.array([10, 20, 30, 40, 50, 60])
print(x[2:4])

実行結果

[30, 40]


 スライスの終了位置を省略すると開始位置とそれ以降の全ての要素が指定される。
3つまり4番目以降の要素を指定した場合。

import numpy as np

x = np.array([10, 20, 30, 40, 50, 60])
print(x[3:])

実行結果

[40, 50, 60]


 スライスの開始位置を省略すると終了位置より前(終了位置は含まれない)の全ての要素が指定される。
3つまり4番目までの要素を指定した場合。

import numpy as np

x = np.array([10, 20, 30, 40, 50, 60])
print(x[:3])

実行結果

[10, 20, 30]


2. 2次元ndarrayの場合

 2次元ndarrayは1次元ndarrayをカンマで区切って複数並べ[]で囲った構造。arrayの軸(要素が並ぶ向き)がaxis=0、axis=1の2方向となる。2次元ndarrayに対してインデックスを1つだけ付けた場合はaxis=0の向きのインデクシングとなり要素である1次元ndarrayを指定することになる。
インデックス[1]として2番目の要素を指定した場合。

import numpy as np

x = np.array([[10, 20, 30],
              [40, 50, 60]])
print(x[1])

実行結果

[40, 50, 60]


 カンマで区切って2つ目のインデックスを付ければ要素の中の要素を指定できる(axis=0、axis=1の2方向とも指定)。
axis=0をインデックス1(2番目の要素)、axis=1をインデックス2(3番目の要素)とした場合。

import numpy as np

x = np.array([[10, 20, 30],
              [40, 50, 60]])
print(x[1, 2])

実行結果

60


 1番目のインデックスを省略し2番目のインデックスのみ指定することでaxis=1方向に要素を指定できる。インデックスを省略する場合は:を用いる(スライシングで全要素を指定している)。

import numpy as np

x = np.array([[10, 20, 30],
              [40, 50, 60]])
print(x[:, 2])

実行結果

[30, 60]


1次元ndarray同様インデクシングが可能。

import numpy as np

x = np.array([[10, 20, 30],
              [40, 50, 60]])
print(x[1, 1:3])

実行結果

[50, 60]


3. 3次元ndarrayの場合

 例えば画像ファイルは x方向の位置、y方向の位置、RGB各画素の輝度 の3次元の配列となる。
このような3次元ndarrayにはaxis=0,1,2の3方向あるためインデックスの数字も3つになる。
次の例では最初のインデックス 1 で [[200, 210, 220], [230, 240, 250]] を選び(axis=0)
次のインデックス 1 で [230, 240, 250] を選び1(axis=1)
最後のインデックス 0 で 230 を選んでいる(axis=2)。

import numpy as np

x = np.array([[[100, 110, 120], [160, 170, 180]],
              [[200, 210, 220], [230, 240, 250]]])

print(x[1, 1, 0])

実行結果

230


インデックス・スライスの書き方は1次元、2次元と同様。
axis=0,1がコロン(:)により全てを選択、axis=2としている。

import numpy as np

x = np.array([[[100, 110, 120], [160, 170, 180]],
              [[200, 210, 220], [230, 240, 250]]])

print(x[:, :, 2])

実行結果

[[120 180]
 [220 250]]


4. リファレンス

NumPy > Indexing
NumPy > Quickstart tutorial
Scipy.org > NumPy > numpy.ndarray

使用バージョン:Python 3.7.0/numpy 1.18.4

2020年4月12日日曜日

【Numpy】ndarrayの要素数、次元、形状の取得

 Pythonの数値計算ライブラリNumpyの配列型データ構造であるndarrayの要素数を取得するsize、次元数を取得するndimおよび形状を取得するshapeについて説明する。

Numpyを使う際にはimportが必要。通常npと略される。

import numpy as np


1. sizeによる要素数の取得

 sizeにより配列の次元によらず要素数が取得される。

import numpy as np

x = np.array([10, 11, 12])
print(x.size)

実行結果

3


import numpy as np

x = np.array([[10, 11, 12],[2, 3, 4]])
print(x.size)

実行結果

6


2. ndimによる次元数の取得

ndimにより配列の次元数が取得できる

import numpy as np

x = np.array([10, 11, 12])
print(x.ndim)

実行結果

1


import numpy as np

x = np.array([[10, 11, 12],[2, 3, 4]])
print(x.ndim)

実行結果

2


import numpy as np

x = np.array([[[12, 24, 36], [1, 2, 3]],[[5, 6, 7],[100, 110, 120]]])
print(x.ndim)

実行結果

3


3. shapeによる形状の取得

shapeにより配列の形状(行数、列数)が取得できる

import numpy as np

x = np.array([10, 11, 12])
print(x.shape)

実行結果

(3,)


import numpy as np

x = np.array([[10, 11, 12],[2, 3, 4]])
print(x.shape)

実行結果

(2, 3)


取得した形状情報はタプル型なのでインデックスで部分的に取得することが可能。

import numpy as np

x = np.array([[10, 11, 12],[2, 3, 4]])
rows = x.shape[0]
print(rows)

実行結果

2


タプル型なのでカンマで区切った複数の変数で受け取る(アンパック)ことが可能。

import numpy as np

x = np.array([[10, 11, 12],[2, 3, 4]])
rows, columns = x.shape
print(rows, columns)

実行結果

2 3


4. リファレンス

Scipy.org > Numpy > numpy.ndarray.size
Scipy.org > Numpy > numpy.ndarray.ndim
Scipy.org > Numpy > numpy.ndarray.shape

使用バージョン:Python 3.7.0 / numpy 1.18.4

2020年4月6日月曜日

【Numpy】ndarrayの作り方

 多次元配列計算を効率よく実行できるPythonの数値計算ライブラリNumPyの配列型データ構造であるndarrayの作り方について説明する。



1. NumPyのインポート

 NumPyを使う際にはimportが必要。しばしばnpと略される。

import numpy as np


2. arrayによるndarrayの生成

 numpy.arrayの引数に[]で囲った要素(つまりリスト)や()で囲った要素(つまりタプル)を与えると、ndarrayが生成される。

import numpy as np

x = np.array([10, 11, 12])
print(x)

実行結果

[10, 11, 12]


引数のリストは複数与えることが可能。

import numpy as np

y = np.array([[10, 11, 12],[13, 14, 15]])
print(y)

実行結果

[[10, 11, 12],
 [13, 14, 15]]


引数に別に作ったリストを与えても等価

import numpy as np

y1 = [10, 11, 12]
y2 = [13, 14, 15]
y = np.array([y1, y2])
print(y)

実行結果

[[10, 11, 12],
 [13, 14, 15]]


タプル→ndarrayの例。

import numpy as np

x = np.array((10, 11, 12))
print(x)

実行結果

[10, 11, 12]


3. zeros / ones / emptyによるndarrayの生成

 numpy.zerosは全ての要素が0のndarrayを生成する。numpy.onesは全ての要素が1、numpy.emptyはランダムな値が入ったndarrayが生成される。

import numpy as np

print(np.zeros(3))

実行結果

[0. 0. 0.]


import numpy as np

print(np.ones((2, 3)))

実行結果

[[1., 1., 1.],
 [1., 1., 1.]]


import numpy as np

print(np.empty((2, 3, 4)))

実行結果

[[[1.09918035e+155 1.27124315e+232 1.14448054e+243 9.92132497e+247]
  [6.01334637e-154 1.87673453e-152 1.28036948e-152 2.19528033e-152]
  [1.42709638e+248 6.52016598e+252 1.46923560e+195 6.52022889e+252]]

 [[2.43580036e-152 2.46088219e-154 8.83078595e+199 1.21906099e-152]
  [9.29380881e+242 2.17978855e+243 1.06400250e+248 6.87060129e+228]
  [1.32914175e+179 2.42766858e-154 2.32160024e-152 7.82137594e+179]]]


4. arangeによる規則的なndarrayの生成

 numpy.arangeを用いるとrange関数のように任意のステップ刻みの一次元ndarrayを生成できる。引数は(start, stop)もしくは(start, stop, step)となりstepの指定がない場合は1刻みとなる。なおrange関数では小数は使えないがarangeでは小数が使える。

import numpy as np

print(np.arange(5, 10))

実行結果

[5, 6, 7, 8, 9]


import numpy as np

print(np.arange(5, 25, 5))

実行結果

[ 5, 10, 15, 20]


import numpy as np

print(np.arange(1.5, 2.1, 0.2))

実行結果

[1.5, 1.7, 1.9, 2.1]


5. reshapeによる1次元ndarrayの変形

 reshapeにより要素は変えずにndarrayを変形できる。1次元ndarrayを生成しreshapeすることで多次元のndarrayを作成可能。書式は以下の通り。

numpy.reshape(a, newshape, order='C')
引数 意味
a : array_like 変形するndarray
newshape : int or tuple of ints 変形後の
order : {‘C’, ‘F’, ‘A’}, optional 変形後の要素の置き換え順の指定(オプション)

要素数6のndarrayを3x2の2次元ndarrayに変形する例。

import numpy as np

print(np.arange(6).reshape(3, 2))

実行結果

[[0 1]
 [2 3]
 [4 5]]


要素数12のndarrayを2x2x3の3次元ndarrayに変形する例。

import numpy as np

print(np.arange(12).reshape(2, 2, 3))

実行結果

[[[ 0  1  2]
  [ 3  4  5]]

 [[ 6  7  8]
  [ 9 10 11]]]


6. リファレンス

NumPy > Array creation
NumPy > Quickstart tutorial
Scipy.org > NumPy > numpy.ndarray
Scipy.org > NumPy > numpy.reshape

使用バージョン:Python 3.7.0/numpy 1.18.4