[翻訳]NumPy公式チュートリアル "NumPy: the absolute basics for beginners"

訳者による紹介

本記事は、NumPy v.1.19 公式Documentation内の "NumPy: the absolute basics for beginners" の翻訳です。このドキュメントが開発版から本リリース扱いに変わったことをきっかけに、公開しました。


近年Pythonの人気は高止まりしています。その理由の一つは、AIブームとPythonの機械学習ライブラリの充実でしょう。Pythonが機械学習など科学技術計算分野でのライブラリが豊富であることが、さらなるライブラリの拡充や、初心者に限らない支持を引き起こしているようです。

NumPyはこれら科学技術計算ライブラリの基盤となるシステムです。NumPyが採用される理由に、Pythonの速度の問題があります。Pythonは言語の特性上、一部の操作は非常に低速であることで知られています。そのため多くのライブラリは、Pythonの速度が処理のボトルネックになることを回避するために、C言語で実装されたNumPyなどを使うことで大量のデータ処理にも耐えうる速度を実現しているのです。



NumPyはとても便利かつ高速に作動する魅力がありますが、Python自身と比べるとすこしとっつきにくいかもしれません。本記事では、NumPyの基礎を、画像をまじえつつ明快に説明していています。解説の範囲は["Quickstart tutorial"](https://numpy.org/doc/stable/user/quickstart.html#quickstart-tutorial)の半分以上をカバーしているので、あの無味乾燥なチュートリアルを読まずとも、ある程度のことができるようになるはずです。

また、[【初心者向け】図解でわかるNumPyとデータ表現](https://note.com/sayajewels/n/n95edaedb0fc5)にも目を通すと参考になるかもしれません。執筆者は本記事の画像の作成者です。
誤訳等の指摘をいただけると大変助かります。

**以下翻訳**






NumPy完全初心者へのガイドへようこそ！もしコメントや提案があれば、遠慮なく連絡してください！

# Welcome to NumPy!

NumPy (Numerical Python)は科学と工学(engineering)のほとんどすべての領域で用いられているオープンソースPythonライブラリです。NumPyは数値データを扱うための世界標準であり、ScientificPythonとPydata系の中核です[Pydata ecosystems: Numpyの開発元Pydataの製品群]。NumPyユーザーには始めたてのプログラマーから、最先端の科学・工学研究と開発を行うベテラン研究者までいます。NumPy APIはPandas, SciPy, Matplotlib, scikit-learn, scikit-imageや他のほとんどのデータサイエンス用や科学用Pythonパッケージに広く用いられています。
NumPyライブラリは多次元の配列と行列データ構造を持ちます（これに関しては後の節でより詳しく説明します）。NumPyは、同一のデータ型で構成されたn次元の配列オブジェクトであるndarrayを、配列を効率的に処理するためのメソッドと併せて提供します。Numpyは配列についての多様な数学的操作を行うために用いることができます。NumPyは配列と行列の効率的な計算を保証する力強いデータ構造をPythonに付け足し、これら配列と行列で働く高度の数学的機能を持った巨大なライブラリを提供します。
Learn more about [NumPy here!](https://numpy.org/doc/stable/user/whatisnumpy.html#whatisnumpy) 



# NumPyをインストールする

NumPyをインストールするには、科学用Pythonディストリビューションを利用することを強く勧めます。もし
お使いのOSにNumPyをインストールするための完全な手引きが必要なら、ここで[すべての詳細を見つけることができます](https://www.scipy.org/install.html)。

もしすでにPythonを使っているなら、以下のコードでNumPyをインストールできます。

```shell
conda install numpy
```

あるいは

```shell
pip install numpy
```

もしまだPythonを持っていないのであれば、Anacondaの使用を検討するのがよいでしょう。[Anaconda](https://www.anaconda.com/)はPythonを一番簡単に始められる方法です。このディストリビューションを使う利点は、NumPyやデータ解析に使われる主要なパッケージ、pandas、Scikit-Learnなどを個々にインストールすることをそこまで心配する必要がないことです。

You can find all of the installation details in the [Installation](https://www.scipy.org/install.html) section at [SciPy](https://www.scipy.org/).



# NumPyをインポートする方法

パッケージやライブラリを使いたい時はいつでも、最初に使いたいものをアクセス可能にする必要があります。
NumPyとそれに備わるすべての機能を使いはじめるには、NumPyをインポートしなければなりせん。これは次のインポート文[statement]によって簡単にできます。

```shell
import numpy as np
```

(我々はNumPyをnpと省略します。それは時間を節約するためであり、またコードを標準化しておくことで、そのコードを使って働く誰もが簡単に理解でき実行できるようにするためです。)



# コード例の読み方

もしコードがたくさんのチュートリアルを読むのにまだ慣れていないなら、どのように次のようなコードブロックを理解すればよいかわからないかもしれません。

```
>>> a = np.arange(6)
>>> a2 = a[np.newaxis, :]
>>> a2.shape
(1, 6)
```

もしこのやり方をよく知らなくても、この表記法はとても理解しやすいです。もし>>>があれば、**入力**、つまりあなたが入力するだろうコードを指しています。コードの前に>>>がないものはすべて**出力**、つまりコードを実行した結果です。これはPythonをコマンドラインで実行するときのスタイルですが、IPythonを使うときは、異なるスタイルが表示されるかもしれません。



# Python list と NumPy arrayの違いは何ですか?

NumPyは、配列を作り数値データを操作するための高速かつ効率的な方法を非常に多く備えています。Pyhonリストは一つのリストに異なったデータ型を持つことが可能ですが、NumPy配列で配列上のすべての要素は同種でなければなりません。もし配列に他のデータ型が混ざっていれば、配列上で働くはずの数学的操作はひどく非効率になるでしょう。



#### NumPyはなぜ使われているのですか?

NumPy配列はPythonリストよりも高速で簡潔です。[Pythonの]配列はメモリーをあまり使わず、使用するのに便利です。それと比べてもNumPyがデータをためるためにメモリーを使う量ははるかに少なく、データタイプを識別するメカニズムも備えています。このことはコードをさらに最適化することを可能にします。



# 配列とはなんですか?

配列とはNumPyライブラリの主要なデータ構造のひとつです。配列は値たちのグリッドであり配列は生のデータについての情報、要素をどのように配置するかについての情報、要素をどのように理解(interpret)するかについての情報を持ちます。NumPyが持つ諸要素からなるgridは、[様々な方法](https://numpy.org/doc/stable/user/quickstart.html#quickstart-indexing-slicing-and-iterating)でインデックスすることができます。要素はすべて同種であり、配列の`dtype`として表されます。

配列は正の整数のタプル、ブール値(booleans)、別の配列や整数によってインデックス可能です。配列の`rank`は次元の数です。配列の`shape`は各次元に沿った配列のサイズを表す整数のタプルです。
NumPy配列を初期化する一つの方法は、Pythonリストから初期化することです。二次元以上のデータにはネストしたリストを用います。

例:

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

あるいは

```
>>> a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
```

配列の要素にアクセスするには鍵括弧を使います。配列の要素にアクセスするとき、NumPyのインデックスは0から始まることを忘れないでください。これはあなたが配列の最初の要素にアクセスしたいならば、配列”0”にアクセスすることになるだろうという意味です。

```shell
>>> print(a[0])
[1 2 3 4]
```



# 配列についてさらに詳しく

*この節では `1D array`, `2D array`, `ndarray`, `vector`, `matrix` を扱います*

「ndarray」と表記される配列を時折目にしたことがあるかもしれません。これは「N次元配列」の略記です。N次元配列は簡単に言うと任意の次元数をもつ配列です。「**1-D**」ないし一次元配列、「**2-D**」ないし二次元配列、etc...、もまた目にしたことがあるかもしれません。NumPyのndarrayクラスは行列とベクトルのどちらを表すのにも使われます。**ベクトル**は一次元配列（行ベクトルと列ベクトルの違いはありません）であり、**行列**は二次元の配列を参照します。 **3D**（三次元）以上の配列では、**テンソル**という用語もよく使われます。



#### **配列の属性とはなんですか？**

配列は通常、同じ種類かつ同じサイズの項目の固定サイズのコンテナです。配列の次元数と項目は配列の形から定義されます。配列の形は各次元のサイズを規定する自然数のタプルです。
NumPyでは、次元は**axes**と呼ばれます。すなわち、もし次のような配列があるなら

```shell
[[0., 0., 0.],
 [1., 1., 1.]]
```

この配列は二つの軸を持ちます。一つ目の軸の長さは2で、二つ目の長さは3です。
他のPythonコンテナと同様に、インデックスやスライシングで配列の内容にアクセスしたり修正したりすることができます。ですが典型的なコンテナオブジェクトと違って、同じデータを異なる配列で共有できるので、ある配列で行われた変更が、別の配列で現れるかもしれません。

配列の**属性**は配列固有の情報を反映します。もし新たに配列を作らずに配列のプロパティを得る、あるいは設定する必要があるなら、配列の属性を通して配列にアクセスすることが多いです。

[Read more about array attributes here](https://numpy.org/doc/stable/reference/arrays.ndarray.html#arrays-ndarray) and learn about [array objects here](https://numpy.org/doc/stable/reference/arrays.html#arrays).



# 簡単な配列をつくる方法

_この節では `np.array()`, `np.zeros()`, `np.ones()`, `np.empty()`, `np.arange()`, `np.linspace()`, `dtype`を扱います_

NumPy配列を作るには、関数`np.array()`を使います。
簡単な配列を作るのに必要なことは、リストを渡すことです。必要に応じてリストのデータ型を指定することもできます。 [You can find more information about data types here](https://numpy.org/doc/stable/reference/arrays.dtypes.html#arrays-dtypes).

```shell
>>> import numpy as np
>>> a = np.array([1, 2, 3])
```

次のように配列を視覚化することができます。![../_images/np_array.png](https://numpy.org/doc/stable/_images/np_array.png)
これらの視覚化は概念をわかりやすくし、NumPyの発想と仕組みの基礎的な理解を与えるためのものであることに注意してください。配列と配列操作はここで表現されたものよりはるかに複雑です。
要素の連続から作る配列以外にも、`0`で埋め尽くされた配列を簡単に作成することができます。

```shell
>>> np.zeros(2)
array([0., 0.])
```

他にも`1`で埋め尽くされた配列を作ることができます。

```shell
>>> np.ones(2)
array([1., 1.])
```

あるいは空の配列だってすら！`empty`関数は、初期内容がランダムかつメモリの状態に依存する配列を作成します。`empty`関数を`zero`関数(やそれに似たもの)に優先して使う理由はスピードです。後ですべての要素を埋めるのを忘れないようにしてください！

```shell
>>> # Create an empty array with 2 elements
>>> np.empty(2)
array([ 3.14, 42.  ])  # may vary
```

連続した要素の配列を作成できます：

```shell
>>> np.arange(4)
array([0, 1, 2, 3])
```

そして均等に間隔をあけた列からなる配列も作成できます。そのためには、**最初の数**・**最後の数**・ステップ数を指定します。

```shell
>>> np.arange(2, 9, 2)
array([2, 4, 6, 8])
```

`np.linspace()`を使用して、指定した間隔で線形に間を空けた値を持つ配列を作成することができます。

```shell
>>> np.linspace(0, 10, num=5)
array([ 0. ,  2.5,  5. ,  7.5, 10. ])
```



#### **データタイプを指定する**

デフォルトのデータ型は浮動小数点(np.float64)ですが、使いたいデータ型をdtypeキーワードで明示的に指定できます。

```shell
>>> x = np.ones(2, dtype=np.int64)
>>> x
array([1, 1])
```

[Learn more about creating arrays here](https://numpy.org/doc/stable/user/quickstart.html#quickstart-array-creation)



# 要素を追加・削除・ソートする

*この節は `np.sort()`, `np.concatenate()`を扱います*

要素をソートするとき、`np.sort()`を使うと簡単です。この関数を呼ぶ際には、軸、種類、順序を指定できます。

この配列を例にとると、

```shell
>>> arr = np.array([2, 1, 5, 3, 7, 4, 6, 8])
```


こうして昇順に素早く並び替えることができます。

```shell
>>> np.sort(arr)
array([1, 2, 3, 4, 5, 6, 7, 8])
```

sortは配列にソートされたコピーをかえしますが、その外にも以下を利用できます
・[`argsort`](https://numpy.org/doc/stable/reference/generated/numpy.argsort.html#numpy.argsort): 指定された軸による間接ソート
・[`lexsort`](https://numpy.org/doc/stable/reference/generated/numpy.lexsort.html#numpy.lexsort): 複数のキーによる間接的な静的ソート[indirect stable sort on multiple keys]
・[`searchsorted`](https://numpy.org/doc/stable/reference/generated/numpy.searchsorted.html#numpy.searchsorted): ソートされた配列から要素を発見する
・[`partition`](https://numpy.org/doc/stable/reference/generated/numpy.partition.html#numpy.partition): 部分ソート

これらの配列を例にしましょう:

```shell
>>> a = np.array([1, 2, 3, 4])
>>> b = np.array([5, 6, 7, 8])
```

np.concatenate()でこれらの配列を連結することができます。

```shell
>>> np.concatenate((a, b))
array([1, 2, 3, 4, 5, 6, 7, 8])
```

また、この配列を例にとると、:

```shell
>>> x = np.array([[1, 2], [3, 4]])
>>> y = np.array([[5, 6]])
```

こうすることで連結できます:

```shell
>>> np.concatenate((x, y), axis=0)
array([[1, 2],
       [3, 4],
       [5, 6]])
```

配列から要素を削除するには、インデックスを使用して残したい要素を選択するのが簡単です。
連結についてさらに知りたい場合は、右を参照してください: [`concatenate`](https://numpy.org/doc/stable/reference/generated/numpy.concatenate.html#numpy.concatenate).



# 配列の形とサイズをどうやって知るか?

*このセクションは `ndarray.ndim`, `ndarray.size`, `ndarray.shape`を扱います* 

`ndarray.ndim` は配列の軸の数、すなわち次元の数を示します。

`ndarray.size`は配列の要素の総数を示します。これは配列のサイズの要素を掛けたものです。

`ndarray.shape`は配列の次元ごとに格納されている要素の数を示す整数のタプルを表示します。たとえば、2行3列の2次元配列がある場合、配列の形状は(2,3)です。

たとえば、次の配列を作成するとします。

```shell
>>> array_example = np.array([[[0, 1, 2, 3],
...                           [4, 5, 6, 7]],
...                          [[0, 1, 2, 3],
...                           [4, 5, 6, 7]],
...                          [[0 ,1 ,2, 3],
...                           [4, 5, 6, 7]]])
```


配列の次元数を調べるには、次を実行します:

```shell
>>> array_example.ndim
3
```

配列の要素の総数を調べるには、次を実行します:

```shell
>>> array_example.size
24
```

そして配列の形状を調べるには、次を実行します:

```shell
>>> array_example.shape
(3, 2, 4)
```



# 配列を変形できますか？

*この節では `arr.reshape()`を扱います*

**もちろん!**
`arr.reshape()`を使えば、データを変更せずに配列に新しい形を与えることができます。この変形メソッドを使うときは、作りたい配列は元の配列と同じ要素数の必要があることを忘れないでください。12個の要素の配列を変形するなら、新たな配列もまた合計で12個の要素を持つことを確かめる必要があります。 
この配列を用いるなら:

```shell
>>> a = np.arange(6)
>>> print(a)
[0 1 2 3 4 5]
```

配列を変形するために`reshape()`を使えます。たとえば、この配列を3行2列の配列に変形することができます:

```shell
>>> b = a.reshape(3, 2)
>>> print(b)
[[0 1]
 [2 3]
 [4 5]]
```

`np.shape()`とともに、いくつかのパラメーターを指定することが可能です。:

```shell
>>> numpy.reshape(a, newshape=(1, 6), order='C')]
array([[0, 1, 2, 3, 4, 5]])
```

`a`は形状を変更する配列です。
`newshape` は新しい配列の形です。整数か整数のタプルを指定することができます。整数を指定した場合、その整数の長さの配列が生まれます。形状は元の形状と互換性をもつ必要があります。
`order:` `C` はCに似たインデックス順序で読み書きすることを表し、FはFortranに似たインデックス順序で読み書きすることを表します。Aは要素がメモリ上でFortran連続であれば、Fortranに似たインデックス順序を使い、そうでなければCに似たインデックスを使うことを意味します(これは任意のパラメーターであり、必ず指定する必要はありません)。
If you want to learn more about C and Fortran order, you can read more about the internal organization of NumPy arrays here. Essentially, C and Fortran orders have to do with how indices correspond to the order the array is stored in memory. In Fortran, when moving through the elements of a two-dimensional array as it is stored in memory, the first index is the most rapidly varying index. As the first index moves to the next row as it changes, the matrix is stored one column at a time. This is why Fortran is thought of as a Column-major language. In C on the other hand, the last index changes the most rapidly. The matrix is stored by rows, making it a Row-major language. What you do for C or Fortran depends on whether it’s more important to preserve the indexing convention or not reorder the data.
Learn more about shape manipulation here.



# 1D配列を2D配列に変換する方法（配列に新しいaxisを加える方法）

*この節では `np.newaxis`, `np.expand_dims`を扱います*

`np.newaxis` と  `np.expand_dims` を使えば、既存の配列の次元を増やすことが可能です。

`np.newaxis`を使用すると、一度だけ使用した場合には、配列の次元が一次元増加します。つまり、1D配列は2D配列に、2D配列は3D配列に、となります。

例えば、次の配列では、

```shell
>>> a = np.array([1, 2, 3, 4, 5, 6])
>>> a.shape
(6,)
```

`np.newaxis` を使って新たな軸を追加できます。:

```shell
>>> a2 = a[np.newaxis, :]
>>> a2.shape
(1, 6)
```

`np.newaxis` を使うことで、行ベクトルか列ベクトルのどちからの1D配列を明示的に変形することができます。たとえば、第1次元上の軸を挿入することで、1D配列を行ベクトルに変換することができます。

```shell
>>> row_vector = a[np.newaxis, :]
>>> row_vector.shape
(1, 6)
```

また、列ベクトルには、第2次元上の軸を挿入できます:

```shell
>>> col_vector = a[:, np.newaxis]
>>> col_vector.shape
(6, 1)
```

np.expand_dims で指定した軸を挿入して、配列を拡張することも可能です。
たとえば、この配列では、:

```shell
>>> a = np.array([1, 2, 3, 4, 5, 6])
>>> a.shape
(6,)
```

インデックス位置1に軸を追加するには`np.expand_dims`を使用できます。:

```shell
>>> b = np.expand_dims(a, axis=1)
>>> b.shape
(6, 1)
```

インデックス位置0に軸を追加するためには次のようにします。:

```shell
>>> c = np.expand_dims(a, axis=0)
>>> c.shape
(1, 6)
```



# 添え字アクセスとスライス(Indexing and slicing)

Numpy配列の添え字アクセスとスライスはPythonリストをスライスするのと同じ方法で行えます。

```shell
>>> data = np.array([1, 2, 3])

>>> data[1]
2
>>> data[0:2]
array([1, 2])
>>> data[1:]
array([2, 3])
>>> data[-2:]
array([2, 3])
```

これは次のように視覚化できます:![../_images/np_indexing.png](https://numpy.org/doc/stable/_images/np_indexing.png)

さらなる分析や操作に使うために、配列の一部や配列の特定の要素を取り出す必要があるかもしれません。そのためには、配列をサブセット、スライス、そして/もしくは インデクスしなければならないでしょう。

配列から特定の条件を満たす値を抜き出したいなら、NumPyを使うと簡単です。

たとえば、次の配列を例にします。

```shell
>>> a = np.array([[1 , 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
```

配列にある5未満の数値を簡単に表示できます.

```shell
>>> print(a[a < 5])
[1 2 3 4]
```

また、例えば5以上の数値を選択して、その条件を用いて配列のインデックスを作成することもできます。

```shell
>>> five_up = (a >= 5)
>>> print(a[five_up])
[ 5  6  7  8  9 10 11 12]
```

2で割れる要素たちを取り出すこともできます。:

```shell
>>> divisible_by_2 = a[a%2==0]
>>> print(divisible_by_2)
[ 2  4  6  8 10 12]
```

`&` と `|` 演算子を使い、二つの条件を満たす要素をとりだすこともできます:

```shell
>>> c = a[(a > 2) & (a < 11)]
>>> print(c)
[ 3  4  5  6  7  8  9 10]
```

また、論理演算子**&** と **|** を使って、配列の値がある条件を満たすか否かを示すブール値を返すこともできます。これは名前や別カテゴリーの値を持つ配列のときに便利です。

```shell
>>> five_up = (a > 5) | (a == 5)
>>> print(five_up)
[[False False False False]
 [ True  True  True  True]
 [ True  True  True True]]
```

`np.nonzero()` を使い配列から要素の要素やインデクスを選択することも可能です。
次の配列を起点にしましょう:

```
>>> a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
```

`np.nonzero()` を使って、この場合では5未満の、要素のインデクスを表示することができます:

```shell
>>> b = np.nonzero(a < 5)
>>> print(b)
(array([0, 0, 0, 0]), array([0, 1, 2, 3]))
```

この例では配列のタプルが返されます。返されるタプルはそれぞれの次元に一つずつです。第一の配列は条件を満たす値がある行インデクスを表し、第二の配列は条件を満たす値がある列インデクスを示します。

要素がある座標のリストを生成したい場合、この配列をzipし、座標のリストを反復処理して、表示することができます。たとえば、:

```shell
>>> list_of_coordinates= list(zip(b[0], b[1]))

>>> for coord in list_of_coordinates:
...    print(coord)
(0, 0)
(0, 1)
(0, 2)
(0, 3)
```


np.nonzero()を使って配列中で5未満の要素を表示することもまたできます:

```shell
>>> print(a[b])
[1 2 3 4]
 ```shell

探している要素が配列に存在しない場合、戻り値のインデクスの配列は空になります。たとえば、以下のようになります。

​```shell
>>> not_there = np.nonzero(a == 42)
>>> print(not_there)
(array([], dtype=int64), array([], dtype=int64))
```



# 既存のデータから配列をつくる方法

*この節では `slicing and indexing`, `np.vstack()`, `np.hstack()` ,`np.hsplit()`, `.view()`, `copy()`を扱います*



既存の配列の部分からたやすく配列を作ることができます。
次の配列があるとしましょう。

```shell
>>> a = np.array([1,  2,  3,  4,  5,  6,  7,  8,  9, 10])
```

配列のスライスしたい部分を指定することで、配列の部分からいつでも新しい配列を作ることができます。

```shell
>>> arr1 = a[3:8]
>>> arr1
array([4, 5, 6, 7, 8])
```

ここで、インデクス位置3からインデクス位置8までの範囲を指定しています。



既存の配列二つを連結するのは縦横どちらにもできます。次の二つの配列、`a1`,`a2`があるとします。

```shell
>>> a1 = np.array([[1, 1],
...               [2, 2]])

>>> a2 = np.array([[3, 3],
...               [4, 4]])
```

`vstack`を使って、これらを縦に積み重ねることができます。

```shell
>>> np.vstack((a1, a2))
array([[1, 1],
       [2, 2],
       [3, 3],
       [4, 4]])
```

そして`hstack`で横に積み重ねることができます。

```shell
>>> np.hstack((a1, a2))
array([[1, 1, 3, 3],
       [2, 2, 4, 4]])
```

`hsplit`で配列をいくつかの小さな配列に分割することができます。配列を同形配列何個に分割するかや、分割後の列の数を指定することができます。

この配列があるとしましょう:

```shell
>>> x = np.arange(1, 25).reshape(2, 12)
>>> x
array([[ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12],
       [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]])
```

もしあなたがこの配列を3つの同じ形の配列へと分割したいなら、次のコードを実行しましょう。

```shell
>>> np.hsplit(x, 3)
[array([[1,  2,  3,  4],
        [13, 14, 15, 16]]), array([[ 5,  6,  7,  8],
        [17, 18, 19, 20]]), array([[ 9, 10, 11, 12],
        [21, 22, 23, 24]])]
```

もし3列目と4列目の後ろで配列を分割したいなら、次のコードを実行しましょう。

```shell
>>> np.hsplit(x, (3, 4))
[array([[1, 2, 3],
        [13, 14, 15]]), array([[ 4],
        [16]]), array([[ 5, 6, 7, 8, 9, 10, 11, 12],
        [17, 18, 19, 20, 21, 22, 23, 24]])]
```

[Learn more about stacking and splitting arrays here.](https://numpy.org/doc/stable/user/quickstart.html#quickstart-stacking-arrayshttps://numpy.org/doc/stable/user/quickstart.html#quickstart-stacking-arrays)



`view`メソッドを使って、元の配列と同じデータを参照する新たな配列を作ることができます(浅いコピー:shallow copy)。

ビューはNumPyの重要な概念の一つです。NumPyの関数は、添字アクセスやスライスなどの操作と同様に、可能な限りビューを返します。これはメモリの節約になり、高速です（データのコピーを作成する必要がありません）。しかし注意しなければならないことがあります––ビュー内のデータを変更すると、元の配列も変更されてしまいます。

次のような配列を作成したとしましょう。

```shell
>>> a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
```

ここで`a`をスライスして`b1`をつくり、`b1`の最初の要素を変更します。この操作は`a`の対応する要素をも変更します。


```shell>>>
>>> b1 = a[0, :]
>>> b1
array([1, 2, 3, 4])
>>> b1[0] = 99
>>> b1
array([99,  2,  3,  4])
>>> a
array([[99,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])
```

`copy`メソッドを使用すると、配列とそのデータの完全なコピーを作成します（ディープコピー）。これを配列に使用するには、次のコードを実行します。


```shell>>>
>>> b2 = a.copy()
```




# 配列の基本的演算(operation)

*この節では加算、減算、乗算、除算などを扱います* 



配列を作成したら、その配列で作業を始めることができます。例えば、”data”と”ones”と呼ばれる二つの配列を作成したとしましょう。![../_images/np_array_dataones.png](https://numpy.org/doc/stable/_images/np_array_dataones.png)

プラス記号を使って配列を足し合わせることができます。

```shell
>>> data = np.array([1, 2])
>>> ones = np.ones(2, dtype=int)
>>> data + ones
array([2, 3])
```

![../_images/np_data_plus_ones.png](https://numpy.org/doc/stable/_images/np_data_plus_ones.png)

もちろん、できることは加算だけに留まりません!

```shell
>>> data - ones
array([0, 1])
>>> data * data
array([1, 4])
>>> data / data
array([1., 1.])
```

![../_images/np_sub_mult_divide.png](https://numpy.org/doc/stable/_images/np_sub_mult_divide.png)

NumPyでは基本的操作は簡単です。もし配列の合計を知りたいなら、sum()を使いましょう。これは1D, 2Dやそれ以上の配列で動きます。

```shell
>>> a = np.array([1, 2, 3, 4])

>>> a.sum()
10
```

二次元配列で列や行を加算したいなら(To add the rows or the columns in a 2D array)、軸を指定します。
この配列から始める場合、:

```shell
>>> b = np.array([[1, 1], [2, 2]])
```

行は次のように合計できます:

```shell
>>> b.sum(axis=0)
array([3, 3])
```

列は次のように合計できます。:

```shell
>>> b.sum(axis=1)
array([2, 4])
```




# Broadcasting

配列とひとつの数とで、あるいは異なるサイズの配列間で、演算したい時があります（前者はベクトルとスカラー間の演算とも呼ばれます）。たとえば、ある配列（”data”と呼びます）は何マイル離れているかの情報を持っており、あなたはそれをキロメートルに変換したいものとします。この操作を次のように行うことができます。

```shell
>>> data = np.array([1.0, 2.0])
>>> data * 1.6
array([1.6, 3.2])
```

![../_images/np_multiply_broadcasting.png](https://numpy.org/doc/stable/_images/np_multiply_broadcasting.png)

NumPyは掛け算が一つ一つのセルで行われなければならないことを了解しています。このコンセプトは**ブロードキャスト**と呼ばれます。ブロードキャステトはNumPyが相異なる形の配列の演算を行うための仕組みです。配列の次元は互換性がなければなりません。例えば、両方の配列の次元が同じか、片方が1次元の場合にそうです。もしそうでなければ、`ValueError`が発生します。



# より便利な配列操作

この節では、`maximum`, `minimum`, `sum`, `mean`, `product`, `standard deviation` などを扱います

NumPyは集合関数も実行します。`min`, `max`, `sum`に加えて、平均を得るための`mean`, 要素をかけ合わせた結果を得るための`prod`, 標準偏差を得るための`std`などを簡単に実行できます。

```shell
>>> data.max()
2.0
>>> data.min()
1.0
>>> data.sum()
3.0
```

![../_images/np_aggregation.png](https://numpy.org/doc/stable/_images/np_aggregation.png)

まずこの配列、“a”から始めましょう

```shell
>>> a = np.array([[0.45053314, 0.17296777, 0.34376245, 0.5510652],
...              [0.54627315, 0.05093587, 0.40067661, 0.55645993],
...              [0.12697628, 0.82485143, 0.26590556, 0.56917101]])
```

行や列に沿って集計したいというのは非常によくあることです。デフォルトでは、NumPy集計関数はすべて、配列全体の総和を返します。配列の要素の合計や最小値を知りたいときは、次のコードを用います。

```shell
>>> a.sum()
4.8595784
```

あるいは:

```shell
>>> a.min()
0.05093587
```

どの軸で集計関数をさせたいのか指定することができます。たとえば、axis=0とすることで、各列内の最小値を見つけることができます。

```shell
>>> a.min(axis=0)
array([0.12697628, 0.05093587, 0.26590556, 0.5510652 ])
```

上記の4つの数値は元の配列の行の数値と一致しています。4行の配列では、結果として、4つの値を得ることができます。


# 行列を作る

Pythonリストを渡して、NumPyでその配列を表す2D配列（または「行列」）を作ることができます。

```shell
>>> data = np.array([[1, 2], [3, 4]])
>>> data
array([[1, 2],
       [3, 4]])
```

![../_images/np_create_matrix.png](https://numpy.org/doc/stable/_images/np_create_matrix.png)

添え字アクセスとスライス操作は、行列を扱う際に便利です。

```shell
>>> data[0, 1]
2
>>> data[1:3]
array([[3, 4]])
>>> data[0:2, 0]
array([1, 3])
```

![../_images/np_matrix_indexing.png](https://numpy.org/doc/stable/_images/np_matrix_indexing.png)

行列の操作はベクトルの操作と同じ方法でできます。

```shell
>>> data.max()
4
>>> data.min()
1
>>> data.sum()
10
```

![../_images/np_matrix_aggregation.png](https://numpy.org/doc/stable/_images/np_matrix_aggregation.png)

行列内のすべての値を集計することも、軸パラメータを使って列か行をまたいで[across columns or rows]集計することができます。

```shell
>>> data.max(axis=0)
array([3, 4])
>>> data.max(axis=1)
array([2, 4])
```

![../_images/np_matrix_aggregation_row.png](https://numpy.org/doc/stable/_images/np_matrix_aggregation_row.png)

行列を作成したら、同じサイズの行列が二つあれば、算術演算子を使って足し算や掛け算を行えます。

```shell
>>> data = np.array([[1, 2], [3, 4]])
>>> ones = np.array([[1, 1], [1, 1]])
>>> data + ones
array([[2, 3],
       [4, 5]])
```

![../_images/np_matrix_arithmetic.png](https://numpy.org/doc/stable/_images/np_matrix_arithmetic.png)

異なるサイズの行列に対してもこれらの算術演算をすることができますが、一方の行列が一行か一列しかない場合に限ります。この場合、NumPyは演算のためにブロードキャスト規則を使います。

```shell
>>> data = np.array([[1, 2], [3, 4], [5, 6]])
>>> ones_row = np.array([[1, 1]])
>>> data + ones_row
array([[2, 3],
       [4, 5],
       [6, 7]])
```

![../_images/np_matrix_broadcasting.png](https://numpy.org/doc/stable/_images/np_matrix_broadcasting.png)

NumPyがN次元の配列を表示するとき、最後の軸は最もループし、対して最初の軸は緩やかにループすることに注意してください[次の例では最後の軸である列に関しては12回のループが、最初の軸については4回のループがある]。
たとえば、

```shell
>>> np.ones((4, 3, 2))
array([[[1., 1.],
        [1., 1.],
        [1., 1.]],
 
       [[1., 1.],
        [1., 1.],
        [1., 1.]],
 
       [[1., 1.],
        [1., 1.],
        [1., 1.]],
 
       [[1., 1.],
        [1., 1.],
        [1., 1.]]])
```

NumPyで配列を初期化したい場合がよくあります。NumPyは`ones()`や`zeros()`といった関数や、乱数生成のための`random.Generator`クラスを提供しています。初期化に必要なのは、ただ生成してほしい要素数を渡すことだけです。

```shell
>>>np.ones(3)
array([1., 1., 1.])
>>> np.zeros(3)
array([0., 0., 0.])
# the simplest way to generate random numbers
>>> rng = np.random.default_rng(0)
>>> rng.random(3)
array([0.63696169, 0.26978671, 0.04097352])
```

![../_images/np_ones_zeros_random.png](https://numpy.org/doc/stable/_images/np_ones_zeros_random.png)この関数やメソッドに二次元の行列を表すタプルを与えれば、`ones()`、`zeros()` と `random()` を使って二次元配列も生成可能です。

```shell
>>> np.ones((3, 2))
array([[1., 1.],
       [1., 1.],
       [1., 1.]])
>>> np.zeros((3, 2))
array([[0., 0.],
       [0., 0.],
       [0., 0.]])
>>> rng.random((3, 2))
array([[0.01652764, 0.81327024],
       [0.91275558, 0.60663578],
       [0.72949656, 0.54362499]])  # may vary
```





# 乱数を生成する

乱数生成の使用は多くの数学的あるいは機械学習アルゴリズムの配置や評価の重要なパートです。人工神経ネットワークの重さのランダムな初期化、ランダムなセットへの分割、あるいはデータセットのランダムシャッフル、どれにせよ、乱数（実際には、再現可能な擬似乱数の数）の生成をできることは欠かせません。`Generator.integers`を使って、最小値から最大値までのランダムな整数を出力できます（Numpyでは最小値は含まれ、最大値は含まれない事に注意してください）。`endpoint=True`を設定して、最高値を含む乱数を生成することができます。


0から4までのランダムな整数から成る2×4行列を生成することができます:

```shell
>>> rng.integers(5, size=(2, 4))
array([[2, 1, 1, 0],
       [0, 0, 0, 4]])  # may vary
```





# 重複しない要素を取り出し数える方法

*この節では `np.unique()`を扱います*

`Np.unique`で配列の要素を重複なしに一つずつ取り出すことができます。
たとえば、この配列を例にします。

```shell
>>> a = np.array([11, 11, 12, 13, 14, 15, 16, 17, 12, 13, 11, 14, 18, 19, 20])
```

`Np.unique`を使って配列中のユニークな値を知ることができます。

```shell
>>>
>>> unique_values = np.unique(a)
>>> print(unique_values)
[11 12 13 14 15 16 17 18 19 20]
```

Numpy配列のユニークな値のインデクス（配列のユニークな値それぞれの最初のインデックス）を得るためには、`np.unique()`に配列とともに`return_index`引数を渡してください。

```shell
>>> unique_values, indices_list = np.unique(a, return_index=True)
>>> print(indices_list)
[ 0  2  3  4  5  6  7 12 13 14]
```

Numpy配列のユニークな値がそれぞれいくつあるかをしるために、`np.unique()`に配列とともに`return_counts`引数をわたすことができます。

```shell
>>> unique_values, occurrence_count = np.unique(a, return_counts=True)
>>> print(occurrence_count)
[3 2 2 2 1 1 1 1 1 1]
```

これは二次元配列でも作用します! この配列を用いた場合、

```shell
>>> a_2d = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [1, 2, 3, 4]])
```

こうしてユニークな値を見つけることができます。

```shell
>>> unique_values = np.unique(a_2d)
>>> print(unique_values)
[ 1  2  3  4  5  6  7  8  9 10 11 12]
```



軸引数が渡されなかった場合、二次元配列は一次元に平坦化されます。
もしユニークな行や列を知りたい場合、必ずaxis引数をわたすようにしてください。ユニークな行をしるためには`axis=0`を指定し、列には`axis=1`を指定してください。

```shell
>>> unique_rows = np.unique(a_2d, axis=0)
>>> print(unique_rows)
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
```

ユニークな列やインデックス位置や出現数を得るためには、以下のようにします:

```shell
>>> unique_rows, indices, occurrence_count = np.unique(
...     a_2d, axis=0, return_counts=True, return_index=True)
>>> print(unique_rows)
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
>>> print(indices)
[0 1 2]
>>> print(occurrence_count)
[2 1 1]
```



# 行列の転置と変形

*この節では `arr.reshape()`, `arr.transpose()`, `arr.T()`を扱います*
行列の転置を必要とすることはしばしばあります。Numpy配列は行列を転置させるプロパティ`T`を持ちます。![../_images/np_transposing_reshaping.png](https://numpy.org/doc/stable/_images/np_transposing_reshaping.png)

また、配列の次元を入れ替える必要があるかもしれません。これはたとえば、データセットと異なる入力の配列形を想定したモデルがある場合などに起こります。このような場合にreshapeメソッドが役に立ちます。必要なのは、行列に必要な新しい寸法[dimensions]を渡すだけです。

```shell
>>> data.reshape(2, 3)
array([[1, 2, 3],
       [4, 5, 6]])
>>> data.reshape(3, 2)
array([[1, 2],
       [3, 4],
       [5, 6]])
```

![../_images/np_reshape.png](https://numpy.org/doc/stable/_images/np_reshape.png)

`.transpose`を使って、指定した値に従い、配列の軸を反転させたり変更したりすることもできます。

この配列を例にとりましょう：

```shell
>>> arr = np.arange(6).reshape((2, 3))
>>> arr
array([[0, 1, 2],
       [3, 4, 5]])
```

`arr.transpose()`を使って配列を転置できます。

```shell
>>> arr.transpose()
array([[0, 3],
       [1, 4],
       [2, 5]])
```



# 配列を反転させる方法

*この節は `np.flip` を扱います*

NumPyの`np.flip()`はaxisを基準に、配列の軸を反転させることができます。`np.flip()`を使うときは反転させたい配列と軸を指定してください。軸を指定しない場合、NumPyは与えられた配列をすべての軸に関して反転させます。



#### 1D配列を反転させる

次のような一次元配列を例にとりましょう：

```shell
>>> arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
```

こうやって配列を反転できます：

```shell
>>> reversed_arr = np.flip(arr)
```

反転された配列を表示したいなら、このコードを実行しましょう:

```shell
>>> print('Reversed Array: ', reversed_arr)
Reversed Array:  [8 7 6 5 4 3 2 1]
```



#### 2D配列を反転させる

2D配列も、ほぼ同じやり方で反転します。	

この配列を例にとりましょう：

```shell
>>> arr_2d = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
```

すべての列と行で内容を反転させることができます。

```shell
>>> reversed_arr = np.flip(arr_2d)
>>> print(reversed_arr)
[[12 11 10  9]
 [ 8  7  6  5]
 [ 4  3  2  1]]
```

行だけを反転するのはこうするだけです:

```shell
>>> reversed_arr_rows = np.flip(arr_2d, axis=0)
>>> print(reversed_arr_rows)
[[ 9 10 11 12]
 [ 5  6  7  8]
 [ 1  2  3  4]]
```

列だけを反転するには:

```shell
>>> reversed_arr_columns = np.flip(arr_2d, axis=1)
>>> print(reversed_arr_columns)
[[ 4  3  2  1]
 [ 8  7  6  5]
 [12 11 10  9]]
```

一つの行や列だけを反転させることもできます。たとえば、インデックスが1の行（2行目）を反転させることできます:

```shell
>>> arr_2d[1] = np.flip(arr_2d[1])
>>> print(arr_2d)
[[ 1  2  3  4]
 [ 8  7  6  5]
 [ 9 10 11 12]]
```

インデックスが1の列（2列目）を反転させることもできます:

```shell
>>> arr_2d[:,1] = np.flip(arr_2d[:,1])
>>> print(arr_2d)
[[ 1 10  3  4]
 [ 8  7  6  5]
 [ 9  2 11 12]]
```



# 多次元配列を再整形・平坦化させる方法

*この節では `.flatten()`, `ravel()`を扱います*

配列をフラットにする一般的な方法は二つあります。`.flatten()` と `.ravel()`です。この二つの主要な違いは、.ravel()を使って作られた配列は、実は親配列への参照（つまり「ビュー」）なのです。したがって、新しい配列を何か変更すると、親配列もまた同様に変更されるということになります。`ravel`はコピーを作らないので、メモリ効率が良いです。

```shell
>>> x = np.array([[1 , 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
```

`flatten`を使って、配列を1D配列にすることができます。

```shell
>>> x.flatten()
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])
```

 `flatten`‘を使うと、配列への変更は親配列に適用されません。

たとえば：

```shell
>>> a1 = x.flatten()
>>> a1[0] = 99
>>> print(x)  # Original array
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
>>> print(a1)  # New array
[99  2  3  4  5  6  7  8  9 10 11 12]
```

しかし`ravel`を使うと、配列への変更は親配列に適用されません。

```shell
>>> a2 = x.ravel()
>>> a2[0] = 98
>>> print(x)  # Original array
[[98  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
>>> print(a2)  # New array
[98  2  3  4  5  6  7  8  9 10 11 12]
```



# docstringにアクセスして詳細を知る

この節では `help()`, `?`, `??`を扱います。

データサイエンスエコシステムに関しては[when it comes to]、PythonとNumPyはユーザーのことを念頭に置いて作られています。このことの良い例の一つが、ドキュメンテーションへのアクセスが備え付けられていることです。すべてのオブジェクトは文字列への参照があり、その文字列はdocstringとして知ら得ています。たいていの場合、このdocstringは手短かつ簡潔なオブジェクトの概要と使い方を含みます。Pythonは組み込みのhelp関数を持ち、これはdocstringにアクセスするのを手助けします。つまり、より情報が必要なときはたいてい、help()を使って必要な情報をすぐに見つけることができます。

たとえば、

```shell
>>> help(max)
Help on built-in function max in module builtins:
 
max(...)
    max(iterable, *[, default=obj, key=func]) -> value
    max(arg1, arg2, *args, *[, key=func]) -> value
 
    With a single iterable argument, return its biggest item. The
    default keyword-only argument specifies an object to return if
    the provided iterable is empty.
    With two or more arguments, return the largest argument.
```

更なる情報へのアクセスはなかなか役立つので、IPythonは？をドキュメンテーションと関連した他の情報にアクセスするための略号として用います。IPythonは複数の言語で使える、インタラクティブな計算を行うためのコマンドシェルです。[IPythonについてのさらなる情報はこちら](https://ipython.org/)。

たとえば、

```shell
In [0]: max?
max(iterable, *[, default=obj, key=func]) -> value
max(arg1, arg2, *args, *[, key=func]) -> value
 
With a single iterable argument, return its biggest item. The
default keyword-only argument specifies an object to return if
the provided iterable is empty.
With two or more arguments, return the largest argument.
Type:      builtin_function_or_method
```

この表記法を、オブジェクトメソッドやオブジェクトそのものにさえ使うことができます。

次の配列を作ったとしましょう。


```shell
>>> a = np.array([1, 2, 3, 4, 5, 6])
```

すると、たくさんの役立つ情報を得ることができます（最初にオブジェクトそのものの詳細、次にaがインスタンスであるndarrayのdocstringが続きます）。

```shell
In [1]: a?
Type:            ndarray
String form:     [1 2 3 4 5 6]
Length:          6
File:            ~/anaconda3/lib/python3.7/site-packages/numpy/__init__.py
Docstring:       <no docstring>
Class docstring:
ndarray(shape, dtype=float, buffer=None, offset=0,
        strides=None, order=None)
 
An array object represents a multidimensional, homogeneous array
of fixed-size items.  An associated data-type object describes the
format of each element in the array (its byte-order, how many bytes it
occupies in memory, whether it is an integer, a floating point number,
or something else, etc.)
 
Arrays should be constructed using `array`, `zeros` or `empty` (refer
to the See Also section below).  The parameters given here refer to
a low-level method (`ndarray(...)`) for instantiating an array.
 
For more information, refer to the `numpy` module and examine the
methods and attributes of an array.
 
Parameters
----------
(for the __new__ method; see Notes below)
 
shape : tuple of ints
        Shape of created array.
...
```

これはあなたが作成した関数や他のオブジェクトにも作用します。ただ。関数内に文字リテラルを使ってdocstringを入れるのを忘れないで下さい（`""" """` か `''' '''` でドキュメンテーションを囲む）。

たとえば、次の関数を作った場合、

```shell
>>> def double(a):
...  '''Return a * 2'''
...  return a * 2
```

この関数について情報を得るには、次のようにします。

 ```
 In [2]: double?
Signature: double(a)
Docstring: Return a * 2
File:      ~/Desktop/<ipython-input-23-b5adf20be596>
Type:      function

 ```

関心あるオブジェクトのソースコードを読むことで、また違った水準の情報に触れることができます。二重疑問符(??)を使うことで、ソースコードにアクセスできます。

たとえば、

```shell
In [3]: double??
Signature: double(a)
Source:
def double(a):
    '''Return a * 2'''
    return a * 2
File:      ~/Desktop/<ipython-input-23-b5adf20be596>
Type:      function
```

当該のオブジェクトがPython以外の言語でコンパイルされている場合、??を使うと?と同じ情報が返ってきます。このことは、たくさんの組み込みオブジェクトやタイプで見ることができます。たとえば、

```shell
In [4]: len?
Signature: len(obj, /)
Docstring: Return the number of items in a container.
Type:      builtin_function_or_method
```

そして :

```shell
In [5]: len??
Signature: len(obj, /)
Docstring: Return the number of items in a container.
Type:      builtin_function_or_method
```

これらが同一の出力なのは、これらがPythonではない言語でコンパイルされているからです。



# 数式を扱う

NumPyが科学のPythonコミュニティでここまで広く使われている理由の一つに、配列上で作用する数式を簡単に実装できることがあります。

たとえば、これが平均二乗誤差（回帰を扱う教師付き機械学習モデルで使われる中心的な公式）です。

![../_images/np_MSE_formula.png](https://numpy.org/doc/stable/_images/np_MSE_formula.png)

この式の実装はNumPyではシンプルで式そのままです：

```shell
error  = (1/n) * np.sum(np.square(predictions - labels))
```

これが非常にうまく機能するのは、予測値とラベルが1個でも1000個の値でも含むことができるからです。必要なのは、予測値とラベルが同じサイズであることだけです。

これは次のように可視化することができます。

![../_images/np_mse_viz1.png](https://numpy.org/doc/stable/_images/np_mse_viz1.png)

この例では、予測とラベルは3つの値をもつベルトルであり、それゆえnは3という値をとります。引き算を行った後、ベクトルの値は二乗されます。そしてNumPyが値を合計し、その結果が予測値の誤差とモデルの品質のスコアとなります。

![../_images/np_mse_viz2.png](https://numpy.org/doc/stable/_images/np_mse_viz2.png)



# NumPyをセーブ・ロードする方法

*この節は `np.save`, `np.savez`, `np.savetxt`, `np.load`, `np.loadtxt`を扱います*

いつか、配列をディスクに保存して、コードをもう一度実行することなくロードしたいと思うことがあるでしょう。さいわい、NumPyではオブジェクトを保存したりロードしたりする方法がいくつかあります。ndarrayオブジェクトは、`loadtxt` と `savetxt`関数で通常のテキストファイルをロード・セーブし、`load` and `save`関数で.npz拡張子のNumPyバイナリファイルを扱うことができます。そして、`savez`関数で.npz拡張子のNumpyファイルを扱うことができます。

**.npy**と **.npz**ファイルは、ファイルが異なるアーキテクチャ上でも正しく復旧できるように、データ、形状、dtypeやその他の、ndarrayを再構築するために必要な情報を格納しています。

1つのndarrayオブジェクトを保存したい場合、np.saveを使って.npyファイルとして保存してください。複数のndarrayを配列に保存したい場合、np.savezを使って.npzとして保存してください。また、savez_compressedを用いて圧縮されたnpz形式で保存することで、複数の配列を1つのファイルに保存することもできます。

`np.save()`でセーブ・ロード・配列するのは簡単です（It’s easy to save and load and array with np.save().）。保存したい配列とファイルネームを指定することを忘れないでください。たとえば、この配列をつくった場合、

```shell
>>> a = np.array([1, 2, 3, 4, 5, 6])
```

"filename.npy"として保存できます。

```shell
>>> np.save('filename', a)
```

np.load()で配列を復元できます。

```shell
>>> b = np.load('filename.npy')
```


もし配列を確かめたいなら、このコードを実行すればよいです。

```shell
>>> print(b)
[1 2 3 4 5 6]
```

np.savetxtを使えば、.csvや.txtファイルのようなプレーンテキストとしてNumPyファイルを保存できます。

たとえば、次の配列を作った場合、

```shell
>>> csv_arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
​```shell
 
You can easily save it as a .csv file with the name “new_file.csv” like this:

​```shell
>>> np.savetxt('new_file.csv', csv_arr)
```

loadtxt()を使って、簡単に保存したテキストファイルを読み込めます。

```shell
>>> np.loadtxt('new_file.csv')
array([1., 2., 3., 4., 5., 6., 7., 8.])
```

savetxt()とloadtxt()関数はヘッダー、フッター、区切り文字といった追加パラメーターを受け付けます。テキストファイルは共有に便利な一方で、.npyと.npzファイルは小さく、読み書きが高速です。もしテキストファイルのもっと洗練された取り扱いが必要なら(たとえば欠損値を含む行列[lines]を扱う場合)、[`genfromtxt`](https://numpy.org/doc/stable/reference/generated/numpy.genfromtxt.html#numpy.genfromtxt) 関数を使う必要があるでしょう。

[`savetxt`](https://numpy.org/doc/stable/reference/generated/numpy.savetxt.html#numpy.savetxt)を使うとき、ヘッダー、フッター、コメントなどを指定することができます。

Learn more about [input and output routines here](https://numpy.org/doc/stable/reference/routines.io.html#routines-io).



# CSVをインポート・エクスポートする方法

既存の情報が入っているCSVファイルを読み込むのは簡単です。最も簡単な方法は[Pandas](https://pandas.pydata.org/getpandas.html)を使うことです。

```shell
>>> import pandas as pd
 
>>> # If all of your columns are the same type:
>>> x = pd.read_csv('music.csv', header=0).values
>>> print(x)
[['Billie Holiday' 'Jazz' 1300000 27000000]
 ['Jimmie Hendrix' 'Rock' 2700000 70000000]
 ['Miles Davis' 'Jazz' 1500000 48000000]
 ['SIA' 'Pop' 2000000 74000000]]
 
>>> # You can also simply select the columns you need:
>>> x = pd.read_csv('music.csv', usecols=['Artist', 'Plays']).values
>>> print(x)
[['Billie Holiday' 27000000]
 ['Jimmie Hendrix' 70000000]
 ['Miles Davis' 48000000]
 ['SIA' 74000000]]
```

![../_images/np_pandas.png](https://numpy.org/doc/stable/_images/np_pandas.png)

配列のエクスポートもPandasを使えば簡単です。NumPyに慣れていない方は、配列の値からPandasデータフレームを作り、そのデータフレームをPandasでCSVファイルに書き出すのが良いでしょう。

配列"a"を作ったとしましょう。

```shell
>>> a = np.array([[-2.58289208,  0.43014843, -1.24082018, 1.59572603],
...              [ 0.99027828, 1.17150989,  0.94125714, -0.14692469],
...              [ 0.76989341,  0.81299683, -0.95068423, 0.11769564],
...              [ 0.20484034,  0.34784527,  1.96979195, 0.51992837]])
```

Pandasデータフレームを次のように作成できます。

```shell
>>> df = pd.DataFrame(a)
>>> print(df)
          0         1         2         3
0 -2.582892  0.430148 -1.240820  1.595726
1  0.990278  1.171510  0.941257 -0.146925
2  0.769893  0.812997 -0.950684  0.117696
3  0.204840  0.347845  1.969792  0.519928
```

次のようにしてデータフレームを保存できます。

```shell
>>> df.to_csv('pd.csv')
```

CSVはこう

```shell
>>> data = pd.read_csv('pd.csv')
```

![../_images/np_readcsv.png](https://numpy.org/doc/stable/_images/np_readcsv.png)NumPyのsavetxtメソッドを使って保存することもできます。

```shell
>>> np.savetxt('np.csv', a, fmt='%.2f', delimiter=',', header='1,  2,  3,  4')
```

コマンドラインを使っているなら、次のようなコマンドで保存したCSVをいつでも読み込むことができます。

```shell
$ cat np.csv
#  1,  2,  3,  4
-2.58,0.43,-1.24,1.60
0.99,1.17,0.94,-0.15
0.77,0.81,-0.95,0.12
0.20,0.35,1.97,0.52
```


または、テキストエディタでいつでも開くことができます。

Pandasについてもっと詳しく知りたい方は、[official Pandas documentation](https://pandas.pydata.org/index.html)を見てみてください。Pandasをインストールする方法については、[official Pandas installation information](https://pandas.pydata.org/pandas-docs/stable/install.html)を参照してください。



# Matplotlibで配列をプロットする

値のプロットを作成する必要がある場合、Matplotlibを使用すると非常に簡単です。

たとえば、このような配列があるかもしれません。

```shell
>>> a = np.array([2, 1, 5, 7, 4, 6, 8, 14, 10, 9, 18, 20, 22])
```

Matplotlibをすでにインストールしているなら、このようにインポートできます。

```shell
>>> import matplotlib.pyplot as plt
 
# If you're using Jupyter Notebook, you may also want to run the following
# line of code to display your code in the notebook:
 
%matplotlib inline
```

値をプロットするには、面倒な操作はいりません。

```shell
>>> plt.plot(a)
 
# If you are running from a command line, you may need to do this:
# >>> plt.show()
```

![../_images/matplotlib1.png](https://numpy.org/doc/stable/_images/matplotlib1.png)

たとえば、1D配列を次のようにプロットできます。

```shell
‘>>> x = np.linspace(0, 5, 20)
>>> y = np.linspace(0, 10, 20)
>>> plt.plot(x, y, 'purple') # line
>>> plt.plot(x, y, 'o')      # dots
```

![../_images/matplotlib2.png](https://numpy.org/doc/stable/_images/matplotlib2.png)

Matplotlibでは、膨大な数の可視化オプションを使うことができます。

```shell
>>> from mpl_toolkits.mplot3d import Axes3D
>>> fig = plt.figure()
>>> ax = Axes3D(fig)
>>> X = np.arange(-5, 5, 0.15)
>>> Y = np.arange(-5, 5, 0.15)
>>> X, Y = np.meshgrid(X, Y)
>>> R = np.sqrt(X**2 + Y**2)
>>> Z = np.sin(R)
 
>>> ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='viridis')
```

![../_images/matplotlib3.png](https://numpy.org/doc/stable/_images/matplotlib3.png)

To read more about Matplotlib and what it can do, take a look at [the official documentation](https://matplotlib.org/). For directions regarding installing Matplotlib, see the official [installation section](https://matplotlib.org/users/installing.html).

------

*mage credits: Jay Alammar http://jalammar.github.io/*