[Pandas]代表値を求める(平均値、中央値、最頻値)

一般的によく知られている代表値といえば、平均値(mean)、中央値(median)、最頻値(mode)です。

Pandasを使ってこれらの値を求めてみます。

下準備

今回はTitanicデータセットから年齢(Age)を使用します。

import pandas as pd
import math

df = pd.read_csv('./titanic/train.csv')

平均値を求める

平均値を求めるにはmean()を使用します。

# 平均値(mean)を求める
df['Age'].mean()
# -> 29.69911764705882

中央値を求める

中央値を求めるにはmedian()を使用します。

# 中央値(median)求める
df['Age'].median()

最頻値を求める

最頻値を求めるには一工夫が必要です。最頻値は最も大きい度数の階級値になるため、一旦度数分布表を作成します。

ヒストグラムを確認する

度数分布表を作成する前にヒストグラムを確認しておきましょう。

df['Age'].hist(bins=10)

ビンの数を10に設定してヒストグラムを作成すると、20代が最頻値のようだということがわかります。

最頻値を求める

視覚的に確認できたところで、最頻値を求めます。度数分布表の作成方法はいくつかありますが、ここでは簡易的にcut()value_counts()を組み合わせて、先ほど確認したグラフと同じ区間で度数分布表を作成します。

# 度数分布表を作成する
pd.cut(df['Age'], 10).value_counts()
---
(16.336, 24.294]    177
(24.294, 32.252]    169
(32.252, 40.21]     118
(40.21, 48.168]      70
(0.34, 8.378]        54
(8.378, 16.336]      46
(48.168, 56.126]     45
(56.126, 64.084]     24
(64.084, 72.042]      9
(72.042, 80.0]        2
Name: Age, dtype: int64

作成した結果を確認しても20代が最頻値のようです。最頻値は区間の最小値と最大値の中間になりますので、$24.294-(24.294-16.336)\div2=20.315$となります。

M1/M2 Macで機械学習の環境を構築する

TensorflowとPytorchがApple Siliconに対応したため、Pythonの機械学習・ディープラーニング環境を構築します。

仮想環境の作成

仮想環境を作成します。

使用するPythonのバージョンですが、このあとインストールするTensorflowが執筆時点では3.7から3.10をサポートしており、Pytorchが3.7以上をサポートしているため、3.10を使用することにします。

conda create -n datascience python=3.10
conda activate datascience

ここでは仮想環境の名前をdatascienceにしていますが、任意の名前で構いません。

機械学習関連

機械学習関連のパッケージをインストールします。

機械学習でよく使われるパッケージをインストールします。

conda install numpy scipy pandas scikit-learn

代表的な可視化パッケージをインストールします。

conda install matplotlib seaborn plotly

EDAパッケージをインストールします。

conda install -c conda-forge pandas-profiling autoviz sweetviz

ローコード機械学習をインストールします。

conda install -c conda-forge pycaret

Jupyter notebookをインストールします。

conda install notebook

スクレイピング関連

スクレイピングでよく使用されるパッケージをインストールします。

conda install -c conda-forge requests scrapy beautifulsoup4

画像処理関連

画像処理でよく使用されるパッケージをインストールします。

conda install -c conda-forge pillow opencv

ディープラーニング関連

TensorflowとPytorchをインストールします。

Tensorflow

Xcode Command Line Toolをインストールしていない場合は以下のコマンドでインストールします。 

xcode-select --install

Tensorflow dependenciesをインストールします。

conda install -c apple tensorflow-deps

Tensorflowをインストールします。

pip install tensorflow-macos

Metalプラグインをインストールします。

pip install tensorflow-metal

インストール後にGPUが使用可能か確認しましょう。

import sys
import tensorflow.keras
import pandas as pd
import sklearn as sk
import scipy as sp
import tensorflow as tf
import platform

gpu = len(tf.config.list_physical_devices('GPU'))>0
print("GPU is", "available" if gpu else "not available")

以下のように表示されればGPUが使用可能です。

GPU is available

Pytorch

PytorchはTensorflowに比べるとインストールは簡単です。以下のコマンドでインストールします。

pip install --pre torch torchvision --extra-index-url https://download.pytorch.org/whl/nightly/cpu

インストール後にGPUが使用可能か確認しましょう。

import torch

gpu = torch.backends.mps.is_available()
print("GPU is", "available" if gpu else "not available")

以下のように表示されればGPUが使用可能です。

GPU is available

今後の課題

現時点で形態素解析パッケージであるMecabのインストールに失敗しています。手順もいくつか示されていますが、実際に試したところいずれもうまくいっていません(インストール自体に失敗する、インストール後に動作しない)。

こちらは引き続きインストール方法を調査し、判明次第本記事を更新したいと思います。

Pandasで日付項目を日付型として扱う

Pandasで日付項目をdatetime[ns]型に変換し、日付型として扱う方法について解説します。

日付項目を読み込む

次のCSVファイルを特にオプションを指定せずに読み込みます。

date1        ,date2      ,date3     ,date4   ,date5     ,date6   ,date7
2020年12月31日,2020年6月9日,2020-12-31,2020-6-9,2020/12/31,2020/6/9,20201231

このファイルには4種類(うち3種類は0埋めありとなしの2パターン用意)の日付項目が設定されています。

import pandas as pd
df = pd.read_csv('test.csv')

各項目がどの型で読み込まれているかinfo関数で確認します。

df.info()

yyyymmdd形式はint64型、それ以外はobject型(str型)で読み込まれているのがわかります。

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1 entries, 0 to 0
Data columns (total 7 columns):
 #   Column  Non-Null Count  Dtype 
---  ------  --------------  ----- 
 0   date1   1 non-null      object
 1   date2   1 non-null      object
 2   date3   1 non-null      object
 3   date4   1 non-null      object
 4   date5   1 non-null      object
 5   date6   1 non-null      object
 6   date7   1 non-null      int64 
dtypes: int64(1), object(6)
memory usage: 184.0+ bytes

日付型に変換する

日付項目を加工したり、年・月・日などを取り出しやすくするために、datetime64[ns]型に変換しておくと便利です。

datetime64[ns]型に変換するには、pandas.to_datetime関数を使います。

df['datetime1'] = pd.to_datetime(df['date1'], format="%Y年%m月%d日")
df['datetime2'] = pd.to_datetime(df['date2'], format="%Y年%m月%d日")
df['datetime3'] = pd.to_datetime(df['date3'])
df['datetime4'] = pd.to_datetime(df['date4'])
df['datetime5'] = pd.to_datetime(df['date5'])
df['datetime6'] = pd.to_datetime(df['date6'])
df['datetime7'] = pd.to_datetime(df['date7'], format="%Y%m%d")

年月日形式の項目はformatオプションを指定しないとエラーになります。また、yyyymmdd形式はエラーにはなりませんが、値をナノ秒と見なして読み込むため、1970-01-01 00:00:00.020201231のような値になってしまいます。こちらもformatオプションの指定が必要です。

読み込み時に 日付型に変換する

読み込んでみてから、「あ、これ日付項目か」と気づく場合は前述の方法を使っていただければよいですが、事前にどれが日付項目かわかっている時は読み込む時に日付型として読み込む方が効率的です。

標準の日付パーサーで変換できる場合

yyyy-mm-dd形式やyyyy/mm/dd形式、yyyymmdd形式の場合は標準の日付パーサーで変換できます。

次のような形式の CSVファイルの場合、

date    ,average
2021/8/1,28.7
2021/8/2,28.6
2021/8/3,29.0
2021/8/4,29.5
2021/8/5,29.1
2021/8/6,29.1
2021/8/7,27.9

以下のようにすることで、項目dateを日付datetime64[ns]型で読み込むことができます。

df = pd.read_csv('weather.csv', 
                 dtype={"date": str},
                 parse_dates=["date"])
df.info()

直接dtypedatetime64を指定するのではなく、一旦dtypeオプションではstr型を指定して、parse_datesオプションで日付型にしたい項目を指定して変換するというやり方になります。

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 7 entries, 0 to 6
Data columns (total 2 columns):
 #   Column    Non-Null Count  Dtype         
---  ------    --------------  -----         
 0   date      7 non-null      datetime64[ns]
 1    average  7 non-null      float64       
dtypes: datetime64[ns](1), float64(1)
memory usage: 240.0 bytes

日付パーサーを自作して変換する場合

年月日形式などPandasが用意している標準の日付パーサーで変換できない場合は日付パーサーを自作して指定することで日付変換ができるようになります。

次のようなCSVファイルの場合、

date,       average
2021年8月1日,28.7
2021年8月2日,28.6
2021年8月3日,29.0
2021年8月4日,29.5
2021年8月5日,29.1
2021年8月6日,29.1
2021年8月7日,27.9

先ほどと同じコードで読み込むと、エラーは発生しませんが、datetime64[ns]型には変換されません。

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 7 entries, 0 to 6
Data columns (total 2 columns):
 #   Column    Non-Null Count  Dtype  
---  ------    --------------  -----  
 0   date      7 non-null      object 
 1    average  7 non-null      float64
dtypes: float64(1), object(1)
memory usage: 240.0+ bytes

このような場合は、日付パーサーを自作し、date_parserオプションで指定します。

from datetime import datetime
my_parser = lambda date: datetime.strptime(date, '%Y年%m月%d日')
df = pd.read_csv('weather.csv', 
                 dtype={"date": str},
                 parse_dates=["date"],
                 date_parser=my_parser)
df.info()

先ほどとは異なり、datetime64[ns]型に変換されていることが確認できます。

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 7 entries, 0 to 6
Data columns (total 2 columns):
 #   Column    Non-Null Count  Dtype         
---  ------    --------------  -----         
 0   date      7 non-null      datetime64[ns]
 1    average  7 non-null      float64       
dtypes: datetime64[ns](1), float64(1)
memory usage: 240.0 bytes

pandas.datetime.strptimeを使用するサンプルを見かけると思いますが、pandas.datetimeは将来的に削除される予定ですので、今後はdatetimeを使用しましょう。
/var/folders/3r/qfsmvnsd5sz0qvf367p_d5j00000gp/T/ipykernel_83309/1860031930.py:1: FutureWarning: The pandas.datetime class is deprecated and will be removed from pandas in a future version. Import from datetime module instead.
my_parser = lambda date: pd.datetime.strptime(date, ‘%Y年%m月%d日’)

PandasでCSVファイル読み込む(read_csv関数)

PandasでCSVファイルを読み込む方法について解説します。
本記事では読み込みオプションの解説ではなく、CSVファイルや CSVファイルに似たファイルの読み込み方について解説しています。

CSVファイルを読み込む

次のCSVファイルを読み込んでデータフレームを作成します。

社員番号,氏名,姓,名,生年月日,役職
001,山田 太郎,山田,太郎,1990-01-01,係長
002,田中 花子,田中,花子,1990-12-31,部長

ふつうのCSVファイルであればオプションなしで読み込むことができます。

import pandas as pd
test1_df = pd.read_csv('test1.csv')

カンマやダブルクォーテーションをカラムに含むCSVファイルを読み込む

カラムにカンマを含む場合、ダブルクォーテーションでカラムを囲みます(a,b"a,b") 。もちろん、カンマを含んでいない場合でもダブルクォーテーションでカラムを囲んでもかまいません。
ダブルクォーテーションでカラムを囲んでいるときにカラムにダブルクォーテーションが含まれる場合はエスケープする必要があります。エスケープする場合はダブルクォーテーションを二つ重ねます(a"b"a""b")。

次のCSVファイルを読み込んでデータフレームを作成します。

社員番号,氏名,姓,名,生年月日,役職
001,"山田,""太郎",山田,太郎,1990-01-01,係長
002,"田中,""花子",田中,花子,1990-12-31,部長

Pandasのread_csv関数は基本的なCSVの仕様に対応しているため、特にオプションを使用せずに読み込むことができます。

import pandas as pd
test2_df = pd.read_csv('test2.csv')

タブ区切りファイルを読み込む

最近は見かけることが減りましたが、タブ区切りファイル(TSVファイル)をread_csv関数で読み込むことができます。

次のTSVファイルを読み込んでデータフレームを作成します。

社員番号	氏名	姓	名	生年月日	役職
001	山田 太郎	山田	太郎	1990-01-01	係長
002	田中 花子	田中	花子	1990-12-31	部長

オプションなしで読み込むことはできないため、sepで区切り文字を指定します。

import pandas as pd
test3_df = pd.read_csv('test3.csv', sep='\t')

任意の区切り文字のファイルを読み込む

出力する側の問題でダブルクォーテーションによる区切り文字が使用できない場合や出力または中間での加工の都合で、カラム内に絶対に含まれない文字を使ってファイルを出力することがあります。
先ほどのタブ区切りの応用でread_csv関数を使って読み込むことができます。

垂直バー(|)を区切り文字にした次のCSVファイルを読み込んでデータフレームを作成します。

社員番号|氏名|姓|名|生年月日|役職
001|山田 太郎|山田|太郎|1990-01-01|係長
002|田中 花子|田中|花子|1990-12-31|部長

TSVファイルのときと同様に、sepで区切り文字を指定します。

import pandas as pd
test4_df = pd.read_csv('test4.csv', sep='|')

まとめ

read_csv関数を使うことで、CSVファイルやTSVファイルだけでなく、任意の区切り文字のファイルも読み込むことができます。

運用上の理由からCSVファイルでは都合が悪いケースもありますので、その場合は任意の区切り文字を使うことを検討してみてはいかがでしょうか。

モバイルバージョンを終了