Python Pandas基礎① -DataFrameとSeries-

### 初めに
pythonのpandasについて初学者なりにまとめたいと思います。
学習に使っているのはこちらのキノコードです。

https://kino-code.com/category/introductory-course-pandas/

### pandasとは
データ解析を支援する機能を提供するライブラリです。
下記に当てはまる際に利用するのがおすすめです。

>毎日なんらかの情報を集計・分析する必要がある人
組織の課題を発見・解決したい人
株価や為替の相場、財務データの分析をしたい人
さまざまなデータを統合して相関関係を見出したい人

https://aidemy.net/magazine/618/

### できること
csv、Excelファイルを読み取る
列や行の操作
計算
フィルターで抽出
グループにまとめる
表のマージ
欠損値の操作
時系列データの取り扱い
グラフの描写
etc...

ExcelやSQLができることはある程度こなすことができる。
pandasは人工知能開発や、データ分析をする際のデータの前処理に使われることが多いです。

### データ構造
#### DataFrame
簡単に言うとExcelのシートのように行と列で成り立っている2次元配列です。

>2次元の大きさが変更できる表形式データである
列ごとに様々な形式のデータが格納される。
各次元(行と列)方向にはラベリングされた軸(axes)が存在する。
各次元(行と列)方向に数学的な操作を行うことができる。
Seriesオブジェクトを辞書のような形式で格納できるオブジェクトと考えることができる。

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html

### Series

DataFrameから一列取り出した際にできる一次元配列で、Pythonで言うリストにindexを付けたようなものです。

>PandasにおけるSeriesはnumpy.ndarrayの1次元配列にインデックス(ラベル)を付けたものに相当し、複数のSeriesを組み合わせることでDataFrameになります。DataFrameから列や行を抽出することでもSeriesを取得することができます。

https://biotech-lab.org/articles/11919#Series

### 実際に使う
今回はJupyterLabを利用します。
JupyterLabについては以前まとめたので、もしよろしければご覧ください。

https://qiita.com/y-matsunaga/items/2c7efdae8777f15059e0

まず初めにpandasをimportして、as pdとします。
asに続いた文字がpandasとして扱われます。

### DataFrameについて

#### 2次元リストを使った作成方法

pd.DataFrame([[データ1],[データ2], [データ3]])の形式で値を渡します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/593ebea0-f657-90cd-3c74-b0ad9b68e48b.png)

index(行)とculumns(列)に情報がないので0から連番でindexが振られています。
情報を与えるようにコードを編集します。
値を渡したリストの後ろにカンマで区切ってindexとcolumnsを指定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/06436cdb-3aac-414e-3973-2612f9938bf0.png)

#### Numpy配列を使った作成方法
データフレームのデータを、Numpy配列で作成することもできます。
NumPy配列とは、NumPyライブラリ独自の配列の型（ndarray型）のことです。
Numpyライブラリをインポートし、npで使用できるようにasで定義をします。
Numpy配列でデータフレームを作成する場合は、配列の各要素（内側の配列）を1行ごとのデータとして考えます。
例えば、1行目はSato,34,Tokyoで1つの配列にします。
文字列を指定する場合には、シングルクォーテーションで囲むことを忘れないようにしましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/cf977aa9-c89d-ccec-253e-b513d83eaf88.png)

#### インデックス、カラム参照
DataFrameクラスのindex属性、columns属性、values属性で、インデックス、カラム、データの値を取得することができます。
dtypeはデータ型を示しています。
Pandasにおいては、各要素が文字列型のデータはstr型ではなく、object型となることを覚えておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/8d159824-958d-c44c-bcf9-7b5f9d94442c.png)

#### 辞書型を使った作成方法
辞書型で指定することもできます。
カラムとデータを辞書型でしてするには、辞書のキーにカラム、値にデータを指定します。indexについては別途引数で指定する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/8ac2a5be-8066-6c6d-f218-dda710954db0.png)

#### インデックス、カラムの操作
データフレームのカラムとインデックスの値を変更するには、2通りの方法があります。
1つ目は、解答例1のようにindex属性とcolumns属性を使用する方法です。
2つ目は、解答例2のようにDataFrameクラスの引数columns、引数indexを指定する方法です。
なお、インデックスとカラムを指定せずに、DataFrameクラスでデータフレームを作成すると、それぞれの値が0から自動的に附番されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/807b3bb4-21af-1fc8-ff84-52cb896dd725.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/a867ef32-4b2c-5caa-12d1-1fa9a3e3df0d.png)

#### renameメソッドでカラム名変更
renameメソッドを使用すると、データフレームのカラムやインデックスの値を変更することができます。
インデックスを変更する場合は、renameメソッドの引数indexに、辞書型でインデックスの値を指定します。
辞書のキーに変更するインデックスの値、辞書の値に変更後のインデックスの値を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/a2e05d24-5183-c8d8-ec9b-dacb137e62ab.png)

#### 列を取得
データフレームからカラムをデータフレームで取得するには、角括弧内にリスト型でカラム名を指定します。
下記のように記述します。
データフレームオブジェクト[['カラム名']]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/d895b87f-6178-254e-8a0c-01563c2411aa.png)

#### locプロパティで行を取得
データフレームから指定の行をデータフレームとして取得するには、locプロパティの角括弧内にリスト型でインデックス名を使用します。
下記の通り記述します。
データフレームオブジェクト.loc[['インデックス名']]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/1586add3-2bc1-0a50-4eb9-06656ab76cca.png)

#### locプロパティで行と列を指定して取得
locプロパティの角括弧内でインデックスとカラムの両方を指定すると、そのインデックスとカラムにおける要素の値をシリーズで取得することができます。
角括弧内の第1要素にインデックス名、第二要素にカラム名を指定します。

複数のカラムとインデックスを指定することも可能です。
今回は、要素の28は'B'行、要素の22は'D'行にあるため、2つのインデックスをリストで指定します。
データフレームオブジェクト.loc[['インデックス名1','インデックス名2'],'カラム名']
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/6f0ef65c-af67-45d8-2e67-9b82f27c173a.png)

#### locプロパティで列を取得
locプロパティの角括弧内でインデックスとカラムの両方を指定すると、そのインデックスとカラムにおける要素の値を取得することができます。
角括弧内の第1要素にインデックス名、第二要素にカラム名を指定します。
データフレームオブジェクト.loc['インデックス名','カラム名']

locプロパティでは、スライスを使用することもできます。
スライスとは、リストや辞書のようなデータ型が、順番に並べられたものを取り出したいときに使う操作です。
データフレームのインデックスやカラムに対しても、同様に使用することができます。
スライスにおけるコロンは、全てのデータという意味です。
この問題では、'C'行と'E'行の全てを取得するため、カラムは全てのデータを指定する必要があります。
また、複数のインデックスを指定する場合には、インデックス名はリスト型で指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/44091c3e-b9e8-7e18-3979-ed5439001aa5.png)

#### locプロパティでデータ操作
locプロパティを使用すると、データフレームのデータを抽出することができます。
角括弧内の第1要素にインデックス名、第二要素にカラム名を指定します。
データフレームオブジェクト.loc['インデックス名','カラム名']

locプロパティでは、スライスを使用することもできます。
スライスとは、リストや辞書型のようなデータが順番に並べられたものを取り出したいときに使う操作です。
データフレームのインデックスやカラムに対しても、同様に使用することができます。
全てのデータを指定する場合には、コロンを一つ記述します。
この問題では、行の指定は'B'行から'D'行のため、それぞれのインデックスの間にコロンを記述します。
続いて、列の指定は'No.1'列から'No.2'列のため、それぞれのカラムの間にコロンを記述します。

なお、locプロパティに似たプロパティで、ilocプロパティがあります。
2つのプロパティは、インデックス参照でデータを抽出できる点は同じですが、下記の点において異なります。
locプロパティ：角括弧内にインデックス・カラム（行・列のラベル）を指定して抽出
ilocプロパティ：角括弧内に行番号・列番号を指定して抽出
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/9e976ff4-86f3-022f-6d07-9e2d100bc372.png)

#### locプロパティでデータ変更
ilocプロパティでは、角括弧内で行番号・列番号を指定して、データを抽出することができます。
get_locメソッドでは、引数にカラム名やインデックス名を渡すことで、その行番号・列番号を取得することができます。
応用として、この問題では、ilocプロパティで角括弧内に指定する行番号・列番号を、get_locメソッドで取得する、という方法をとっています。
まず、get_locメソッドの引数に、要素の1のインデックス名'B'、カラム名'No.2'を渡して、列番号と行番号を取得します。
次に、ilocプロパティで、取得した列番号と行番号でデータを抽出します。
最後に、代入演算子の=（イコール）を使用して、変更後のデータを指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/8f2f1955-8ac8-25fe-40b0-31f082ba88b9.png)

#### get_locメソッドで行番号取得
行番号・列番号を取得するには、get_locメソッドを使用します。
行番号の場合、index属性の後にget_locメソッドを記述します。
続いて、get_locメソッドの引数に取得したい行のインデックス名を指定します。
なお、行番号は0から開始するため、'idx03'行の行番号は2です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/c563e13f-d5a3-cea9-3f92-07c653095f6b.png)

#### get_locメソッドで列番号取得
行番号・列番号を取得したい場合には、get_locメソッドを使用します。
列番号の場合、columns属性の後にget_locメソッドを記述します。
続いて、get_locメソッドの引数に取得したい列のカラムを指定します。
なお、列番号は0から開始するため、'idx02'行の行番号は1です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/7878a28c-2a6a-3461-4fdb-39d4f8e69731.png)

#### データ型を調べる
指定の列のみデータ型を確認したい場合には、データフレームオブジェクトに角括弧で列を指定して、dtypeプロパティを記述します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/ea8c19d3-4512-aa1b-a4fb-7ec59b7fa73d.png)

#### 行数・列数取得
shapeプロパティを使用すると、データフレームの行数と列数をタプルで取得することができます。
行数と列数のいずれかを取得したい場合には、タプルの要素をインデックスで指定することにより、取得することができます。
行数は第1要素なので、インデックスは0を指定します。（解答例1）
また、組み込み関数のlen関数を使用することも可能です。
データフレームをlen関数で実行すると、行数を取得することができます。（解答例2）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/c41c5338-bc9d-6349-b5af-53baeb8aa22d.png)

### Seriesについて

#### リストを使ったSeries作成方法
Seriesオブジェクトを作成するには、Seriesクラスを使用します。
Seriesクラスの引数に、データを指定します。
この問題のように、データにはリストを使用することができます。
リストでシリーズを作成する場合は、リストの各要素を、1行ずつのデータとして考えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/af656a4b-08a3-a5fc-3506-8ae44d916fe8.png)

#### Numpyを使ったSeries作成方法
Seriesオブジェクトを作成するには、Seriesクラスを使用します。
Seriesクラスの引数にデータを指定します。
この問題では、Numpyライブラリのlincpace関数を使用してデータを作成します。
したがって、まずNumPyライブラリをインポートし、npで使用できるようにasで定義します。
NumPyとは、高水準の数学関数や多次元配列を高速に計算ができるライブラリのことです。

指定した区間で、要素数を指定して配列を作成するには、NumPyライブラリのlinspace関数を使用します。
第1引数に区間の開始値を渡します。
第二引数に区間の終了値を渡します。
第3引数に要素数を指定します。
なお、arange関数とは異なり、linspace関数では終了値も配列の値に含まれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/1c66e3ae-cc66-b813-ce7f-f319222d46c3.png)

#### データ型の取得
指定した区間で等間隔の配列を得るには、NumPyライブラリのarange関数を使用します。
第1引数に区間の開始値を渡します。
第二引数に区間の終了値を渡します。
第3引数に各要素の歩数（増分）を指定します。
0.2を指定すると、各要素の値が0.2ずつ増えていくことになります。
なお、arange関数で作成する配列の値に開始値は含まれますが、終了値は含まれません。

シリーズのデータ部分のデータ型を取得するには、dtypes属性を使用します。
この問題のシリーズのデータはすべて小数のため、データ型はfloat64です。
なお、整数のデータ型はint64、文字列のデータ型はobjectです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/9a7e85a2-a7a0-7013-ec40-9c9aa1545861.png)

#### index取得
シリーズのインデックスを設定するには、2通りの方法があります。
1つ目は、解答例1のようにindex属性を使用する方法です。
2つ目は、解答例2のようにSeriesクラスの引数indexを使用する方法です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/1412d0b9-3cef-83dd-c90e-cb4102ae4495.png)

#### 辞書型を使ったSeries作成方法
Seriesオブジェクトを作成するには、Seriesクラスを使用します。
Seriesクラスの引数にデータを指定します。
辞書でシリーズを作成する場合は、辞書のキーがシリーズのインデックスとなり、辞書の値がシリーズの要素の値となります。

シリーズのインデックスの値を変更するには、index属性を使用します。
続いて、代入演算子の=（イコール）を使用して、変更後のデータを指定します。
変更後のデータが複数ある場合には、リスト型で指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/af1ce3b2-459e-3217-e03d-88092440af13.png)

#### 値の取得
シリーズの要素の値を取得するには、角括弧の中にインデックス名または行番号を記述します。
・シリーズの変数名['インデックス名']（解答例1）
・シリーズの変数名[行番号]（解答例2）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/bf32b1d1-8c3f-c2f7-6d28-decc7ceae2fe.png)

#### 複数の値の取得
条件を指定してシリーズの値を取得するには、下記のように、角括弧の中に関係演算子（比較演算子）で条件式を記述します。
シリーズオブジェクト[a > b]
指定の数値が80より大きいかを判定するには、>（大なり）を使用します。
ここでTrueが返された値のみ取得されます。 関係演算子については、下記の通りです。
a > b：aはbより大きい
a < b：aはbより小さい
a >= b：aはb以上である（bの値も含む）
a <= b：aはb以下である（bの値も含む）
a == b：aとbは等しい
a is b ：aとbは等しい
a != b：aとbは等しくない
a is not b：aとbは等しくない
a in b：a はb に含まれる
a not in b ：a はb に含まれない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/02403198-035b-80ca-2d99-3a4c6b720289.png)

#### 要素数の取得
シリーズの要素数取得には、size属性とlen関数の他に、shapeプロパティを使用する方法もあります。
shapeプロパティは、一般的にはデータフレームの行数・列数をタプルで取得するプロパティです。
シリーズの要素数は行数と等しいため、この問題のように、シリーズの要素数取得としても使用することもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/b8f910d4-c731-2adf-8f26-fc96657778d4.png)

#### Seriesの四則演算
シリーズの全ての要素に対して演算を行うには、Seriesオブジェクトに対して算術演算子を使用します。
足し算には算術演算子の+（プラス）を使用します。
シリーズの各要素の平均値を取得するには、meanメソッドを使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/6fbfccfb-5cc3-83eb-344f-574b3414202c.png)

#### Series同士の計算
算術演算子を使用して、シリーズの各要素同士の演算を行うことができます。
2つのシリーズのインデックス名が一致する場合は、演算が実行されます。
2つのシリーズのインデックス名が一致しない場合は、NaN（欠損値）が返されます。

欠損値の要素を他の値で置換するには、fillnaメソッドを使用します。
fillnaメソッドの引数に、置換する値を渡します。

シリーズの要素の平均値を取得するには、meanメソッドを使用します。
今回は、シリーズの各要素同士の掛け算の結果から、平均値を取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/d6bb658c-beff-dad8-b3aa-3428981433e0.png)

#### 欠損値確認
シリーズの各要素が欠損値であるか否かを取得するには、inull関数またはSeriesクラスのisnullメソッドを使用します。
さらに、isnullで取得されたTrueまたはFalseの判定結果からTrueの数を取得するには、sumメソッドを使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/3335b847-1c5f-d4fe-cbd1-0ba4be2dc116.png)

#### DataFrameからSeries取得
データフレームからカラムをシリーズで取得するには、2通りの方法があります。
・解答例1では、角括弧でカラム名を指定します。
下記のように記述します。
データフレームオブジェクト['カラム名']
・解答例2では、values属性としてカラム名を指定します。
下記のように記述します。
データフレームオブジェクト.カラム名
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/6d46f2ba-3722-36a4-0ff1-68f1efbb87b8.png)

#### 時系列データ
時系列データを取得するには、date_range関数を使用します。
第1引数に、時系列データの開始値を指定します。
第2引数に、時系列データの終了値を指定します。（解答例2）
引数periodで、生成する時系列データの数を指定することもできます。（解答例1）
続いて、引数freqで生成するデータの周期を指定します。
引数freqに渡す値は、主に下記の通りです。
D:日
W:週
MS:月の開始日（1日）
M:月の最終日
なお、date_range関数については、こちらの1分動画で詳しく解説していますので、是非ご参考ください。

https://www.youtube.com/watch?v=ZBkYLg4kbo0

Seriesオブジェクトを作成するには、Seriesクラスを使用します。
Seriesクラスの引数にデータを指定します。

### 終わりに
覚えることがたくさんありますが、今回はDataFrameとSeriesに絞りました。
基本のこの２つを抑えていないと先に進めないと思うのでしっかり覚えておきたいです。
[キノコード](https://kino-code.com/)ではもっと細かい部分まで説明がありますので利用してみてください。