記事ディレクトリ
- 1. NumPy の概要
- 2. 基本 - 配列
- 3. 配列を作成する
-
- 3.1 np.array()
- 3.2 np.arange()
- 3.3 np.zeros()
- 3.4 np.zeros_like()
- 3.5 np.ones()
- 3.6 np.ones_like()
- 3.7 np.empty()
- 3.8 np.empty_like()
- 3.9 np.linspace()
- 3.10 np.logspace()
- 3.11 np.indices()
- 3.12 np.ランダム
- 3.13 np.fromfunction()
- 3.14 np.fromfile()
- 3.15 np.identity()
- 3.16 np.eye()
- 3.17 np.mgrid()
- 3.18 np.ogrid()
- 4. 索引
- 5. 反復
- 6. 配列演算
- 7. 配列演算
- 8. ブロードキャスト
- 9. 一般的な機能
- 10. API関数
1. NumPy の概要
NumPy は、Python の科学計算用の基本パッケージです。多次元配列オブジェクト、さまざまな派生オブジェクト (マスク配列や行列など)、および数学、ロジック、形状演算などの配列に対する高速演算のためのさまざまな API を提供する Python ライブラリです。 、ソート、選択、入出力、離散フーリエ変換、基本的な線形代数、基本的な統計演算、確率的シミュレーションなど。
NumPy パッケージの中心となるのはndarray
オブジェクトです。同じデータ型の Python のネイティブ n 次元配列をカプセル化します。NumPy の最下層はプリコンパイルに C コードを使用するため、Python のネイティブ配列よりも動作効率が大幅に高くなります。同時に、NumPy にはベクトル化とブロードキャストの特性があるため、コードはより簡潔で合理化されます。
この記事では、NumPy をすぐに使い始めることを目的として、NumPy の基本的な概念と使い方を主に紹介します。
2. 基本 - 配列
ネイティブ Python リストは、同時に異なる型の要素を含めることをサポートしますが、NumPy のメイン オブジェクトは同じ型の多次元配列です。NumPy の次元は、 axis。
NumPy の配列クラスには、ndarray
Python のネイティブ配列よりも多くのプロパティがあります。
-
ndarray.ndim
配列の軸 (次元) の数。ランクとも呼ばれます。
-
ndarray.shape
配列の次元は配列のタプルであり、配列の各次元のサイズを表します。マトリックスが
n
行とm
列の場合は、shape
「はい」です(n, m)
。タプルの長さndim
です。shape
-
ndarray.size
配列内の要素の合計数。
shape
配列内の要素の積に等しい。 -
ndarray.dtype
配列内の要素の型を記述するために使用されるオブジェクト。標準の Python データ型を使用できます。
numpy.int32
NumPy によって提供される、やnumpy.int64
などnumpy.float64
のデータ型を使用することもできます。 -
ndarray.itemsize
要素タイプのバイト長。例えば、
float64
タイプitemsize
は8(=64/8)であり、別のcomplex32
例はitemsize
4(=32/8)である。に等しいndarray.dtype.itemsize
。 -
ndarray.data
要素内の実際の要素を含むバッファ。通常、インデックスによって配列内の要素にアクセスできるため、このプロパティを直接使用する必要はありません。
3. 配列を作成する
配列は NumPy の中核概念であるため、配列を作成することが最初のステップです。配列を作成するには 5 つの一般的なメカニズムがあります。
- 他の Python 構造 (リスト、タプルなど) から変換します。
- numpy ネイティブ配列 (例: 範囲、1、0 など) の作成
- 標準またはカスタム形式でディスクから配列を読み取ります
- 文字列またはバッファを使用して生のバイトから配列を作成する
- 特殊なライブラリ関数 (ランダムなど) を使用する
以下に、配列を作成する一般的に使用される方法をいくつかまとめます (通常の配列の作成だけでなく、さまざまな特殊な配列を作成するために NumPy が提供する API も同様です)。
シリアルナンバー | API | 説明 |
---|---|---|
1 | np.array() | Python リストまたはタプルから配列を作成する |
2 | np.arange() | 数値の配列を作成する |
3 | np.zeros() | すべて0の配列を作成する |
4 | np.zeros_like() | ターゲット配列と同じサイズのすべて 0 の配列を作成します |
5 | np.ones() | すべて 1 の配列を作成する |
6 | np.ones_like() | ターゲット配列と同じサイズのすべて 1 の配列を作成します |
7 | np.empty() | 指定されたサイズの配列を作成しますが、値は初期化されません |
8 | np.empty_like() | 値の初期化を行わずに、ターゲット配列と同じサイズの配列を作成します。 |
9 | np.lispace() | 算術配列を作成する |
10 | np.logspace() | 比例配列を作成する |
11 | np.indices() | 指定された形状番号の配列コレクションを作成します |
12 | np.ランダム.ランダム | ランダムな配列を作成する |
13 | np.fromfunction() | 指定された関数から配列を作成する |
14 | np.fromfile() | 指定されたファイルから配列を作成します |
15 | np.identity() | 行と列が等しい単位行列を作成する |
16 | np.eye() | 2 次元行列を作成します。対角要素はすべて 1 で、行と列は異なっていてもよく、対角オフセットを指定できます。 |
17 | np.mgrid() | 多次元構造の配列を返します。 |
18 | np.ogird() | スパースな多次元構造の配列を返します。 |
3.1 np.array()
1 次元配列を作成します。
>>> a = np.array([1,2,3])
>>> a
array([1, 2, 3])
2D 配列を作成します。
>>> b = np.array([[1,2,3], [4,5,6]])
>>> b
array([[1, 2, 3],
[4, 5, 6]])
配列を作成するときは、配列のタイプを手動で指定します。
# 指定为float32类型
>>> c = np.array([1, 2, 3], dtype=np.float32)
>>> c
array([1., 2., 3.], dtype=float32)
NumPy は Python リストとタプルの両方を受け入れることができるため、
array()
タプルまたはリストを渡しても問題ありません。また、タプルやリストなどのパラメーターを渡す必要がある関数もいくつか含まれていますshape
。
3.2 np.arange()
デフォルトのステップ サイズ 1 で、0 から始まり特定の数値で終わるシーケンスを作成します。
>>> a = np.arange(3)
>>> a
array([0, 1, 2])
ステップ サイズとタイプを指定して、特定の番号で始まり特定の番号で終わる配列を作成します。
>>> a = np.arange(start=1, stop=8, step=2, dtype=np.int32)
>>> a
array([1, 3, 5, 7])
arange() が配列を作成する方法は、左クローズ、右オープン[開始、停止) です。
3.3 np.zeros()
指定された形状のすべて 0 の配列を作成します。
>>> a = np.zeros((3,2))
>>> a
array([[0., 0.],
[0., 0.],
[0., 0.]])
>>> a.dtype
dtype('float64')
関数zeros
のデフォルトはfloat64
type です。作成時に他のタイプを手動で指定できます。
>>> a = np.zeros((3,2), dtype=np.int32)
>>> a
array([[0, 0],
[0, 0],
[0, 0]])
>>> a.dtype
dtype('int32')
3.4 np.zeros_like()
ターゲット配列と同じサイズのすべて 0 の配列を作成します。
>>> a = np.array([[1,2,3], [4,5,6]])
>>> a
array([[1, 2, 3],
[4, 5, 6]])
>>> b = np.zeros_like(a)
>>> b
array([[0, 0, 0],
[0, 0, 0]])
3.5 np.ones()
指定した形状のすべて1の配列を作成する方法はnp.zeros()
使い方と同じなので、ここでは詳しく説明しません。デフォルトのタイプも ですfloat64
。dtype
タイプを指定することもできます。
3.6 np.ones_like()
ターゲット配列と同じサイズのすべて 1 の配列を作成し、np.zeros_like()
同じ方法で使用します。
3.7 np.empty()
指定された形状の配列を作成しますが、配列内の値は初期化されません。Empty は初期化されていないため、より速く作成されます。プレースホルダー配列を必要とするシナリオの作成に使用できます。
>>> a = np.empty((3, 4))
>>> a
array([[6.23042070e-307, 2.04719289e-306, 6.23057010e-307,
1.24611741e-306],
[1.78019082e-306, 6.23058028e-307, 1.06811422e-306,
3.56043054e-307],
[1.37961641e-306, 8.90071135e-308, 1.78021527e-306,
1.66889876e-307]])
3.8 np.empty_like()
宛先配列と同じサイズの配列を作成しますが、初期化はしません。
3.9 np.linspace()
特定の数値で始まり特定の数値で終わる算術配列を作成し、間隔内の要素の数を指定します。
>>> a = np.linspace(2, 9, num=8)
>>> a
array([2., 3., 4., 5., 6., 7., 8., 9.])
関数によって作成される配列の範囲linspace
は、デフォルトの左閉および右閉[start, stop]であり、これには stop が含まれます。Endpoint
パラメータを通じて stop を含めるかどうかを指定できます。
>>> a = np.linspace(2, 9, num=7, endpoint=False)
>>> a
array([2., 3., 4., 5., 6., 7., 8.])
この関数は比較linspace
と似ておりarange
、関数はarange
ステップ サイズを指定しますが、linspace
関数によって指定される合計数、そのステップ サイズは動的に計算され、retstep
パラメータを通じて計算されたステップ サイズを取得できます。
>>> a = np.linspace(2, 9, num=7, endpoint=False, retstep=True)
>>> a
(array([2., 3., 4., 5., 6., 7., 8.]), 1.0)
>>> a = np.linspace(2, 9, num=7, endpoint=False, retstep=True)
# 指定retstep之后可以同时得到数组和步长
>>> a
(array([2., 3., 4., 5., 6., 7., 8.]), 1.0)
# 获取创建出来的数组
>>> a[0]
array([2., 3., 4., 5., 6., 7., 8.])
# 获取数组的步长
>>> a[1]
1.0
3.10 np.logspace()
比例配列を作成します。デフォルトは基数10、1 0 start 10^{start}から始まります。1 0開始、開始、 1 0停止10^{停止}1 0合計は次のとおりです(デフォルトは50num
)。
>>> a = np.logspace(1, 5, num=5)
>>> a
array([1.e+01, 1.e+02, 1.e+03, 1.e+04, 1.e+05])
>>> b = np.logspace(1, 5, num=4, dtype=np.int32)
>>> b
array([ 10, 215, 4641, 100000])
ベースはパラメータで指定できるため、 basestartbase^{start}base
から指定できます。基本_ _スタート、スタート、ベースストップへbase ^ {stop}基本_ _もちろん、ストップエンドをパラメータでendpoint
含めるかどうかを指定することstop
もできます。
>>> a = np.logspace(1, 10, base=2, num=10, dtype=np.int32)
>>> a
array([ 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024])
>>> b = np.logspace(1, 5, base=3, num=5, dtype=np.int32)
>>> b
array([ 3, 9, 27, 81, 243])
3.11 np.indices()
指定された形状のシリアル番号の配列コレクションを作成します。コレクションは各次元のシリアル番号です。抽象的に聞こえますが、例を見ると理解しやすいはずです。
>>> a = np.indices((3,2))
>>> a
array([[[0, 0],
[1, 1],
[2, 2]],
[[0, 1],
[0, 1],
[0, 1]]])
>>> a[0]
array([[0, 0],
[1, 1],
[2, 2]])
>>> a[1]
array([[0, 1],
[0, 1],
[0, 1]])
上記の例では、shape
(3, 2) を指定しました。3x2 行列の座標分布は次のようになると考えてください:
[ a 0 , 0 a 0 , 1 a 1 , 0 a 1 , 1 a 2 , 0 a 2 , 1 ] \begin{bmatrix} a_{0, 0} & a_{0,1} \\ a_{1,0} & a_{1,1} \\ a_{2,0} & a_{2,1} \\ \end{bmatrix}
ある0、0 _ _ある1、0 _ _ある2、0 _ _ある0、1 _ _ある1、1 _ _ある2、1 _ _
高次元の座標行列は、
[ 0 , 0 1 , 1 2 , 2 ] \begin{bmatrix} 0, 0 \\ 1, 1 \\ 2, 2 \\ \end{bmatrix} です。
0 、01 、12 、2
低次元の座標行列は、
[ 0 , 1 0 , 1 0 , 1 ] \begin{bmatrix} 0, 1 \\ 0, 1 \\ 0, 1 \\ \end{bmatrix} です。
0 、10 、10 、1
上記の例の結果と正確に一致します。3D マトリックスの別の例を見てみましょう。
>>> a = np.indices((2,3,2))
>>> a[0]
array([[[0, 0],
[0, 0],
[0, 0]],
[[1, 1],
[1, 1],
[1, 1]]])
>>> a[1]
array([[[0, 0],
[1, 1],
[2, 2]],
[[0, 0],
[1, 1],
[2, 2]]])
>>> a[2]
array([[[0, 1],
[0, 1],
[0, 1]],
[[0, 1],
[0, 1],
[0, 1]]])
同様に、2x3x2 の 3 次元行列は、次の 2 つの 2 次元行列を前後に重ね合わせることで決定できます: [
a 0 , 0 , 0 a 0 , 0 , 1 a 0 , 1 , 0 a 0 , 1 , 1 a 0 , 2 , 0 a 0 , 2 , 1 ] \begin{bmatrix} a_{0,0,0} & a_{0,0,1} \\ a_{0,1,0 } & a_{0,1 ,1} \\ a_{0,2,0} & a_{0,2,1} \\ \end{bmatrix}
ある0、0、0 _ _ _ _ある0、1、0 _ _ _ _ある0、2、0 _ _ _ _ある0、0、1 _ _ _ _ある0、1、1 _ _ _ _ある0、2、1 _ _ _ _
[ a 1 , 0 , 0 a 1 , 0 , 1 a 1 , 1 , 0 a 1 , 1 , 1 a 1 , 2 , 0 a 1 , 2 , 1 ] \begin{bmatrix} a_{1,0,0 } & a_{1,0,1} \\ a_{1,1,0} & a_{1,1,1} \\ a_{1,2,0} & a_{1,2,1} \\ \end{b行列} ある1、0、0 _ _ _ _ある1、1、0 _ _ _ _ある1、2、0 _ _ _ _ある1、0、1 _ _ _ _ある1、1、1 _ _ _ _ある1、2、1 _ _ _ _
最高次元の座標行列は、
[ 0 , 0 0 , 0 0 , 0 ] \begin{bmatrix} 0, 0 \\ 0, 0 \\ 0, 0 \\ \end{bmatrix} です。
0 、00 、00 、0
[ 1 , 1 1 , 1 1 , 1 ] \begin{bmatrix} 1, 1 \\ 1, 1 \\ 1, 1 \\ \end{bmatrix} 1 、11 、11 、1
残りの 2 次元の座標行列は同じなので、詳細は説明しません。関数によって生成された順序配列indices
は、次のように配列の部分配列を計算するために使用できます。
>>> a = np.arange(12).reshape(3,4)
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> b = np.indices((2,3))
>>> b
array([[[0, 0, 0],
[1, 1, 1]],
[[0, 1, 2],
[0, 1, 2]]])
>>> a_sub = a[b[0], b[1]]
>>> a_sub
array([[0, 1, 2],
[4, 5, 6]])
# 在数组切片层面,效果同
>>> a[:2, :3]
array([[0, 1, 2],
[4, 5, 6]])
この関数indices
によって作成される配列は、デフォルトでは非スパースですが、sparse
パラメーターによってスパースとして指定できます。
>>> a = np.indices((3,2), sparse=True)
>>> a
(array([[0],
[1],
[2]]), array([[0, 1]]))
3.12 np.ランダム
np.random.random()
指定されたランダム配列を生成しますshape
。デフォルトの値の範囲は[0, 1)です。
>>> a = np.random.random((2,3))
>>> a
array([[0.48152382, 0.58393539, 0.61701583],
[0.05104326, 0.23513154, 0.21062412]])
np.random.randint()
指定されたランダムな配列を生成しshape
、デフォルトの値の範囲がパラメーターとして渡されます。
# [3,9)之间的随机整数,数组尺寸3X4
>>> a = np.random.randint(3, 9, (3,4))
>>> a
array([[6, 3, 3, 4],
[5, 7, 7, 3],
[7, 6, 3, 7]])
この関数の機能np.random.shuffle()
は、配列をランダムにシャッフルすることです。np.random
パッケージには、ランダムな配列を生成するための API が他にも多数あります。ここでは、最も基本的な 2 つの関数のみを紹介します。
3.13 np.fromfunction()
指定したサイズの配列を作成し、ラムダ式を渡して値を初期化します。ラムダ式のパラメータは、値に対応する座標です。
>>> a = np.fromfunction(lambda i,j: i, (2,2))
>>> a
array([[0., 0.],
[1., 1.]])
# 将坐标i+j作为数组元素的初始化值
>>> b = np.fromfunction(lambda i,j: i + j, (3,3), dtype=np.int32)
>>> b
array([[0, 1, 2],
[1, 2, 3],
[2, 3, 4]])
上の例はラムダであるか、関数に直接渡されます。
>>> def f(x,y):
... return 10*x+y
...
>>> a = np.fromfunction(f, (2,2), dtype=np.int32)
>>> a
array([[ 0, 1],
[10, 11]])
3.14 np.fromfile()
ファイルからデータを読み取り、配列を生成します。
>>> import tempfile
>>> fname = tempfile.mkstemp()[1]
>>> fname
'C:\\Users\\doudou\\AppData\\Local\\Temp\\tmpmyq7otph'
>>> a = np.arange(12)
>>> a
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
>>> a.tofile(fname)
>>> b = np.fromfile(fname, dtype=np.int32)
>>> b
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
tofile
関数とfromfile
関数は、プラットフォームに依存しないバイナリ メソッドを使用してデータを保存および読み取ります。また、第 2 に、このメソッドは配列のバイト順序とデータ型を保存できないことに注意してください。たとえば、2 次元データを保存する場合、fromfile
関数によって読み取られる元のデータは 1 次元であるため、dtype
データを正しく読み取るためには次のように指定する必要があります。
>>> a = np.arange(12).reshape(3,4)
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> a.tofile(fname)
# 这种方式不存储数组结构信息,所以读取出来变成了一维的
>>> b = np.fromfile(fname, dtype=np.int32)
>>> b
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
# 这种方式不存储数据类型,所以如果不指定dtype,是无法正确读出数据的
>>> c = np.fromfile(fname)
>>> c
array([2.12199579e-314, 6.36598737e-314, 1.06099790e-313, 1.48539705e-313,
1.90979621e-313, 2.33419537e-313])
sum メソッドtofile
の欠点をまとめると、公式の提案は、データの保存と読み取りに sum メソッドを使用することです。fromfile
save
load
>>> fname = tempfile.mkstemp()[1]
>>> fname
'C:\\Users\\doudou\\AppData\\Local\\Temp\\tmpynt0tqt3'
>>> a = np.arange(12).reshape(3,4)
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> np.save(fname, a)
>>> b = np.load(fname + '.npy')
>>> b
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
save
sumメソッドload
はデータの構造とデータ型を正確に復元でき、非常に便利であることがわかります。
3.15 np.identity()
N行とN列からなる単位行列を作成する
>>> a = np.identity(4)
>>> a
array([[1., 0., 0., 0.],
[0., 1., 0., 0.],
[0., 0., 1., 0.],
[0., 0., 0., 1.]])
>>> b = np.identity(2)
>>> b
array([[1., 0.],
[0., 1.]])
3.16 np.eye()
指定された行と列を含む 2 次元行列を作成します。対角要素はすべて 1 です。列数を指定しない場合、デフォルトの列数と行数は等しくなります。
>>> a = np.eye(4)
>>> a
array([[1., 0., 0., 0.],
[0., 1., 0., 0.],
[0., 0., 1., 0.],
[0., 0., 0., 1.]])
>>> b = np.eye(4, 5)
>>> b
array([[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.]])
パラメータを設定するとk
、すべての 1 の対角線のオフセットを指定できます。k
正の場合は上向きに安くなり、負の場合は下向きに相殺されます。
>>> a = np.eye(4, k=1)
>>> a
array([[0., 1., 0., 0.],
[0., 0., 1., 0.],
[0., 0., 0., 1.],
[0., 0., 0., 0.]])
>>> b = np.eye(4, k=2)
>>> b
array([[0., 0., 1., 0.],
[0., 0., 0., 1.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])
>>> c = np.eye(4, k=-1)
>>> c
array([[0., 0., 0., 0.],
[1., 0., 0., 0.],
[0., 1., 0., 0.],
[0., 0., 1., 0.]])
3.17 np.mgrid()
多次元構造の配列を返し、各次元の開始値と終了値、ステップ サイズを指定できます。
np.mgrid[第1维, 第2维, 第3维, ...]
n 次元の記述形式は次のとおりです。
a:b:c
c はステップ サイズを表し、間隔を表す実数です。長さは [a, b)、左が開き、右が閉じます。
または:
a:b:cj
cj はステップ サイズを表し、ポイントの数を表す複素数です。長さは [a,b]、左が閉じた状態、右が閉じた状態です。
>>> x, y = np.mgrid[1:3:1, 4:5:2j]
>>> x
array([[1., 1.],
[2., 2.]])
>>> y
array([[4., 5.],
[4., 5.]])
関数
np.mgrid()
と関数はnp.indices()
返される結果は似ていますが、np.indices()
返される配列内の値は連続座標であり、np.mgrid()
の値はパラメータで指定された区間内の値になります。
3.18 np.ogrid()
スパースな多次元構造の配列を返します。呼び出しメソッドはnp.mgrid()
パラメーターおよび関数と一貫しています。
>>> x, y = np.ogrid[1:3:1, 4:5:2j]
>>> x
array([[1.],
[2.]])
>>> y
array([[4., 5.]])
4. 索引
配列のインデックス付けとは、角括弧を使用して配列の値[]
に。
4.1 1 次元配列の単一要素のインデックス付け
>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a[2]
2
>>> a[-2]
8
4.2 多次元配列の単一要素のインデックス付け
>>> a = np.arange(10).reshape(2, 5)
>>> a
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
>>> a[1, 3]
8
>>> a[1, -1]
9
>>> a[1][-1]
9
標準の Python リストとタプルの場合、
[x, y]
この。[x][y]
サポートされている方法のみがサポートされており、NumPy にも適用できます。
4.3 1 次元配列のスライスとストライドのインデックス付け
1 次元配列の場合、NumPy のスライスとストライドはリストやタプルと同じ方法でインデックスが付けられます。
>>> a = np.arange(10)
>>> a[2:5]
array([2, 3, 4])
>>> a[:-7]
array([0, 1, 2])
>>> a[1:7:2]
array([1, 3, 5])
4.4 多次元配列のスライスとストライドのインデックス付け
多次元配列の場合、NumPy はスライスとストライドのインデックス付けをサポートしますが、リストとタプルはサポートしません。
>>> a = np.arange(35).reshape(5,7)
>>> a
array([[ 0, 1, 2, 3, 4, 5, 6],
[ 7, 8, 9, 10, 11, 12, 13],
[14, 15, 16, 17, 18, 19, 20],
[21, 22, 23, 24, 25, 26, 27],
[28, 29, 30, 31, 32, 33, 34]])
>>> a[1:5:2,::3]
array([[ 7, 10, 13],
[21, 24, 27]])
4.5 配列のインデックス付け
NumPy は、配列またはリスト (タプルではない) を使用して、この配列内の複数の要素に同時にインデックスを付ける方法をサポートしています。
インデックス付き配列は整数型である必要があり、負の数値も使用できます。
>>> a = np.arange(10)
>>> a[np.array([1, 1, 3, 5, -2])]
array([1, 1, 3, 5, 8])
>>> a[[1, 1, 3, 5, -2]]
array([1, 1, 3, 5, 8])
多次元のインデックス付き配列を使用することもできます(注: 多次元配列のインデックス付けではなく、多次元のインデックス付き配列 - つまり、それ自体が多次元であるインデックス付き配列)。
>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a[np.array([[1, 1], [7, -2]])]
array([[1, 1],
[7, 8]])
上記の例では、2 次元インデックス配列を使用して 1 次元配列にインデックスを付け、2 次元配列を取得しました。つまり、インデックス付き配列を使用すると、インデックス付き配列と同じ形状の配列が返されます。
4.6 多次元配列のインデックス付け
インデックス配列を使用して多次元配列にインデックスを付けます。
>>> a = np.arange(35).reshape(5, 7)
>>> a
array([[ 0, 1, 2, 3, 4, 5, 6],
[ 7, 8, 9, 10, 11, 12, 13],
[14, 15, 16, 17, 18, 19, 20],
[21, 22, 23, 24, 25, 26, 27],
[28, 29, 30, 31, 32, 33, 34]])
>>> a[[2, 4, 4], [3, 3, 4]]
array([17, 31, 32])
上の例では、2 つのインデックス配列を使用して 2 次元配列にインデックスを付けました:[2, 4, 4]
と[3, 3, 4]
このように、インデックスを付けたい要素の位置は[2,3], [4,3], [4,4]
これら 3 つであることを意味するため、結果は次のように[17, 31, 32]
なります。
ブロードキャスト メカニズムを利用してインデックスを作成できます。
>>> a[[2, 4, 4], 5]
array([19, 33, 33])
このようにして、インデックスを付けたい要素の位置は となり[2,5], [4,5], [4,5]
、結果は になります[19, 33, 33]
。
1 次元インデックス配列を使用して 2 次元配列にインデックスを付けると、選択された行の新しい配列が取得されます。
>>> a = np.arange(10).reshape(2, 5)
>>> a
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
>>> a[[0, 0, 1]]
array([[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
この方法は、多次元インデックス配列が配列の次元より小さい場合にも適用できます。
4.7 ブール値のインデックス付き配列
ブール インデックス配列の原理は、True
出力することFalse
ではなく、出力することです。
>>> a = np.arange(12).reshape(3,4)
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> b = a > 5
>>> b
array([[False, False, False, False],
[False, False, True, True],
[ True, True, True, True]])
>>> a[b]
array([ 6, 7, 8, 9, 10, 11])
ブール型インデックス付き配列の次元が配列よりも少ない場合、より高い次元に従ってインデックスが付けられます。
>>> a = np.arange(35).reshape(5, 7)
>>> a
array([[ 0, 1, 2, 3, 4, 5, 6],
[ 7, 8, 9, 10, 11, 12, 13],
[14, 15, 16, 17, 18, 19, 20],
[21, 22, 23, 24, 25, 26, 27],
[28, 29, 30, 31, 32, 33, 34]])
>>> a[[True, False, True, False, False]]
array([[ 0, 1, 2, 3, 4, 5, 6],
[14, 15, 16, 17, 18, 19, 20]])
上の例ではブールインデックス配列は1次元でしたが、2次元配列にインデックスを付けると1行目と3行目からなる2次元配列が得られます。
3 次元配列の例をもう一度見て、2 次元のブール インデックス配列を通じて 3 次元配列にインデックスを付けます。
>>> a = np.arange(30).reshape(2, 3, 5)
>>> a
array([[[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]],
[[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24],
[25, 26, 27, 28, 29]]])
>>> b = np.array([[True, True, False], [False, True, True]])
>>> a[b]
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[20, 21, 22, 23, 24],
[25, 26, 27, 28, 29]])
4.8 インデックス付き配列とスライスの結合
スライスはインデックス付き配列で使用できます。
>>> a = np.arange(35).reshape(5, 7)
>>> a
array([[ 0, 1, 2, 3, 4, 5, 6],
[ 7, 8, 9, 10, 11, 12, 13],
[14, 15, 16, 17, 18, 19, 20],
[21, 22, 23, 24, 25, 26, 27],
[28, 29, 30, 31, 32, 33, 34]])
>>> a[np.array([0, 2, 4]), 1:3]
array([[ 1, 2],
[15, 16],
[29, 30]])
4.8np.newaxis
と...
np.newaxis
: 新しい次元を追加するために使用できます。この場合、新しい要素はありませんが、次元は増加します。
>>> a=np.arange(5)
>>> a
array([0, 1, 2, 3, 4])
>>> a.shape
(5,)
>>> b = a[:,np.newaxis]
>>> b
array([[0],
[1],
[2],
[3],
[4]])
>>> b.shape
(5, 1)
>>> c = a[np.newaxis,:]
>>> c.shape
(1, 5)
>>> c
array([[0, 1, 2, 3, 4]])
...
: 完全なインデックス付き配列を生成するために必要なコロンを示します。
- x[1,2,…] は x[1,2,:,:,:] と同等です。
- x[…,3] は x[:,:,:,:,3] と同等です
- x[4,...,5,:] は x[4,:,:,5,:] と同等です。
>>> a = np.arange(15).reshape(5, 3)
>>> a
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11],
[12, 13, 14]])
>>> a[1,...]
array([3, 4, 5])
>>> a[1]
array([3, 4, 5])
>>> a[...,2]
array([ 2, 5, 8, 11, 14])
4.9 インデックス作成後の代入
ブロードキャスト機能を利用したり、同じ形状の値をインデックス付き配列に割り当てることができます。
>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a[2:7] = 1
>>> a
array([0, 1, 1, 1, 1, 1, 1, 7, 8, 9])
>>> a[2:7]=np.arange(5)
>>> a
array([0, 1, 0, 1, 2, 3, 4, 7, 8, 9])
>>> a[2:7] += 10
>>> a
array([ 0, 1, 10, 11, 12, 13, 14, 7, 8, 9])
5. 反復
次の方法で配列を反復処理できます。デフォルトでは、最も高い次元から開始します。
>>> a = np.arange(6).reshape(2, 3)
>>> for x in a:
... print(x)
...
[0 1 2]
[3 4 5]
また、 array のプロパティを使用することもできますflat
。これにより、配列の次元が削減されてタイル化され、すべての要素を簡単に走査できるようになります。
>>> for x in a.flat:
... print(x)
...
0
1
2
3
4
5
6. 配列演算
6.1 サイズの変更
次のようにして、reshape
対応するサイズの配列を取得できます。
>>> a = np.arange(6)
>>> a
array([0, 1, 2, 3, 4, 5])
>>> a.reshape(2,3)
array([[0, 1, 2],
[3, 4, 5]])
>>> a
array([0, 1, 2, 3, 4, 5])
resize
配列の実際のサイズを変更することもできます。
>>> a.resize(2,3)
>>> a
array([[0, 1, 2],
[3, 4, 5]])
reshape
対応するサイズの新しい配列のみが返され、元の配列のサイズは変更されず、代わりにresize
配列自体のサイズが変更されることに注意してください。
.shape
サイズを変更するために直接割り当てを行うことができます。
>>> a = np.arange(6)
>>> a.shape = (3,2)
>>> a
array([[0, 1],
[2, 3],
[4, 5]])
reshape()
と の場合.shape
、サイズを -1 として指定できます。これにより、サイズが自動的に計算されます (注:resize()
サポートされていません)。
>>> a = np.arange(6)
>>> a.shape = 3, -1
>>> a
array([[0, 1],
[2, 3],
[4, 5]])
>>> a.reshape(2, -1)
array([[0, 1, 2],
[3, 4, 5]])
>>> a.reshape(-1, 2)
array([[0, 1],
[2, 3],
[4, 5]])
6.2 タイリング
多次元配列は、関数flatten()
と1 次元配列にフラット化できますravel()
が、この 2 つの違いは、flatten()
変更された配列は元の配列を変更せず、ravel()
変更された配列は元の配列に影響を与えることです。
>>> a = np.arange(6).reshape(2, 3)
>>> a
array([[0, 1, 2],
[3, 4, 5]])
>>> b = a.flatten()
>>> b
array([0, 1, 2, 3, 4, 5])
# 修改这个平铺数组不会影响原数组
>>> b[0] = 100
>>> a
array([[0, 1, 2],
[3, 4, 5]])
>>> c = a.ravel()
>>> c
array([0, 1, 2, 3, 4, 5])
# 修改这个平铺数组会影响原数组
>>> c[0] = 100
>>> a
array([[100, 1, 2],
[ 3, 4, 5]])
6.3 並べ替え
sort()
配列を並べ替えることで、並べ替える次元を指定できます。デフォルトでは、最も低い次元で並べ替えられます。
>>> a = np.array([[8, 0, 1], [5, 3, 4], [2, 6, 7]])
>>> a
array([[8, 0, 1],
[5, 3, 4],
[2, 6, 7]])
>>> a.sort()
>>> a
array([[0, 1, 8],
[3, 4, 5],
[2, 6, 7]])
>>> a.sort(axis=0)
>>> a
array([[0, 1, 5],
[2, 4, 7],
[3, 6, 8]])
デフォルトでは、関数はsort()
昇順で並べ替えられます。降順が必要な場合は、負の数を使用できます-np.sort(-a)
。
6.4 トランスポーズ
配列の転置は、プロパティ.T
または実行できます。transponse()
>>> a = np.arange(6).reshape(2, 3)
>>> a
array([[0, 1, 2],
[3, 4, 5]])
>>> a.T
array([[0, 3],
[1, 4],
[2, 5]])
>>> a.transpose()
array([[0, 3],
[1, 4],
[2, 5]])
上記の transpose メソッドは配列自体を変更せず、新しい配列を返すだけです。
6.5 統合
np.vstack()
配列はおよび とnp.hstack()
マージできます。
>>> a = np.arange(4).reshape(2, 2)
>>> a
array([[0, 1],
[2, 3]])
>>> b = np.arange(start=4, stop=8).reshape(2, 2)
>>> b
array([[4, 5],
[6, 7]])
>>> np.vstack((a,b))
array([[0, 1],
[2, 3],
[4, 5],
[6, 7]])
>>> np.hstack((a,b))
array([[0, 1, 4, 5],
[2, 3, 6, 7]])
上記は固定の垂直方向と水平方向のマージであり、軸をnp.concatenate
指定して(axis
サイズが小さいほど、次元が高くなります)。
>>> np.concatenate((a,b), axis=0)
array([[0, 1],
[2, 3],
[4, 5],
[6, 7]])
>>> np.concatenate((a,b), axis=1)
array([[0, 1, 4, 5],
[2, 3, 6, 7]])
6.6 分割
配列は、水平軸に沿って によって分割np.hsplit
できます。均等分割または不均等分割が可能です。
>>> a = np.arange(9).reshape(3, 3)
>>> a
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
# 等量分割成3列
>>> np.hsplit(a, 3)
[array([[0],
[3],
[6]]), array([[1],
[4],
[7]]), array([[2],
[5],
[8]])]
# 不等量分割,1份为1列,1份为2列
>>> np.hsplit(a, (1,2))
[array([[0],
[3],
[6]]), array([[1],
[4],
[7]]), array([[2],
[5],
[8]])]
np.vsplit
分割は、 で垂直軸に沿って行うことも、 で軸np.array_split
を指定すること。
6.7 コピー
Numpy の配列は、コピーなし、浅いコピー、深いコピーに分けられます。直接割り当てた場合、配列オブジェクトとそのデータはコピーされません。
>>> a = np.arange(12)
>>> b = a
>>> id(a)
2258092791568
>>> id(b)
2258092791568
>>> b is a
True
view()
ビューは、関数 、つまり浅いコピーを通じて作成できます。異なる配列オブジェクトが同じデータを共有しており、一方を変更すると他方にも影響を与えるようです。
>>> a = np.arange(12)
>>>
>>> b = a.view()
>>> id(a)
2257817754800
>>> id(b)
2258092792144
>>> a[0] = 130
>>> b
array([130, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
配列とデータの完全なコピーは、関数を通じて生成copy()
できます。つまり、ディープ コピーです。この 2 つは相互に影響しません。
>>> a = np.arange(12)
>>> b = a.copy()
>>> id(a)
2258092791664
>>> id(b)
2258092791568
>>> a[0] = 130
>>> b
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
7. 配列演算
NumPyは計算効率が高く、ベクトル化の特徴があり非常にわかりやすいです。基本的な数学演算とは、次のタイプを含む数学記号に基づく演算を指します (演算は対応する要素に従って実行されます)。
シリアルナンバー | 手術 | 説明 |
---|---|---|
1 | + 、、、、、、- _ * _ / _ // _% |
基本的な数学演算 |
2 | ** |
指数演算 |
3 | += 、、、、、、、-= _ *= _ /= _ //= _ %= _**= |
複合代入演算 |
4 | > 、、、、、>= _ < _ <= _== |
比較演算 |
7.1 +、-、*、/、//、%
NumPy 配列は、数値による直接操作をサポートしています。
>>> a = np.array([1,2,3])
>>> a+10 # 加
array([11, 12, 13])
>>> a-10 # 减
array([-9, -8, -7])
>>> a*10 # 乘
array([10, 20, 30])
>>> a/10 # 除
array([0.1, 0.2, 0.3])
>>> a // 10 # 取整除
array([0, 0, 0], dtype=int32)
>>> a%10 # 取余
array([1, 2, 3], dtype=int32)
配列と配列の間の操作もサポートされています。
>>> a = np.array([1,2,3])
>>> b = np.array([4,5,6])
>>> a+b
array([5, 7, 9])
>>> a-b
array([-3, -3, -3])
>>> a*b
array([ 4, 10, 18])
>>> a/b
array([0.25, 0.4 , 0.5 ])
>>> a//b
array([0, 0, 0])
>>> a%b
array([1, 2, 3])
配列間の演算は同じ位置の要素を 1 つずつ演算するため、演算に参加する配列は同じ値を持つ必要があり、そうでない場合はshape
演算を実行できません。
7.2 **
渡された**N
フォームは N 乗までの演算を実行でき、数値または配列間のメソッドをサポートします。
>>> a = np.array([1,2,3])
>>> b = np.array([4,5,6])
>>> a**2 # 数组a的2次方
array([1, 4, 9])
>>> a**b # 数组a的b次方
array([1, 32, 729])
7.3 +=、-=、*=、/=、//=、%=、**=
NumPy の複合代入演算はほとんどのプログラミング言語と似ていますが、前の 2 つのセクションの基本的な数学演算および指数演算との違いは、基本的な数学演算および指数演算は新しい配列を生成し、配列の値を変更しないことです。配列要素; 一方、複合代入演算は配列要素自体に作用します。
>>> import numpy as np
>>> a = np.array([1,2,3])
>>> a += 1
>>> a
array([2, 3, 4])
>>> a -= 1
>>> a
array([1, 2, 3])
>>> a *= 2
>>> a
array([2, 4, 6])
>>> a **= 2
>>> a
array([4, 16, 36])
上の例では、配列自体が実際に変更されていることがわかりますa
。
なお、例では使用していませんが/=
、特殊なので別途説明する必要があり、理論的には/=
配列を定義しa
た後、a /= 2
直接行うべきなのですが、このように書くとエラーになってしまいます。報告される:
>>> a /= 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
numpy.core._exceptions._UFuncOutputCastingError: Cannot cast ufunc 'divide' output from dtype('float64') to dtype('int32') with casting rule 'same_kind'
つまり/=
、関数配列は浮動小数点型である必要があり、それを整数として定義したため、2 つの方法があります。つまり、最初に配列を浮動小数点型として定義するか、または次を使用します。整数の除算を処理するための記号//=
:
>>> a = np.array([1, 2, 3], dtype=np.float32)
>>> a /= 2
>>> a
array([0.5, 1. , 1.5], dtype=float32)
>>> b = np.array([1, 2, 3])
>>> b //= 2
>>> b
array([0, 1, 1])
7.4 >、>=、<、<=、==
演算を比較することで、ブール値の配列を取得できます。
>>> a = np.array([1, 2, 3])
>>> a > 1
array([False, True, True])
>>> a >= 1
array([ True, True, True])
>>> a < 1
array([False, False, False])
>>> a <= 1
array([ True, False, False])
>>> a == 1
array([ True, False, False])
8. ブロードキャスト
NumPy でのブロードキャストは非常に興味深い概念であり、その主な目的は、さまざまな形状や次元の配列を操作し、独自のルール セットを持たせることです。
ブロードキャスト互換性の条件は、2 つの配列が最後の次元から推定されることです。
- 同じサイズであるか、
- そのうちの 1 つは 1
次の 2 つの例はブロードキャスト互換性を満たしているため、それらはブロードキャスト互換性があります。
A (3d array): 15 x 3 x 5
B (2d array): 3 x 5
Result (3d array): 15 x 3 x 5
A (4d array): 8 x 1 x 6 x 1
B (3d array): 7 x 1 x 5
Result (4d array): 8 x 7 x 6 x 5
上記の条件が満たされない場合、ブロードキャストには互換性がなく、操作中にValueError: operands could not be broadcast together
例外。
A (1d array): 3
B (1d array): 4 # trailing dimensions do not match
A (2d array): 2 x 1
B (3d array): 8 x 4 x 3 # second from last dimensions mismatched
ブロードキャストを理解するには、主に配列を生成するためのサイズ規則を理解する必要があります。これを理解すると、具体的な操作がより明確になります。
# 一维数组的广播
>>> a = np.arange(4)
>>> a + 10
array([10, 11, 12, 13])
# 二维数组的广播
>>> b = a.reshape(4, 1)
>>> b
array([[0],
[1],
[2],
[3]])
>>> c = np.ones(5)
>>> b + c
array([[1., 1., 1., 1., 1.],
[2., 2., 2., 2., 2.],
[3., 3., 3., 3., 3.],
[4., 4., 4., 4., 4.]])
前に紹介したようにnp.newaxis
、これを使用して配列の次元を増やし、ブロードキャスト計算を実行できます。
>>> a = np.array([0.0, 10.0, 20.0, 30.0])
>>> b = np.array([1.0, 2.0, 3.0])
>>> a[:, np.newaxis] + b
array([[ 1., 2., 3.],
[ 11., 12., 13.],
[ 21., 22., 23.],
[ 31., 32., 33.]])
9. 一般的な機能
NumPy は、数学記号を直接使用することに加えて、「一般関数」 ( ufunc
) と呼ばれるいくつかの数学関数も提供します。これらの一般的な関数は配列に対して要素ごとに動作し、新しい配列を生成します。
9.1 単項関数
関数 | 説明 |
---|---|
np.abs | 絶対値 |
np.sqrt | 平方根 (負の平方根の結果は NAN) |
np.square | 四角 |
np.exp | 指数を計算します (e^x) |
np.log、np.log10、np.log2、np.log1p | 底が e、底が 10、底が 2、底が (1+x) の対数を求めます。 |
np.sign | 配列内の値にラベルを付けます。0 より大きい値は 1 になり、0 に等しい値は 0 になり、0 未満の値は -1 になります。 |
np.ceil | 配列内の各要素の上限整数を取得します。 |
NPフロア | 配列内の各要素の下限整数を取得します。 |
np.クロップ | 配列に上限と下限を設定する |
np.rint、np.round | 四捨五入した値を返します |
np.modf | 整数と小数を分割して 2 つの配列を形成します |
NP.イスナン | ナンかどうかの判断 |
np.isinf | inf かどうかを判断する |
np.cos、np.cosh、np.sinh、np.tan、np.tanh | 三角関数 |
np.arccos、np.arcsin、np.arctan | 逆三角関数 |
np.nonzero | ゼロ以外の要素とその座標を検索する |
np.cumsum | 蓄積する |
np.diff | 疲れた |
9.2 二項関数
関数 | 説明 |
---|---|
np.add | 添加 |
np.subtract | 引き算 |
np.ネガティブ | 複雑な算術 |
np.乗算 | 乗算 |
np.除算 | 除算演算 |
np.floor_divide | 丸め演算、// と同等 |
np.mod | 剰余演算 |
np.dot | 内積(ドット積) |
より大きい、より大きい、より小さい、より小さい、等しい、等しくない | >,>=,<,<=,=,!= の関数式 |
論理積 | および演算子関数式 |
論理和 | または演算子関数式 |
9.3 集計関数
関数 | 説明 |
---|---|
np.sum | 要素の合計を計算する |
np.prod | 要素の積を計算する |
np.mean | 要素の平均を計算します |
np.std | 要素ごとの標準偏差を計算する |
np.var | 要素ごとの分散を計算する |
np.min | 要素の最小値を計算します |
np.max | 要素の最大値を計算します |
np.argmin | 最小値のインデックスを見つける |
np.argmax | 最大値のインデックスを見つける |
np.中央値 | 要素の中央値を計算します |
np.平均 | 要素の加重平均を計算します |
9.4 ブール配列関数
関数 | 説明 |
---|---|
np.all() | すべての要素または指定された軸の要素がすべて True であるかどうかを判断します |
np.any() | 判断所有元素或者指定轴的元素中,是否有True |
10. API函数
NumPy中的API的类型很丰富,而且非常多,这一部分可参照官方API文档。