5. データ操作の基礎 - pandas¶
第 5 回では pandas を用いたデータ操作について学びます。
5.1 pandas の概要¶
pandas は、Python でデータ操作やデータ分析を行うためのライブラリで、NumPy を基盤として構築されており、NumPy よりも柔軟にデータを扱えるように設計されています。
pandas が提供する主要なデータ構造には、Series と DataFrame があります。
5.1.1 pandas のインポート¶
pandas は以下のようにインポートして使います。
5.2 Series¶
Series(シリーズ)は、一次元のラベル付きデータを格納することができます。リストや配列と似ていますが、インデックス(ラベル)を使ってアクセスできる特徴があります。
Series は以下のように、pandas.Series() 関数で作ることができます。
インデックスを指定して Series を作成するには以下のようにします。
以下のように辞書から Series を作成することもできます。
値にアクセスする際は、ブラケット ([]) を使う方法と、pandas.Series.at() 関数を使う方法があります。
[]はスライス操作などができる柔軟性を持ちます。atは要素へのアクセスに特化しているため高速に動作します。
Series は内部で NumPy 配列を利用しているため、NumPy のブロードキャストと同様の演算操作が可能です。例えば、各要素に対して以下のように演算を行うことができます。
条件式による要素抽出も可能です。
5.3 DataFrame¶
DataFrame(データフレーム)は、複数の Series を列にまとめた二次元の表形式のデータ構造です。DataFrame は Excel や SQL などの多くの表形式のデータとの連携が容易であること、実務データは複数の変数(列)を持つことが一般的であること、Series を包含していることなどから、実務では圧倒的に DataFrame が使用されることが多いです。
5.3.1 DataFrame の作り方¶
DataFrame を作るためには、pandas.DataFrame() 関数を使用します。
以下は、3 人分の「名前」「年齢」「身長」の情報を含む二次元のリストから DataFrame を作成する例です。columns で列名を指定することができ、これを省略すると整数のインデックス(0, 1, 2, ...)が列名として使用されます。
import pandas as pd
data = [
["太郎", 25, 170],
["花子", 30, 160],
["次郎", 22, 175]
]
df = pd.DataFrame(data, columns=["名前", "年齢", "身長"])
print(df)
デフォルトでは各行に整数のインデックス(0, 1, 2, ...)が振られますが、Series と同様に任意のインデックス(ラベル)を指定することもできます。
import pandas as pd
data = [
["太郎", 25, 170],
["花子", 30, 160],
["次郎", 22, 175]
]
df = pd.DataFrame(data, columns=["名前", "年齢", "身長"], index=["A", "B", "C"])
print(df)
以下のように、辞書から DataFrame を作成することもできます。
import pandas as pd
data = {
"名前": ["太郎", "花子", "次郎"],
"年齢": [25, 30, 22],
"身長": [170, 160, 175]
}
df = pd.DataFrame(data)
print(df)
5.3.2 DataFrame の読み込み¶
DataFrame はリストや辞書から作成する以外に、外部から読み込ませて扱うケースも多くあります。
サンプルデータセットの利用¶
インターネット上に存在する多くのサンプルデータセットは、DataFrame の形式で提供されています。例えば、第 3 回の「データ可視化」で扱った Seaborn のサンプルデータセットも DataFrame 形式であり、以下のようにして読み込ませることができます。
import seaborn as sns
penguins = sns.load_dataset("penguins")
print(penguins.head())
species island bill_length_mm ... flipper_length_mm body_mass_g sex
0 Adelie Torgersen 39.1 ... 181.0 3750.0 Male
1 Adelie Torgersen 39.5 ... 186.0 3800.0 Female
2 Adelie Torgersen 40.3 ... 195.0 3250.0 Female
3 Adelie Torgersen NaN ... NaN NaN NaN
4 Adelie Torgersen 36.7 ... 193.0 3450.0 Female
外部ファイルの読み込み¶
pandas.read_csv() 関数や pandas.read_excel() 関数を使うことで、CSV ファイル Excel ファイルを DataFrame として読み込ませることができます。
pandas.read_excel() 関数では、sheet_name パラメータで読み込むシート名を、usecols パラメータで読み込む列を指定することも可能です。
CSV ファイル
CSV(Comma-Separated Values)は、データをカンマ(,)で区切ったテキスト形式のファイルです。CSV は Excel で開くことが多いかもしれませんが、中身は単純なテキストデータなので、メモ帳などで開くこともできます。
5.3.3 DataFrame の操作¶
DataFrame を操作する方法を見ていきましょう。df という名前で以下の DataFrame があるものとします。
並び替え(ソート)¶
DataFrame の任意の列を並べ替えたい(ソートしたい)場合は、DataFrame.sort_values() 関数を用います。並び替えの対象とする列は by= パラメータで指定します。
デフォルトでは上の例のように、数字の小さい順(昇順)での並び替えが行われます。数字の大きい順(降順)での並び替えをしたい場合は、以下のように ascending=False パラメータを追加します。
列の抽出¶
DataFrame から列を抽出したい場合は、以下のように列名を指定します。このとき、一次元の Series データが抽出されます。
列名をリストで指定することで、複数の列を同時に抽出することもできます。このとき、抽出したデータも DataFrame となります。
行の抽出¶
DataFrame から行を抽出したい場合は、pandas.loc[] インデクサまたは pandas.iloc[] インデクサを使用します。loc ではインデックス名を指定するのに対し、iloc では整数インデックスを指定します。
複数の行を抽出するには、リストで指定するか、スライスを使用します。
デフォルトの整数インデックスの場合、loc と iloc は同じように使うことができます。ただし、スライスを使用する場合、iloc はリストのスライスと同様に終端を含まない範囲を抽出する一方で、loc では終端を含む点に注意が必要です。上のスライスを使用する例で iloc を loc に置き換える場合は、df.loc[:1] となります。
行・列の抽出¶
df.loc[行ラベル, 列ラベル] とすることで、行と列を同時に指定して抽出することもできます。すべての行と列を取得するには、以下のようにします。
行ラベル(インデックス)が 1 、列ラベルが "名前" の値を抽出したい場合は以下のようにします。
行ラベル(インデックス)が 1 以降、列ラベルが "名前" と "年齢" の値を抽出したい場合は以下のようにします。
条件式による抽出¶
条件式を用いることで、DataFrame から効率的にデータを抽出することが可能になります。
- 条件式には、
==,!=,<,>,<=,>=などの比較演算子を使用します。 - 複数の条件を指定する場合は、
&(AND),|(OR),~(NOT) などの論理演算子を使用します。
例えば、年齢が 25 歳以上の人を抽出するには、以下のようにします。
年齢が 25 歳以上かつ身長が 170 cm 未満の人を抽出するには、以下のようにします。
複数条件を利用する際の注意
DataFrame におけるデータ抽出において、& (AND) や '|' (OR) を用いて複数の条件を指定する際は、それぞれの条件式を括弧 () で囲う必要がある点に注意してください。
✅️ df.loc[(df["年齢"] >= 25) & (df["身長"] < 170)] ❌️ df.loc[df["年齢"] >= 25 & df["身長"] < 170]
これらの抽出方法をうまく組み合わせることで、複雑な条件でも効率的にデータ抽出をすることができるようになります。
演習¶
演習 5-1
与えられた都道府県データ [都道府県番号, 人口(万人), 面積(km²), 緯度, 経度] の DataFrame に対し、「人口密度」の列を追加してください。また、人口が250万人以上の都道府県を抽出し、人口密度の高い順に並べ替えて棒グラフで可視化してください。
演習 5-2
Seaborn に含まれる diamonds データセットを使い、ダイヤモンドのカラットを [0, 0.5), [0.5, 1), [1, 2), [2, ∞) の4つの区分に分けて、2x2 のサブプロットを作成しててください。各サブプロットには、対応するカラット区分のダイヤモンドの価格(price)分布をヒストグラムで描画してください。