プログラム未経験者がデータ分析に使う「Pandas」を勉強してみた

blue click pen near white document papers on top of brown wooden table Python
Photo by PhotoMIX Company on Pexels.com

今回は勉強中のデータ分析に利用するためのツール「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

ちゃんと同じカラム単位で結合されました。

Pandas公式サイト

pandas

本日はここまでとなります。
これからも追加していきますので、定期的に見に来ていただければと思います。

参考にしている本

以上です。ありがとうございました。

コメント

タイトルとURLをコピーしました