Pythonデータ処理でよく利用するPandasのキホン的な使い方
Pandasのキホン的な使い方(忘れたときのおさらい)
モモノキ、Pythonをしばらく使っていなかったから、データの扱い方を忘れたかも。Pandasってどう使うんだっけ?
最近、R言語ばっかり使ってたからね...。ナノネ、今回はPadasのキホン的な使い方を復習しておこう。
Pandasだと、SeriesとDataFrameがあったよね?
Serisが一次元のデータ、DataFrameは二次元のデータを扱える型だよ。簡単なデータを作って実際に試してみよう。
まずは必要なライブラリをインポート。PadasとおまけでNumpyがあればとりあえずOKかな。
# ライブラリのインポート
import numpy as np
import pandas as pd
決まり文句でインポートした。
最初はSeriesから。PandasのSeriesメソッドが使うよ。引数に一次元データを指定すればOK。
srs = pd.Series(np.arange(10, 15))
srs
できた。
オプションでindex、nameも指定できるよ。
srs = pd.Series(data = np.arange(10, 15),
index = ['a', 'b', 'c', 'd', 'e'],
name='value')
srs
少し思い出してきたかも。
Serisデータから値を抽出するには、いくつか方法があるけど。例え三番目の12の取得する場合はこんな感じ。
srs[2] # index番号で指定(ゼロ始まりので3番目はindex=2)
srs['c'] # index名で指定
もしくは、ilocやlocを使っても同じように値を取得できるよ。
srs.iloc[2] # ilocでindex番号を指定
srs['c'] # locでindex名を指定
複数指定するとときは:(コロン)だっけ、,(カンマ)だっけ?
連続した範囲を指定するときは:(コロン)で、とびとびのときは:(カンマ)を使ってリスト形式にしてね。
srs.iloc[1:4] # index番号1~3を抽出
srs.iloc[[0, 2, 4]] # index番号0,2,4を抽出
抽出できた。
次はDataFrame。Series単独よりも、こっちを利用する機会の方が多いよね。PandasのDataFrameメソットを利用するよ。こんな感じで二次元データを渡すとデータフレームが作成できるよ。
# 二次元データの作榮
data1 = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
# 二次元データを使ってデータフレームを作成
df = pd.DataFrame(data1)
df
インデックス名、列名とか指定する場合は?
オプションのindex、columnsで指定できるよ。
# データフレームの作成(インデックス、列名を指定)
df = pd.DataFrame(data=data1,
index=['a', 'b', 'c'],
columns=['COL1', 'COL2', 'COL3'])
df
データフレームをつくるとき、キーと値の形式でデータを指定することもできるよ。たとば、身長、体重、胴囲を列として、6件のデータを作るとこんな感じ。
# 身長、体重、胴囲のデータ(キーと値でデータを指定)
df = pd.DataFrame({"Height": [168, 175, 188, 160, 158, 173],
"Weight": [75, 68, 88, 52, 48, 63],
"Weist": [76, 77, 90, 68, 58, 80]})
df
データフレームから値を抽出する方法は?
Serisのときとキホン一緒だけど、二次元データなので行や列を指定する必要があるよ。さっき作った身長・体重・胴囲のデータフレームで試してみよう。
次のケースはheight(身長)列の値だけ抽出する場合だよ。
df['Height'] # Height列の値を抽出
df.loc[:, 'Height'] # 全ての行のHeight列を抽出
df.iloc[:, 0] # 全ての行、0列目(Height)を抽出
抽出結果は同じだけど、書き方がいくつもあるみたい。どれを使うといいの??
ケースバイケースで使いやす表記でOKかも。でも、他の人が書いたコードが読めるように、知識としては複数の書き方を覚えておくのも大事だよ。
ナノネ、次はheight(身長)とWeight(体重)の列を抽出してみて。
df[['Height', 'Weight']] # HeightとWeight列を抽出
df.loc[:, ['Height', 'Weight']] # 全ての行で、HeightとWeight列を抽出
df.iloc[:, 0:2] # 全ての行、0~1列(Height、Weight)
3通りの書き方を試してみたけど、どれもうまく抽出できたみたい。
参考までに、返り値の違いも確認しておこう。最初のケースみたいに1列だけ抽出した場合はSeries型、複数列抽出したときの返り値はDataFrame型になっているよ。
type(df.loc[:, 'Height']) # -> Series型
type(df.loc[:, ['Height', 'Weight']]) # -> DataFrame型
次は単純な行選択をいくつか試してみよう。
df.iloc[3, :] # 4行目(index3)、全ての列を抽出
df.iloc[3:5, :] # 4~5行目(index3~4)、全ての列を抽出
df.iloc[[1, 3], :] # 2と4行目(index1と3)、全ての列を抽出
もし、ピンポイントで値を抽出したい場合は、こんな感じかな?
df.iloc[3, 1] # 4行目(index3)、1列目(weight列)の値を抽出
df.loc[3, 'Weight'] # 4行目(index3)、weight列の値を抽出
次はもう少し複雑な抽出をやってみよう。条件にマッチする行を抽出する方法だよ。
たとえば、Height(身長)が170より大きいデータ行を抽出するには...
df[df['Height'] > 170] # Heightが170より大きいデータ行を抽出
# df.loc[(df['Height'] > 170),:]
条件に合うデータを抽出するときは、データフレームを入れ子するの?けっこう面倒かも。
動作的には内側の条件判定のところで、データ数分のbool値(True/False)が返ってくるよ。Heightが170より大きいデータはインデックス1,2,5が該当。インデックス1,2,5はTrueになってるね。
df['Height'] > 170 # 試しに内側の条件指定だけ出力
書き換えるとこんな感じかな?
# df[df['Height'] > 170] # インデックス1,2,5がTrue
df[[False, True, True, False, False, True]] # インデックス1,2,5を抽出
一度に複数の条件を指定したい場合は、&や|も使えるよ。
# Heightが170より大きい、かつHeightが180より小さいデータ行を抽出
df[(df['Height'] > 170) & (df['Height'] < 180)]
# Heightが170より大きい、またはWeightが180より小さいデータ行を抽出
df[(df['Height'] > 170) & (df['Weight'] < 80)]
カッコの付け忘れとか注意すれば、条件指定もなんとかなりそう。
もし、新しデータ列を付け足したいときは?
データフレームに新しい列名を定義して、値を代入すればOKだよ。身長と体重のデータがあるから、BMIを求めて新しい列に追加してみよう。
BMIは体重(kg)を身長(m)の二乗で割るんだっけ...
df['Weight'] / (df['Height'] / 100) ** 2 # BMI計算
df['BMI'] = round(df['Weight'] / (df['Height'] / 100) ** 2, 1) # BMI列を追加
df
新しい列として、BMIを追加できた。
データ列を削除したいときは?
削除したい場合はdropメソッドが使えるよ。列単位で削除をしたい場合は、引数に列名とaxis=1を指定してみて。
df.drop('BMI', axis=1) # BMI列を削除してデータ出力
df # 元データフレームは更新されていない
列削除されたデータは出力できたけど、元のデータフレーム自体は更新されないみたい。
元のデータフームを更新したい場合、データフレーム変数に再代入するか、inplace=Trueを指定すれば更新できるよ。
df = df.drop('BMI', axis=1)
# もしくは
# df.drop('BMI', axis=1, inplace=True)
df
列の平均値とか求めたいときは?
平均値を求めたいときはmean()でOK。統計量をまとめて出力したいときは、describe()が便利だよ。
df.mean() # 列の平均値
df.describe() # 基本統計量を出力
あと、データによっては欠損値がある場合も多いから、欠損値の扱いも覚えておこう。まずは欠損値があるデータを準備しよう。
# 欠損値を含む身長、体重、胴囲のデータ
df = pd.DataFrame({"Height": [168, 175, 188, 160, 158, 173],
"Weight": [75, np.nan, 88, 52, 48, 63],
"Weist": [76, np.nan, 90, np.nan, 58, np.nan]})
df
欠損値(Nan)はWeightに1個、Weistに3個ある。
欠損値の確認は、isnull()が使えるよ。sum()で集計すれば、欠損値の個数も簡単に確認できるよ。
# 欠損値の個数を確認
df.isnull().sum()
最初は欠損値があるデータ行を全部削除してしまう方法だよ。dropna()メソッドで処理できるよ。
df.dropna() # 欠損値がある行を全て削除
次は特定の列に欠損値がある行だけ削除する方法だよ。たとえばWeightの値が欠損値だったら、その行を削除するケース。
欠損値はisnull()で判定できるから...
df['Weight'].isnull() # Weightが欠損値のときTrueを返す
df[df['Weight'].isnull() == False] # Weightが欠損値では無い行(isnullがFalse)だけ抽出
特定の値より大きい・小さいとか条件指定した方法とキホン一緒だね。
次は欠損値をなんらかの値で補完する方法だよ。簡易的な処理なら平均値、中央値、最頻値などを使うケースも多いよ。でも厳密な補完が必要なときは結構扱いが難しくて、多角的な分析が必要だよ。今回は練習なので欠損値は平均値で埋めてみよう。
df # 補完前(欠損値を含むデータ)
欠損値を別の値で補完するときは、fillna()メソッドが便利だよ。
df['Weight'].fillna(df['Weight'].mean()) # Weightの欠損値をWeightの平均値で補完
df['Weight'] = df['Weight'].fillna(df['Weight'].mean()) # データフレーム更新
df
欠損値だったWeightのインデックス1に数値(Weight平均値65.2)が入った。Weistも同じようにやってみる。
# Weistの欠損値を平均値で補完
df['Weist'] = round(df['Weist'].fillna(df['Weist'].mean()), 1)
df
Weistの欠損値補完も、うまくいったみたい。
次はデータセットを使った練習をやってみよう。データセットは毎度のIrisで。
# データセットのインポート
from sklearn.datasets import load_iris
iris = load_iris() # irisデータ読み込み
読み込んだirisデータを使って、データフレームを作成してみよう。dataにiris.data、columnsはiris.feature_nameを指定しておこう。
# irisのdata、iris.feature_namesを使ってデータフレームを作成
df_iris = pd.DataFrame(data=iris.data, columns=iris.feature_names)
irisデータは150行あるんだけど。データの中身を一部だけチェックしたいときは、head()やtail()を使うと便利だよ。
df_iris.head() # 先頭の5行
df_iris.tail() # 末尾の5行
df_iris.head(n=8) # 表示するデータ数を指定(デフォルトは5)
花の種類もあったはずだから、データフレームに追加してみる。花の種類はiris.targetに入っていたので...。
# 花の種類(Target)をデータフレームに追加
df_iris['target'] = iris.target
df_iris.head()
df_iris.tail()
花の種類(数値で0,1,2)をtarget列として追加できた!次は花の名前も出力してみる。
# 花の名前
iris.target_names
targetの0がsetosa、1がversicolor、2がvirginicaみたいだから...。こんな感じで、花の種類の数値を名前に変換できそう。
iris.target_names[iris.target] # target(0~2)を花の名前に変換
# 花の種類の名前をspecies列として追加
df_iris['species'] = iris.target_names[iris.target]
df_iris[0:3]
df_iris[50:53]
df_iris[100:103]
うまくできたみたいだね。
Pandasって他にも、いろいろ操作や便利機能があったよね。
うん、いっぱいあるね。でも一度にとても覚えきれないから、必要になった機能は都度調べながら試していこう。
最後によく使う機能として、データフレームをCSVファイルに書き出す方法と、ファイルからデータを読み込む練習もやっておこう。
# データフレームをCSVファイルに書き出す
df_iris.to_csv('mydata.csv', index=False) # 行インデックスなし
# CSVファイルからデータフレームに読み込む
df_mydata = pd.read_csv('mydata.csv')
df_mydata.head() # 読み込んだデータの確認
読み書きの条件指定には文字コードやヘッダー有無など、オプションのパラメータがたくさんあるので必要に応じて調べてみてね。
今回のPandasのキホン的な使い方の練習(復習)は以上で。またね!
お疲れ様でした。
0 件のコメント :
コメントを投稿