# python_course4
## 本章の目的
1. NumPyを用いて、配列の作成や計算機能を使えるようになること
2. Matplotlibを用いて、グラブの描画ができるようになること
3. Pandasを用いて、CSVファイルのデータ処理が行えるようになること
## NumPyによる数値計算
### NumPyとは
NumPy (ナンパイ / ナムパイ) は配列を作成できるライブラリで、行列やベクトルなどの計算機能を有しています。本コースでは、NumPyを用いた配列の作成や四則演算などの計算を学んでいきます。
### 配列の作成
数学では以下のように行列を表現します。行列Aと呼ぶことにします。

早速、行列AをNumpyで書いてみましょう。NumPyを使うには、まずNumPyモジュールをインポートする必要があります。JupyterLabの最初の行でインポートすることを忘れないでください。
###### 実行コード
```
import numpy as np
a = np.array([[1, 2], [3, 4]])
print(a)
```
###### 実行結果
```
[[1, 2]
[3, 4]]
```
1行目でNumpyライブラリをインポートしています。「as np」とすることで、NumPyの持つ各種関数を「np.関数名」という形で記述することができます。2行目で、np.array関数を使って配列を作成しています。np.array関数では引数に1行ずつ、成分を格納したリストを渡しています。
ここで、作成した配列のデータ型も確認しておきましょう。
###### 実行コード
```
上記コードの続き
print(type(a))
```
###### 実行結果
```
<class 'numpy.ndarray'>
```
NumPyの配列のデータ型は「ndarray (N-dimensional array = N次元配列)」と言います。以降では、「NumPyの配列」のことをndarrayと呼んでいきます。
ndarrayは、整数以外の要素も取ることができます。以下の例を見てみましょう(ここからはNumPyがインポートされている前提で進めていきます)。
###### 実行コード
```
b = np.array([5.6, 7.8])
print(b)
c = np.array([True, False, True])
print(c)
d = np.array(list('Python'))
print(d)
```
###### 実行結果
```
[5.6 7.8]
[ True False True]
['P' 'y' 't' 'h' 'o' 'n']
```
それぞれ、浮動小数、真偽値、文字列が要素の配列ができました。
### 配列作成で使える便利な関数
以下で紹介する関数を使って、より効率的に、より柔軟にndarrayを作れるようになりましょう。
#### np.arange関数
連続した整数を要素に持つndarrayを作成するのに最適なのがnp.arange関数です。数学的には、等差数列と呼ばれるものです。np.arange関数は、range関数と似ています。引数が1つ(np.arange(n)) なら「0以上n未満」、2つ (np.arange(a, b)) なら「a以上b未満」、3つ (np.arrange (a, b, c)) なら「a以上b未満 (増分:c)」という形で配列ができます。
###### 実行コード
```
e = np.arange(9)
print(e)
f = np.arange(10, 20)
print(f)
g = np.arange(10, 20, 2)
print(g)
```
###### 実行結果
```
[0 1 2 3 4 5 6 7 8]
[10 11 12 13 14 15 16 17 18 19]
[10 12 14 16 18]
```
#### np.linspace関数
np.arange関数と同様、等差数列を作成できる関数です。記述の仕方は、np.arange関数の引数3つのパターンと同じ (np.arrange (a, b, c)) ですが、その意味としては、「a以上b以下の数値をc分割」となります。基本的に、np.linspace関数は小数の等差数列の作成に適しています。「整数ならnp.arange関数、小数ならnp.linspace関数」と理解していただいて差し支えないでしょう。
###### 実行コード
```
h = np.linspace(10, 20, 5)
print(h)
```
###### 実行結果
```
[10. 12.5 15. 17.5 20. ]
```
10以上20以下の数値を5分割したので、12.5 のように小数が出てきました。NumPyでは整数値と小数値が混在した場合、全ての要素が小数値となります (10.などの整数値にも小数点が付いていることを確認しましょう)。
#### np.empty関数
np.empty関数では、空、つまり要素を持たないndarrayを作ることができます。引数には、要素数を指定します。先に配列を作っておいて、後から要素を代入したい、といった場合に適しています。
###### 実行コード
```
i = np.empty(3)
print(i)
```
###### 実行結果
```
[-2.31584178e+77 -2.31584178e+77 -2.00389499e+00]
```
※ 実行結果はランダムな値となりますので、上記と異なります。
#### np.zeros関数とnp.ones関数
np.empty関数と同様に「先に配列を作っておきたい」、一方で「何かしらの数値を格納しておきたい」場合に便利なのが、np.zeros関数とnp.ones関数です。
###### 実行コード
```
j = np.zeros(3)
print(j)
k = np.ones(3)
print(k)
```
###### 実行結果
```
[0. 0. 0.]
[1. 1. 1.]
```
np.empty関数と同様に、引数で指定した数の要素を持つndarrayができており、それぞれ0, 1が格納されています。
#### np.random.rand関数
引数で指定した要素の数だけ、ランダムな値を持つndarrayを作成するのがnp.random.rand関数です。ランダムではありますが、0以上1未満の小数値になります。
###### 実行コード
```
l = np.random.rand(3)
print(l)
```
###### 実行結果
```
[0.92044152 0.27251769 0.50505127]
```
※ 実行結果はランダムな値となりますので、上記と異なります。
### np.concatenate関数
ndarrayを連結させたい場合に役立つのが np.concatenate関数です。
###### 実行コード
```
m = np.arange(4)
n = np.arange(4, 7)
o = np.concatenate([m, n])
print(m)
print(n)
print(o)
```
###### 実行結果
```
[0 1 2 3]
[4 5 6]
[0 1 2 3 4 5 6]
```
0〜3を要素に持つ配列mと、4〜6を要素に持つ配列nとをnp.concatenate関数で連結することができました。
### ndarrayの次元を変換する
#### reshape関数で1次元配列を多次元配列に変換する
冒頭での行列の例では、行データと列データの2次元配列でしたが、NumPyではどのような多次元配列でも作成することができます。ここでは、reshape関数を用いることで、ndarrayの次元を変換する方法を見ていきます。
```
(変換したいndarray).reshape(A, B, C, D, ...)
```
と記述すれば、変換したいndarrayがA×B×C×D×・・・の配列になります。変換の前後で要素数が異なる場合、エラーになってしまう点に注意してください。以下のコードを見ながら理解を深めていきましょう。
###### 実行コード
```
original = np.arange(16)
shape1 = original.reshape(4, 4)
# shape_error = original.reshape(4, 3) 要素数が違うためエラーになります
shape2 = original.reshape(4, 2, -1)
print(original)
print('+++1→2次元配列への変換+++')
print(shape1)
print('+++1→3次元配列への変換+++')
print(shape2)
```
###### 実行結果
```
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
+++1→2次元配列への変換+++
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
+++1→3次元配列への変換+++
[[[ 0 1]
[ 2 3]]
[[ 4 5]
[ 6 7]]
[[ 8 9]
[10 11]]
[[12 13]
[14 15]]]
```
reshape関数の引数として-1を与えた場合は、元のndarrayの要素数に合わせて引数の値を調整してくれます。
#### flatten関数とravel関数で多次元配列を1次元配列に変換する
多次元配列を1次元配列に変換する関数として、flatten関数とravel関数が用意されています。reshape関数でも可能ですが、1次元変換を行っていることがコードからすぐに分かるという利点があります。また、変換後の要素数を気にする必要がないということも特徴の1つです。以下のコードを見ていきましょう。
###### 実行コード
```
original = np.arange(1, 7).reshape(2, 3)
shape_flatten = original.flatten()
shape_ravel = original.ravel()
print(original)
print('+++flatten()での変換+++')
print(shape_flatten)
print('+++ravel()での変換+++')
print(shape_ravel)
```
###### 実行結果
```
[[1 2 3]
[4 5 6]]
+++flatten()での変換+++
[1 2 3 4 5 6]
+++ravel()での変換+++
[1 2 3 4 5 6]
```
どちらも、要素3個、配列2つの2次元配列が1次元配列に変換されています。2つの関数はどのような違いがあるのでしょうか?ravel関数は、データの見た目だけを1次元のように見せているので、変換後の配列を更新すると元の配列の値も更新されてしまいます。その分、処理は高速です。他方、flatten関数は元の配列からデータをコピーして配列を新しく作成しています。
### ndarrayの四則演算
ndarrayでは、非常に簡単に四則演算を行うことができます。実行コードを見てみましょう。
###### 実行コード
```
calc = np.arange(5)
print(calc)
print(calc + 2)
print(calc - 2)
print(calc * 2)
print(calc / 2)
print(calc % 2)
```
###### 実行結果
```
[0 1 2 3 4]
[2 3 4 5 6]
[-2 -1 0 1 2]
[0 2 4 6 8]
[0. 0.5 1. 1.5 2. ]
[0 1 0 1 0]
```
ndarray同士の計算も行えます。
###### 実行コード
```
calc1 = np.arange(1, 7).reshape(2, 3)
calc2 = np.arange(3, 14, 2).reshape(2, 3)
print(calc1)
print(calc2)
print(calc1 + calc2)
print(calc1 - calc2)
print(calc1 * calc2)
print(calc1 / calc2)
```
###### 実行結果
```
[[1 2 3]
[4 5 6]]
[[ 3 5 7]
[ 9 11 13]]
[[ 4 7 10]
[13 16 19]]
[[-2 -3 -4]
[-5 -6 -7]]
[[ 3 10 21]
[36 55 78]]
[[0.33333333 0.4 0.42857143]
[0.44444444 0.45454545 0.46153846]]
```
### ndarrayの反転と回転
以下の関数を用いることで、ndarrayを反転させたり、回転させたりできます。
| 関数 | 内容 |
| -------------- | :-------------------- |
| flipud(配列) | 反転 (上下) |
| fliplr(配列) | 反転 (左右) |
| rot90(配列, 1) | 反時計回りに90度回転 |
| rot90(配列, 2) | 反時計回りに180度回転 |
| rot90(配列, 3) | 反時計回りに270度回転 |
実行コードを見ながらそれぞれ確認していきましょう。
###### 実行コード
```
original = np.arange(1, 7).reshape(2, 3)
shape1 = np.flipud(original)
shape2 = np.fliplr(original)
print(original)
print(shape1)
print(shape2)
```
###### 実行結果
```
[[1 2 3]
[4 5 6]]
[[4 5 6]
[1 2 3]]
[[3 2 1]
[6 5 4]]
```
配列xの要素が上下、左右にそれぞれ反転していることが分かります。
続いて回転です。
###### 実行コード
```
original = np.arange(1, 10).reshape(3, 3)
shape1 = np.rot90(original, 1)
shape2 = np.rot90(original, 2)
shape3 = np.rot90(original, 3)
print(original)
print(shape1)
print(shape2)
print(shape3)
```
###### 実行結果
```
[[1 2 3]
[4 5 6]
[7 8 9]]
[[3 6 9]
[2 5 8]
[1 4 7]]
[[9 8 7]
[6 5 4]
[3 2 1]]
[[7 4 1]
[8 5 2]
[9 6 3]]
```
第2引数に指定した数値分、つまり(90度 × n)度ずつ要素が回転していることを確認しましょう。なお、第2引数に4以上の数値を置いてもエラーにはなりませんが、見た目の結果は1〜3のいずれかと同様になります (第2引数に4を取ると360度となり回転前と同じ並びになります)。
## Matplotlibによるグラフ描画
### Matplotlibとは
数値データをより視覚的に捉えるために、グラフや図形で表現できると便利です。Matplotlib (マットプロットリブ)は数値データを図示する機能を提供してくれるライブラリです。この章では、MatplotlibをNumPyと組み合わせることで、代表的なグラフを描画していきます。
### Matplotlibによるグラフ描画の流れ
NumPy同様、Matplotlibでもモジュールのインポートが必要になります。コードの冒頭に以下を貼り付けましょう。
```
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
```
インポートが済んでいる前提で、以下の流れでコードを書いていきます。
1. データを用意する
1. グラフを作成する (plot関数)
1. 作成したグラフを表示する
### 折れ線グラフの描画
まずは折れ線グラフから描いてみましょう。グラフ化するデータは、リストかndarrayのどちらでも可ですが、今回はndarrayで進めていきます。
###### 実行コード
```
a = np.random.rand(5)
```
データが用意できました。これをグラフ化するために、plot関数を使っていきます。
###### 実行コード
```
plt.plot(a)
```
plot関数は引数に配列を取りますので、今回は配列のaとなります。これらのコードを実行すると、グラフが作成されます。続いて、「作成したグラフを表示する」ステップになりますが、JupyterLabを使用する場合、コードの実行でそのままグラフが表示されます。実際に、次のグラフが表示されます。

なお、今回グラフ化したデータはランダムな要素を持つndarrayですので、必ずしも上図と同じ形にはなりません。
#### 横軸データの設定
先ほど作成した折れ線グラフの横軸を見てみると、0.0から4.0までの値となっていることがわかります。これは、配列のインデックスが反映されていることを示しています。横軸にもデータを指定するにはどうすればいいでしょうか。実行コードを見ていきましょう。
###### 実行コード
```
x = np.arange(1, 21, 4)
y = np.random.rand(5)
plt.plot(x, y)
```
###### 実行結果

※ np.random.rand()を再度実行したため、縦軸の数値は先ほどの折れ線グラフと異なっています。
plot関数の引数に横軸、縦軸両方のデータを渡したことにより、横軸に変数xで指定したデータが反映されていることを確認しましょう。
### グラフのスタイル、書式設定
用途に合わせたグラフを作成できるよう、スタイリングなどを行うためのキーワード引数や関数をご紹介します。
#### グラフのスタイリング
| キーワード引数 | スタイル対象 | 主な設定値 |
| -------------- | :------------- | --------------------------------------------------------- |
| linestyle | 線 | "-"(実線), "-."(一点鎖線), ":"(点線) |
| color | 線の色 | "r"(赤), "g"(緑), "b"(青), "y"(黄), "k"(黒) |
| marker | 点(マーカー) | "."(小さい丸), "o"(少し大きめの丸), "^"(上向き三角) |
※ markerはバリュエーション豊富ですので、一度[公式サイト](https://matplotlib.org/3.0.0/api/markers_api.html#module-matplotlib.markers)でどれぐらい種類があるか確認してみましょう。
試しに、これらを先述の折れ線グラフに追加してみましょう。
###### 実行コード
```
x = np.arange(1, 21, 4)
y = np.random.rand(5)
plt.plot(x, y, linestyle = ":", marker = "^", color = "g")
```
###### 実行結果

ぜひ、上表を参考に様々なスタイリングを試してみてください。
#### グラフ要素の追加
| 関数 | 内容 | 例 |
| -------- | :------------- | ------------------------------ |
| title() | グラフタイトル | plt.title("Score on the Test") |
| xlabel() | 横軸のラベル | plt.xlabel("Name") |
| ylabel() | 縦軸のラベル | plt.ylabel("Score") |
| grid() | 目盛り線 | plt.grid(True) |
どれも、Excelなどの表計算ソフトを使ってグラフ作成した際に、追加・変更したことのある事柄ではないでしょうか。実際の使用については、次の「棒グラフの描画」を具体例の題材にします。
### 棒グラフの描画
縦の棒グラフを描いてみましょう。bar関数を使います。引数は、1つ目が横軸のデータ、2つ目が縦軸のデータの順に指定します。
###### 実行コード
```
name = np.array(['taro', 'jiro', 'hanako'])
score = np.array([90, 70, 85])
plt.bar(name, score)
```
###### 実行結果

意図した通り、縦の棒グラフを描くことができました。なお、横の棒グラフを描きたい場合には、
```
plt.barh(第1引数, 第2引数)
```
に変更するだけで表現できます。試しに上記実行コードのデータを元に、横の棒グラフを描いてみてください。また、先ほどの「グラフ要素の追加」をこのグラフでやってみましょう。
###### 実行コード
```
上記コードの続き
plt.title("Score on the Test")
plt.xlabel("Name")
plt.ylabel("Score")
plt.bar(name, score)
```
###### 実行結果

現実的なグラフの描写に、ぜひ役立ててください。
### 円グラフの描画
円グラフの描画には、pie関数を使用します。pie関数では、第1引数に数値データ、第2引数にデータのラベルを渡します。
###### 実行コード
```
country = np.array(['China', 'India', 'USA', 'Indonesia', 'Pakistan', 'Others'])
population = np.array([1435, 1352, 327, 267, 212, 4001])
plt.pie(population, labels = country)
```
###### 実行結果

### 散布図の描画
散布図の描画には、scatter関数を使用します。scatter関数では、第1引数に横軸、第2引数に縦軸のデータを渡します。
###### 実行コード
```
ward = np.array(['Chiyoda', 'Minato', 'Shinjuku', 'Shibuya', 'Chuo', 'Shinagawa'])
area = np.array([11.66, 20.37, 18.22, 15.11, 10.21, 22.84])
plt.scatter(ward, area)
```
###### 実行結果

## Pandasによるデータ処理
### Pandasとは
Pandas (パンダス) とは、データ分析を効率的に行うための機能がパッケージされた、Pythonのライブラリです。Pythonだけでは骨の折れる作業も、Pandasを用いることで、高速で処理を行うことができます。
### Pandasの特長・メリット
データ分析の現場では、機械学習の大半の時間を前処理工程が占めています。この前処理には、データの読み込みやクリーニング、欠損値の補完などがあります。その前処理工程を効率的に行うために、Pandasは非常に重要なライブラリであり、機械学習エンジニアやデータサイエンティストにとって必要不可欠です。以下にPandasの特長やメリットを紹介します。
1. 異なるデータ型を1つのデータフレームで扱える
Pandasのデータフレームは、異なる型のデータを格納することができます。これは、データの前処理工程を効率的に行う上で、非常に重要なポイントです。NumPyと比較するとわかりやすいでしょう。NumPyの配列 (ndarray) では、全てのデータが単一の型でないと扱うことができません。この点において、文字列や数値データなど複数のデータ型が混在するCSVファイルの処理を行う場合、NumPyは適していません。
2. データを加工するための関数が豊富に揃っている
Pandasライブラリには、データを加工するための関数が豊富に揃えられています。例えば、機械学習の前処理工程で不可欠な欠損値の補完、文字列の数値変換、データの指定抽出など、データ加工に適した関数から、平均値や標準偏差などの演算などデータ解析に必要な関数まで、幅広くカバーされています。
3. 他のライブラリと連携できる
Pandasは、本章で学んだNumPyや、Matplotlibと連携させることができます。つまり、NumPyを用いて計算処理を行ったり、Matplotlibを用いてグラフ (2次元、3次元) を描画することができます。よって、Pandasはユーザーの幅広いニーズに応えるライブラリと言えます。本章では、PandasとNumPyの相互変換についても学習していきます。
それでは、使用方法に移っていきましょう。CSVファイルを読み込む → CSVファイルのデータを参照・抽出する → PandasのDataFrameとNumPyのndarrayを相互変換する、という流れで説明していきます。
### PandasでCSVファイルを読み込む
CSVファイルについては、前章の「テキストファイルの読み書き」で学習しましたが、簡単におさらいしましょう。CSV (Comma-Separated Values) ファイルとは、データをカンマで区切ることで構造化したテキストファイルです。異なる表計算ソフト (Microsoft Excelなど) の間でも、同じ「表」として開くことができます。本コースでの学習用に以下のファイル(scores.csv)を作成しましょう。データはコピー&ペーストしてください。
scores.csv
```
name,sex,national language,mathematics,science,geography,history,english
ichiro,male,81,72,63,54,46,37
jiro,male,72,63,54,45,36,27
saburo,male,63,54,45,36,27,18
shiro,male,54,45,36,27,18,29
goro,male,45,36,27,18,29,30
hanako,female,36,27,18,29,30,41
akiko,female,27,18,29,30,41,52
yoko,female,18,29,30,41,52,63
eri,female,29,30,41,52,63,74
yuri,female,30,41,52,63,74,85
```
このCSVファイルには、生徒の氏名別、科目別のテスト結果が書き込まれています。念の為、科目名を以下に記載します。
```
national language: 国語
mathematics: 数学
science: 理科
geography: 地理
history: 歴史
english: 英語
```
作成したscores.csvは、スムーズに読み込めるよう、ノートブックファイル(~.ipynb)と同じディレクトリにアップロードしてください。
まずはモジュールのインポートです。後ほど使用するNumPyと併せて、1行目でPandasモジュールをインポートしましょう。
###### 実行コード
```
import pandas as pd
import numpy as np
```
PandasでのCSVファイルの読み込みには、read_csv関数を使います。ここでは、score_dataという名前で変数を置くことにします。併せて、score_dataのデータ型も参照してみましょう。
###### 実行コード
```
score_data = pd.read_csv("scores.csv")
print(type(score_data))
```
###### 実行結果
```
<class 'pandas.core.frame.DataFrame'>
```
※ read_csv関数の行については、エラーさえ発生していなければ実行結果には何も表示されません。
score_dataのデータ型は、DataFrame です。これはPandasの2次元配列のデータ型です。ちなみに、1次元配列の場合は Series になります。
### CSVファイルのデータを参照・抽出する
#### データの表示
読み込んだscores.csvを表示してみましょう。
###### 実行コード
```
print(score_data)
```
###### 実行結果

※ 画面幅の関係で「history」から改行されています。
scores.csvが表示されました。今回はprint()を用いましたが、Pandasではより見やすく表を出力することができます。
###### 実行コード
```
score_data
```
###### 実行結果

このようにPandasは、自動でJupyterLabと連携してスタイリングされた表を出力してくれます。scores.csvはデータ量の少ないファイルですが、実際の業務の現場では膨大なデータ量のCSVファイルを扱うことがあります。その場合、出力される表が途中で省略されてしまいます。先頭の5件だけ、あるいは末尾の5件だけ表示できる、head関数、tail関数もこの機会にご紹介します。
###### 実行コード
```
score_data.head()
```
###### 実行結果

###### 実行コード
```
score_data.tail()
```
※ それぞれ別々に実行してください。
###### 実行結果

CSVファイルが適切に読み込めたかどうかの確認をしたい場合に使用するとよいでしょう。
#### データの一部を抽出する
##### 列名を指定してスライスする
以下の記法を用いることで、列名を指定してスライスすることができます。
```
配列名.loc[]
```
###### 実行コード
```
score_data.loc[0, "name"] # "name"列の0行目
```
###### 実行結果
```
'ichiro'
```
###### 実行コード
```
score_data.iloc[0:2, 0:3] # 0〜2行目の0〜3列
```
###### 実行結果

###### 実行コード
```
score_data.loc[:10:3, ["name", "mathematics", "history"]] # 10行目、10列までを増分3で
```
###### 実行結果

##### 位置を指定してスライスする
以下のいずれかの記法を用いることで、データの位置を指定してスライスすることができます。
```
配列名.iloc[行の位置指定][列の位置指定]
あるいは
配列名.iloc[行の位置指定, 列の位置指定]
```
###### 実行コード
```
score_data.iloc[0, 0]
# 0行目の0列
# score_data.loc[0, "name"]と同じ結果になる
```
###### 実行コード
```
score_data.iloc[0:2, 0:3]
# 0〜1行目の0〜2列
# score_data.loc[0:1, ["name", "sex", "national language"]]と同じ結果になる
```
###### 実行コード
```
score_data.iloc[:11:3, :11:3]
# 10行目、10列までを増分3で
# score_data.loc[:10:3, ["name", "mathematics", "history"]]と同じ結果になる
```
loc と iloc で、行の出力範囲の終了位置の指定が少し異なっています。loc では終了位置を含んだ範囲指定、iloc では「終了位置 - 1」での範囲指定となります。
##### 条件式を利用して抽出する: query関数
query関数を用いることで、特定の条件を指定してデータを抽出することができます。記法は以下の通りです。
```
配列名.query(条件式)
```
「英語の点数が40点以上」の生徒を抽出してみます。
###### 実行コード
```
score_data.query("english >= 40")
```
###### 実行結果

文字列型のデータを抽出したい場合は、クォーテーションの付け方に注意が必要です。条件式全体をダブルクォーテーションで囲った場合は抽出したい文字列値をシングルクォーテーションで、逆に条件式全体をシングルクォーテーションで囲った場合は抽出したい文字列値をダブルクォーテーションで囲ってください。
###### 実行コード
```
score_data.query("sex == 'male'")
```
###### 実行結果

また、複数の条件を指定することも可能です。
「英語の点数が30点以上」の「男子生徒」を抽出してみましょう。
###### 実行コード
```
score_data.query("english >= 30 and sex == 'male'")
```
###### 実行結果

### DataFrameとndarrayを相互変換する
冒頭の「Pandasの特長・メリット」でご説明した通り、PandasはNumPyと連携することができるため、行いたい処理内容に合わせてライブラリを選択することができます。それを可能にするため、PandasのDataFrameとNumPyのndarrayを相互に変換する方法を学習していきましょう。
##### DataFrameからndarrayへの変換
DataFrameのオブジェクトが持つ values プロパティを参照します( 変数は「ndarrayへ変換」したことをわかりやすくするために「nd」を付しています )。併せて、変換後のデータ型も参照しておきましょう。
###### 実行コード
```
nd_score_data = score_data.values
print(type(nd_score_data))
print(nd_score_data)
```
###### 実行結果

意図した通り、データ型はndarrayになっています。なお、valuesプロパティには列見出しの情報が含まれていません (実行結果を確認してみましょう) 。列見出しを取得したい場合には以下を実行しましょう (今回は、次項の「2. ndarrayからDataFrameへの変換」でデータ情報と列見出しを使うので、必ず実行するようにしてください)。
###### 実行コード
```
nd_score_columns = score_data.columns
print(type(nd_score_columns))
print(nd_score_columns)
```
###### 実行結果
```
['name' 'sex' 'national language' 'mathematics' 'science' 'geography'
'history' 'english']
```
##### ndarrayからDataFrameへの変換
反対に、ndarrayからDataFrameへ変換してみましょう。ndarrayから変換して、DataFrameのオブジェクトを作るには pd.DataFrame() を使います。pd.DataFrame() は data と columns というキーワード引数を取ることができます。data には参照するデータを、columns には列見出しの情報をndarray形式で指定します。
###### 実行コード
```
df_score_data = pd.DataFrame(data = nd_score_data, columns = nd_score_columns)
print(type(df_score_data))
df_score_data
```
###### 実行結果

データ型がDataFrameになっていることを確認しましょう。
## まとめ
本章では、Pythonをより便利に活用するためのNumPy, Matplotlib, Pandasを学習しました。これからPythonエンジニアを目指す方は、実際の業務の現場で使用する可能性も大いにあるこれらのライブラリにどんどん触れていただき、使いこなせるようになっていきましょう。