(2021/4/23に更新しました)
今回は勉強中のデータ分析に利用するためのツール「Pandas」の内容について、勉強したことを忘れないように備忘録として残しておきます。
もし、Pandasの設定であれどうやるんだっけ?って時の参考になればと思います。
可能な限り実行しながら実例を記載してます。
環境
- Windows10
- Python 3.8.1
- jupyter 1.0.0
- jupyter-client 6.1.7
- jupyter-console 6.2.0
- jupyter-core 4.7.0
- jupyterlab-pygments 0.1.2
- pandas 1.1.5
事前準備
Pandasを利用するときは初めに「pandas」モジュールをインポートしてください。
モジュール:import pandas as pd
各種設定
実行した結果はすべてJupyter Notebookの出力結果をのせています。
Seriesで1次元データを作成する
Seriesを使うことで1次元データを作成できます。
1次元データを作成するには「Series」を使います。
使い方
pd.Series([任意の数字])
ser = Series.array([10, 20, 33]) ser
結果
0 1 1 2 2 3 dtype: int64
1次元のデータができましたね。
DataFrameで2次元データを作成する
DataFrameを使うことで2次元データを作成できます。
2次元データを作成するには「DataFrame」を使います。
使い方
pd.DataFrame([[hoge1, hoge2, hoge3],
hoge4, hoge5, hoge6]])
df = pd.DataFrame([[10, '愛', True],[40, '勇気', False],[50, '希望', False]]) df
結果
0 1 2 0 10 愛 True 1 40 勇気 False 2 50 希望 False
こんな感じで2次元のデータができます。実際のJupyter Notebookだともっとかっこよく表示されます。
DataFrameの行列に名前を付ける
さっき作ったDataFrameの行列に名前を付けてみます。
行に名前を付けるには「index」を使います。
列に名前を付けるには「columns」を使います。
使い方
- 行
名前を付けたい変数名.index = [1行目の名前, 2行目の名前, 3行目の名前,・・・]
- 列
名前を付けたい変数名.colums= [1列の名前, 2列の名前, 3列の名前,・・・]
df.index = ["今日", "明日", "明後日"] df.columns= ["昨日", "3日前", "1週間前" ] df
結果
昨日 3日前 1週間前 今日 10 愛 True 明日 40 勇気 False 明後日 50 希望 False
こんな感じで名前を付けることができます。
DataFrameの値を取り出す
続いて、DataFrameの中身のデータを取り出してみます。
取り出す場合は「リスト型で指定」するか、「loc」メソッドを使います。
使い方
- リスト型で指定
取り出したい変数名[値を指定]
列を取り出したい場合は、「index」番号を指定する。
行を取り出したい場合は、「columns」名を指定する。
df.[:1] df df.["3日前"] df
- locメソッドで指定
取り出したい変数名.loc[行の値を指定, 列の値を指定]
df.loc['今日', :] df.loc[:, '3日前'] df.loc[:, ['3日前', '1週間前']]
結果
- リスト型結果
昨日 3日前 1週間前 今日 10 愛 True 今日 愛 明日 勇気 明後日 希望 Name: 3日前, dtype: object
始めの「df.[:1]」では、1行目を取り出しています。
「df.[“3日前”]」では、「3日前」の列を取り出しています。
- locメソッド結果
昨日 10 3日前 愛 1週間前 True Name: 今日, dtype: object 今日 愛 明日 勇気 明後日 希望 Name: 3日前, dtype: object 3日前 1週間前 今日 愛 True 明日 勇気 False 明後日 希望 False
始めの「df.loc[‘今日’, :] 」では、「今日」の行を取り出しています。
「df.loc[:, ‘3日前’] 」では、「3日前」の列を取り出しています。
「df.loc[:, [‘3日前’, ‘1週間前’]] 」では、「3日前」と「1週間前」の列を取り出しています。
こんな感じで、DataFrameの値を取り出すことが可能です。
ちなみに、インデックス番号でlocのような取り出し方をしたい場合は「iloc」を使うことで実現できます。
例:df.iloc[:, :1]
ファイルを読み込みや書き込みをする
pandasで外部ファイルを読み込むには「read_●●」を使います。
書き込みの場合は「to_●●」を使います。
使い方
読み込み | 書き込み | |
CSV | pd.read_csv(ファイルの保存場所) | pd.to_csv(ファイルの保存場所) |
Excle |
pd.read_excel(ファイルの保存場所) |
pd.to_excel(ファイルの保存場所) |
HTML | pd.read_html(取得したいURL) | pd.to_html(取得したいURL) |
バイナリ | pd.read_pickle(ファイルの保存場所) |
pd.to_pickle(ファイルの保存場所) |
ここでは例としてCSVの読み取りを取り上げます。
df = pd.read_csv("test.csv") df
結果
日付 歩数 摂取カロリー 0 2017-04-01 5439 2500 1 2017-04-02 2510 2300 2 2017-04-03 10238 1950
こんな感じでCSVの中のデータを取得してくれます。
条件で抽出する
演算子を使ってある条件に合ったものだけを抽出します。
使い方
- 抽出元データ:演算子:条件
以下のような2次元データがあるとします。
df = pd.DataFrame([[40, "a", True],[20, "b", False],[30, "c", False]]) df.index = ["01", "02", "03"] df.columns = ["A", "B", "C"]
A B C 01 40 a True 02 20 b False 03 30 c False
この時に、A列が「30以上のもの」ものを判定してみます。
df["A"] >= 30
結果
01 True 02 False 03 True Name: A, dtype: bool
このように、Bool形式で抽出されます。
「30以上のもの」だけを取り出すことも可能です。その場合は、一度変数へ格納します。
df_over30 = df[df["A"] >= 30] df_over30
A B C 01 40 a True 03 30 c False
ちゃんとA列が30以上のものだけが抽出できました。
時系列データを作成する
1カ月と1年分の日付を生成してみる
pandasで時系列データを作成には「date_range」を使います。
使い方
- pd.date_range(start=開始日時, end=終了日時)
endの代わりにperiodsオプションで日数指定することもできます。
- pd.date_range(start=開始日時, periods=日数)
2021年1ヵ月と1年分のデータを作成してみます。
dates_mon = pd.date_range(start="2021-01-01", end="2021-01-31") dates_mon
dates_year = pd.date_range(start="2021-01-01", periods=365) dates_year
結果
DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04', '2021-01-05', '2021-01-06', '2021-01-07', '2021-01-08', ・・・ '2021-01-25', '2021-01-26', '2021-01-27', '2021-01-28', '2021-01-29', '2021-01-30', '2021-01-31'], dtype='datetime64[ns]', freq='D')
DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04', '2021-01-05', '2021-01-06', '2021-01-07', '2021-01-08', '2021-01-09', '2021-01-10', ... '2021-12-22', '2021-12-23', '2021-12-24', '2021-12-25', '2021-12-26', '2021-12-27', '2021-12-28', '2021-12-29', '2021-12-30', '2021-12-31'], dtype='datetime64[ns]', length=365, freq='D')
こんな感じで日付を作成することができます。
生成した日付ごとにランダムなデータを入れてみる
次にさっき作った日付データにランダムな数字を入れてみます。
ランダムな数字を入れるには「numpy」と「PandasのDaraFrame」を使います。
使い方
- pd.DataFrame(npのrandom関数, index=日付データ, columns=カラム名)
import numpy as np dates_mon = pd.date_range(start="2021-01-01", end="2021-01-31") df = pd.DataFrame(np.random.randint(1, 31, 31), index=dates_mon, columns=["乱数"]) df
今回のランダムな数字は「1~30(最大値のマイナス1)」までを作成しています。
結果
乱数 2021-01-01 3 2021-01-02 27 2021-01-03 21 ・ ・ 2021-01-29 12 2021-01-30 1 2021-01-31 26
こんな感じで、一日ごとにランダムな数字を入れることができました。
欠損値の処理をする
欠損値とは、NaNと表示されるデータが入っていない項目のことです。
pandasで欠損値の処理のするには「dropna()」や「fillna()」を使います。
dropnaの使い方
dropnaとは、欠損値が入っている行を削除するメソッドです。
使い方
- 欠損処理したい変数.dropna()
以下CSVデータがあるとします。
A,B,C 1,2,3 ,5,6 high,middle,low 100,,200
df = pd.read_csv('csv_sample.csv') df
現在の結果
A B C 0 1 2 3 1 NaN 5 6 2 high middle low 3 100 NaN 200
df_drop = df.dropna() df_drop
結果
A B C 0 1 2 3 2 high middle low
NaNが入っていた1行目、3行目が削除されました。
列を削除したい場合は引数に「axis=1」を指定します。
以下のような感じになります。「df.dropna(axis=1)」
C 0 3 1 6 2 low 3 200
fillnaの使い方
fillnaとは、欠損値が入っているところに任意の値を挿入するメソッドです。
使い方
- 欠損処理したい変数.fillna()
以下CSVデータがあるとします。
A,B,C 1,2,3 ,5,6 high,middle,low 100,,200
df = pd.read_csv('csv_sample.csv') df
現在の結果
A B C 0 1 2 3 1 NaN 5 6 2 high middle low 3 100 NaN 200
fillnaを使って、欠損値に「0」を入れます。
df_fillna = df.fillna(0) df_fillna
結果
A B C 0 1 2 3 1 0 5 6 2 high middle low 3 100 0 200
このように、欠損値の場所に「0」が挿入されました。
ちなみにfillnaの引数に「method=’ffill’」を与えることで、一つ前(上)の値を欠損値に入れることもできます。
以下のような感じになります。「df.fillna(method=’ffill’)」
A B C 0 1 2 3 1 1 5 6 2 high middle low 3 100 middle 200
一つ下の値を使いたい場合は「backfill」というメソッドもあります。
fillnaで欠損値に中央値などを使う
fillnaでは他にも、欠損値に中央値などを入れることもできます。
使い方
- 欠損処理したい変数.fillna(欠損処理したい変数.median())
以下CSVデータがあるとします。
A,B,C 1,2,3 ,5,6 high,middle,low 100,,200
pandasで表示した時の結果
1 2 3 0 NaN 5.0 6 1 7.0 8.0 9 2 100.0 NaN 200
fillnaを使って、欠損値に「中央値」を入れます。
df_fillna = df.fillna(df.median()) df_fillna
結果
1 2 3 0 53.5 5.0 6 1 7.0 8.0 9 2 100.0 6.5 200
NaNの部分に中央値が挿入されました。
中央値以外に平均値や最頻値でも欠損を補完することができます。
- 平均値:mean()
- 最頻値:mode()
基本統計量を使う
pandasでは基本統計量の出力ができます。
使い方
- 計算したい変数.loc[:, 取得したい列].統計メソッド
※統計量をまとめて出力するの場合は以下になります。 - 計算したい変数.describe()
統計メソッドには以下の種類があります。
内容 | 統計メソッド |
最大値 | max() |
最小値 | min() |
最頻値 | mode() |
平均値 | mean() |
中央値 | median() |
標本標準偏差 | std |
母集団の標準偏差 | std(ddof=0) |
件数 | count() |
統計量をまとめて出力する | describe() |
以下CSVデータがあるとします。
1,2,3 40,50,60 70,80,90 100,200,300
pandasで表示した時の結果
1 2 3 0 40 50 60 1 70 80 90 2 100 200 300
今回は、標本標準偏差の「std」と統計量をまとめて表示できる「describe」を例として取り上げます。
- 標本標準偏差
df_std = df.loc[:, '2'].std() df_std
- 統計量をまとめて表示
df_describe = df.describe() df_describe
結果
- 標本標準偏差結果
79.37253933193772
- 統計量をまとめて表示結果
1 2 3 count 3.0 3.000000 3.000000 mean 70.0 110.000000 150.000000 std 30.0 79.372539 130.766968 min 40.0 50.000000 60.000000 25% 55.0 65.000000 75.000000 50% 70.0 80.000000 90.000000 75% 85.0 140.000000 195.000000 max 100.0 200.000000 300.000000
相関係数を出力する
カラム間データの相関係数を「corr」を使って出力できます。
使い方
- 計算したい変数.corr()
以下CSVデータがあるとします。
1,2,3 40,50,60 70,80,90 100,200,300
pandasで表示した時の結果
1 2 3 0 40 50 60 1 70 80 90 2 100 200 300
相関関係の結果を出力してみます。
df.corr()
結果
1 2 3 1 1.000000 0.944911 0.917663 2 0.944911 1.000000 0.997176 3 0.917663 0.997176 1.000000
データの連結をする
データを連結するには「concat」を使います。
列方向にデータを連結する
列方向にデータを連結します。
使い方
- pd.concat([連結する変数1, 連結する変数2], axis=1)
列方向に結合する場合は「axis=1」に指定します。
以下2つのCSVデータがあるとします。
1,2,3 40,50,60
70,80,90 100,200,300
pandasで表示した時の結果
1 2 3 0 40 50 60 70 80 90 0 100 200 300
これらを列方向に連結します。
1つ目のデータが「df1」、2つ目のデータが「df2」に入ってます。
df_merge = pd.concat([df1, df2], axis=1) df_merge
結果
1 2 3 70 80 90 0 40 50 60 100 200 300
こんな感じで結合されます。
行方向にデータを連結する
行方向にデータを連結します。
使い方
- pd.concat([連結する変数1, 連結する変数2], axis=0)
行方向に結合する場合は「axis=0」に指定するか、デフォルトが「0」なので指定しなくても行方向に結合します。
df_merge = pd.concat([df1, df2], axis=0) df_merge
結果
1 2 3 70 80 90 0 40.0 50.0 60.0 NaN NaN NaN 0 NaN NaN NaN 100.0 200.0 300.0
同じカラムがないのでデータがない部分は「NaN」が表示されています。
カラムを同じにすると次のようになります。
※「70,80,90」を「1,2,3」に値を変更しました。
1 2 3 0 40 50 60 0 100 200 300
ちゃんと同じカラム単位で結合されました。
条件抽出する方法
条件抽出する方法を記載します。
使い方
- 抽出したい変数[抽出したい変数[“抽出したいカラム”] 条件]
例えば、以下のようなデータがあるとします。
列1 | 列2 | 列3 |
10 | 20 | 30 |
100 | 200 | 300 |
1000 | 2000 | 3000 |
この時に「列1」の条件が「50」以上のものを抽出したい場合は次のようにします。
条件:列1が「50」以上
df[df["列1"] >= 50]
もし複数の条件で抽出したい場合
条件:列1が「50」以上かつ「900」以下
df[(df["列1"] >= 50) & (df["列1"] <= 900)]
結果
列1 列2 列3 1 100 200 300 2 1000 2000 3000
列1 列2 列3 1 100 200 300
Pandas公式サイト
本日はここまでとなります。
これからも追加していきますので、定期的に見に来ていただければと思います。
参考にしている本
以上です。ありがとうございました。
コメント