やさしい理系物理

Pandas 20本ノック

この記事は今後更新する可能性があります。

0 はじめに・準備

Pandasは,Pythonにおいて表形式データを扱うための拡張モジュールである。
 ここでは,Pandasに慣れるための問題20問を紹介する。

準備として,必要なモジュール・データをインポートしておこう(コピペでよい)。

#コピペでOK
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris

_iris = load_iris()
df_data = pd.DataFrame(_iris.data, columns=["がく片の長さ","がく片の幅","花びらの長さ","花びらの幅"])
df_target = pd.DataFrame(_iris.target, columns=["花の種類"])
df = pd.concat([df_data,df_target], axis=1)

1 基本的な操作と可視化(1〜10本目)

 データの確認

ノック1 取得したデータ $\rm df$ の先頭5行,末尾10行を表示せよ。

【解答】

#先頭5行を表示
df.head()

#末尾10行を表示
df.tail(10)

 表の一部を抽出①

ノック2 データ $\rm df$ のインデックス100〜110に該当する行,「がく片の幅」「花の種類」列を抽出せよ。

【解答】

df.loc[100:110, ['がく片の幅','花の種類']]

 表の一部を抽出②

ノック3 データ $\rm df$ の上から100〜110行目,2〜4列目のみを抽出せよ。

【解答】

#ilocを用いる場合
df.iloc[99:110,1:4]

#locを用いる場合
df.loc[100:110,'がく片の幅':'花びらの幅']

補足 locは列を「番号」ではなく「カラム名」で取得する。また行については,入力したインデックスの番号をそのまま出力する(仮にインデックスの順番がバラバラでも,ilocは上から順番に取得するが,locはインデックス番号に忠実に取得する)。
普段はilocを用いておき,locを見たらインデックスの順番が異なると覚えておこう。

 条件抽出

ノック4 データ $\rm df$ のうち「がく片の幅が3以上,かつ花びらの長さが6以上」のデータをすべて抽出せよ。

【解答】

df[(df['がく片の幅'] >= 3) & (df['花びらの長さ'] >= 6)]

補足 Pythonでは論理記号はandornotを使うのが普通だが,Pandasではこれは使えないことに注意しよう。Pandasではこれらに対応するものは&|~である。

 カラム名の変更

ノック5 データ $\rm df$ の「花の種類」列を「花の名前」に変更せよ。
(あくまで一時的な問題のためなので,変更後は名前をもとに戻しておくこと)。

【解答】

df.rename(columns={'花の種類':'花の名前'})

 ユニークな値の抽出

ノック6 データ $\rm df$ の「花の種類」列のうち,ユニークな値を抽出せよ(つまり,データに含まれる「花の種類」をすべて列挙せよ)。また,それぞれに当てはまるデータの個数をカウントせよ。

【解答】

#ユニークな値の抽出
df['花の種類'].unique()

#それぞれのデータの個数のカウント
df['花の種類'].value_counts()

 並び替え

ノック7 データ $\rm df$ を「がく片の長さ」の高い順に並び替えよ。

【解答】

df.sort_values('がく片の長さ', ascending=False)
#各データのインデックスはそのままになっていることに注意する。

 グループごとの集計

ノック8 データ $\rm df$ を「花の種類」ごとにグループ分けし,それぞれのカラムの平均値を求めよ。

【解答】

df.groupby('花の種類').mean()

 平均・分散・相関係数

ノック9 データ $\rm df$ の各列での平均と標準偏差を求めよ。また,各列間の相関係数を確認せよ。

【解答】

#平均と分散
df.mean()
df.std()

#相関係数
df.corr()

 散布図でのデータ表示

ノック10 ノック9によれば,データ $\rm df$ には「花びらの長さ」と「花びらの幅」に強い正の相関があることが分かる。実際にこれを散布図を作って確認せよ。

【解答】

df.plot.scatter(x='花びらの長さ', y='花びらの幅')
#日本語が表示できないことでエラーが生じるが,気にしないことにする

2 データの作成と結合(11〜15本目)

 データの作成

ノック11 データ $\rm df1$ を,下記のように作成せよ。

  1. 列は「花の種類」「花の名前」の $2$ つである。
  2. 行は $3$ つあり,中身はそれぞれ「0, "setona"」「1, "versicolor"」「2, "virginica"」である。
  3. 「花の種類」列は,int型となるようにすること。

【解答1】

#1つずつ,行を追加していく方法。可読性が高いが,計算速度が遅い
df1 = pd.DataFrame(columns=["花の種類", "花の名前"])

# 行を追加(ilocは使えないので注意)
df1.loc[len(df1)] = [0, "setona"]
df1.loc[len(df1)] = [1, "versicolor"]
df1.loc[len(df1)] = [2, "virginica"]
df1

【解答2】

#リストの中に辞書型を入れて,それを変換する方法。一括で作るので計算速度が早い
data = [
    {"花の種類": 0, "花の名前": "setona"},
    {"花の種類": 1, "花の名前": "versicolor"},
    {"花の種類": 2, "花の名前": "virginica"}
]
df1 = pd.DataFrame(data)
df1

補足 この他に,numpyで行列を作り,それをDataFlame型に変換する方法もあるが,結果がすべてobject型になってしまう等の課題があり一般的でないので,おすすめしない。

 データの結合

ノック12 データ $\rm df$ に $\rm df1$ を左外部結合せよ。結果を $\rm df2$ とせよ。

【解答】

df2 = pd.merge(df, df1, on = '花の種類', how = 'left')
df2

補足 データを結合するその他の方法として,concatメソッドがある。ただしこれは高度なことを考えずに,たんに $2$ つの表を「くっつける」感覚に近い。たとえばCSVファイルが $2$ つに分かれていて,それを機械的にくっつける場合である。

 ダミー変数への変換

ノック13 データ $\rm df2$ の「花の名前」をダミー変数に変換せよ。

【解答】

pd.get_dummies(df2, columns=['花の名前'])

2 欠損値の扱い(11〜15本目)

 欠損値とは?

まず,欠損値には $2$ 種類あることに注意しよう。$1$ つ目はPythonで標準で与えられているNoneで,$2$ つ目はfloat型で「非数」を表すnanNaNNanと表示されることもあるが,全部同じ)である。

PythonでCSVを読み込むと欠損値はすべてnanへ変換されるので,我々が今後注目すべき欠損値はnanである。

補足 他にも,空の文字列''も欠損値と呼ぶこともある(が,ここでは扱わない)。これはPandasでは何も表示されない。

ノック14 データnanNoneをそれぞれ作成せよ。

【解答】

#Noneはそのまま打つことで作れる
None

#nanの作り方は,おもに2つある。
float('nan') #nanの大文字・小文字は自由。NaN等でも良い
np.nan

 欠損値の列を追加

ノック15 データ $\rm df$ に $2$ つの新しい列「欠損値1」「欠損値2」を作成し,それぞれの列をnanNoneで埋めよ。結果を $\rm df3$ とすること。

【解答】

_df3 = df
_df3['欠損値1'] = np.nan
df3 = _df3
df3['欠損値2'] = None
df3

 欠損値の行を追加

ノック16 データ $\rm df3$ に 対し,すべての列がnanの行を追加せよ。

【解答】

df3.loc[len(df)] = [np.nan for i in range(7)]
df3
# 7は列数。取得しても良い

 欠損値の個数を確認する

ノック17 データ $\rm df3$ の各列における欠損値の個数を集計せよ。

【解答】

df3.isnull().sum()

ノック18 データ $\rm df3$ のすべての欠損値を $0$ で埋めよ。

【解答】

df3.fillna(0)

ノック19 データ $\rm df3$ の欠損値が存在するすべての列を削除せよ。

【解答】

df3.dropna(axis=1)

▲ To Top ▲