import pandas as pd4 データの読み込み
これまでは,リストや NumPy 配列に値を書き込んでデータを用意してきた.実際のデータ分析では,CSV ファイルや Excel ファイルに保存されたデータを読み込むことが多い.
本章では,東京の気温と降水量の表を使い,データを読み込み,内容を確認し,必要な部分を取り出す方法を学ぶ.ここで学ぶ操作は,後の章でデータを分析するときの準備になる.
4.1 表形式のデータ
表 4.1 は,気象庁が東京で観測した 2025 年の月ごとの平均気温と降水量である.平均気温は,その月の毎日の平均気温を平均した値である.降水量は,降った雨や雪をすべて水としてためたときの深さで表し,単位は mm(ミリメートル)を用いる.この表では,その月の合計を示す.
| month | temp_mean_c | precip_mm |
|---|---|---|
| 1 | 6.6 | 26.0 |
| 2 | 6.5 | 6.5 |
| 3 | 10.7 | 153.0 |
| 4 | 15.6 | 154.5 |
| 5 | 19.2 | 206.0 |
| 6 | 24.7 | 100.0 |
| 7 | 28.4 | 74.5 |
| 8 | 29.6 | 68.5 |
| 9 | 26.5 | 203.5 |
| 10 | 18.5 | 106.5 |
| 11 | 12.8 | 17.0 |
| 12 | 8.4 | 36.5 |
出典:気象庁,過去の気象データ・ダウンロードを加工して作成.
このような表では,通常,1 行が一つの観測対象,1 列が一つの項目を表す.この例では,1 行が 1 か月に対応し,各列は次の意味を持つ.
month:月temp_mean_c:月平均気温(℃)precip_mm:月降水量(mm)
4.2 CSV ファイル
CSV(comma-separated values)は,値をカンマで区切って表を保存する形式である.拡張子には .csv を用いる.表 4.1 を CSV 形式で表すと,次のようになる.
month,temp_mean_c,precip_mm
1,6.6,26.0
2,6.5,6.5
3,10.7,153.0
4,15.6,154.5
5,19.2,206.0
6,24.7,100.0
7,28.4,74.5
8,29.6,68.5
9,26.5,203.5
10,18.5,106.5
11,12.8,17.0
12,8.4,36.5
このファイルでは,1 行目が列名,2 行目以降がデータである.例えば,1,6.6,26.0 は,1 月の平均気温が 6.6℃,降水量が 26.0 mm であることを表している.
練習用ファイル tokyo_monthly.csv をダウンロードし,以下の手順で使ってみよう.
4.2.1 Google Colab にファイルをアップロードする
パソコンに保存したファイルを使うには,まず Google Colab にアップロードする. 次のコードを Colab のセルで実行し,表示されるファイル選択ボタンから tokyo_monthly.csv を選ぶ.これは Colab で使うためのコードである.
from google.colab import files
files.upload()アップロードが完了したら,次の節に進む.
4.3 pandas で読み込む
pandas は,表形式のデータを扱うための Python ライブラリである.通常は,pd という別名を付けてインポートする.
CSV ファイルを読み込むには,pd.read_csv() を使う.引数にファイル名を文字列で指定し,読み込んだ表に df という名前を付ける.
df = pd.read_csv("tokyo_monthly.csv")
df| month | temp_mean_c | precip_mm | |
|---|---|---|---|
| 0 | 1 | 6.6 | 26.0 |
| 1 | 2 | 6.5 | 6.5 |
| 2 | 3 | 10.7 | 153.0 |
| 3 | 4 | 15.6 | 154.5 |
| 4 | 5 | 19.2 | 206.0 |
| 5 | 6 | 24.7 | 100.0 |
| 6 | 7 | 28.4 | 74.5 |
| 7 | 8 | 29.6 | 68.5 |
| 8 | 9 | 26.5 | 203.5 |
| 9 | 10 | 18.5 | 106.5 |
| 10 | 11 | 12.8 | 17.0 |
| 11 | 12 | 8.4 | 36.5 |
pandas では,このような行と列を持つ表を DataFrame と呼ぶ.df は自分で付けた変数名であり,weather など別の名前でもよい.
表示の左端にある 0, 1, ..., 11 は,pandas が付けた行のラベルであり,インデックスと呼ばれる.元の CSV ファイルに,この番号の列があるわけではない.インデックスは 0 から始まるので,1 月の行のインデックスは 0 となる.
4.4 読み込んだデータを確認する
ファイルを読み込めても,意図した表になっているとは限らない.まず,表の一部,行数と列数,各列のデータ型,欠損値の有無を確認する.
4.4.1 表の一部と大きさ
df.head() は先頭の 5 行を取り出す.引数を指定すると,取り出す行数を変えられる.例えば,先頭の 3 行を見るには,次のようにする.
df.head(3)| month | temp_mean_c | precip_mm | |
|---|---|---|---|
| 0 | 1 | 6.6 | 26.0 |
| 1 | 2 | 6.5 | 6.5 |
| 2 | 3 | 10.7 | 153.0 |
df.shape は,表の大きさを (行数, 列数) で返す.列名の行やインデックスは,データの行数や列数には含めない.
print(df.shape)(12, 3)
結果は (12, 3) となる.12 か月について,それぞれ 3 項目のデータがあることを確認できる.
4.4.2 列名とデータ型
df.columns で列名を,df.dtypes で各列のデータ型を確認できる.
print(df.columns)
print(df.dtypes)Index(['month', 'temp_mean_c', 'precip_mm'], dtype='object')
month int64
temp_mean_c float64
precip_mm float64
dtype: object
この例では,month は整数として,temp_mean_c と precip_mm は小数として読み込まれる.表示される int64 は整数の型,float64 は小数(浮動小数点数)の型を表す.
4.4.3 欠損値
本来あるはずの値が記録されていない場合,その値を欠損値という.例えば,観測機器の故障などで,ある月の降水量が記録されていない場合である.
各列の欠損値の数は,次のように調べられる.
df.isna().sum()month 0
temp_mean_c 0
precip_mm 0
dtype: int64
isna() は各セルが欠損値かどうかを判定し,続く sum() は列ごとに欠損値の数を数える.このデータでは,すべての列で 0 となる.欠損値を含む小さな表の例を,セクション 4.8.1 で確認しよう.
欠損値がある場合は,何が記録されていないのかを確認してから,分析にどう使うかを考える.
4.5 必要な列を取り出す
4.5.1 一つの列
df["列名"] と書くと,指定した列を取り出せる.例えば,降水量だけを取り出すには,次のようにする.
precip = df["precip_mm"]
precip0 26.0
1 6.5
2 153.0
3 154.5
4 206.0
5 100.0
6 74.5
7 68.5
8 203.5
9 106.5
10 17.0
11 36.5
Name: precip_mm, dtype: float64
取り出した一つの列は,Series(シリーズ)という形式になる.Series は,インデックスの付いた 1 次元のデータである.
列を指定する場合は,列名を引用符で囲む.df["precip_mm"] の "precip_mm" は列名を表す文字列である.
4.5.2 複数の列
複数の列を取り出すには,列名のリストを渡す.次のコードでは,月と降水量を取り出す.
month_precip = df[["month", "precip_mm"]]
month_precip| month | precip_mm | |
|---|---|---|
| 0 | 1 | 26.0 |
| 1 | 2 | 6.5 |
| 2 | 3 | 153.0 |
| 3 | 4 | 154.5 |
| 4 | 5 | 206.0 |
| 5 | 6 | 100.0 |
| 6 | 7 | 74.5 |
| 7 | 8 | 68.5 |
| 8 | 9 | 203.5 |
| 9 | 10 | 106.5 |
| 10 | 11 | 17.0 |
| 11 | 12 | 36.5 |
内側の ["month", "precip_mm"] は列名のリストであり,外側の df[...] がその列を取り出す操作である.結果は,指定した順に列が並んだ DataFrame になる.
一つの列でも,df[["precip_mm"]] のように列名をリストで渡すと,1 列の DataFrame として取り出せる.列の取り出し方を 表 4.2 にまとめる.
| 書き方 | 取り出されるデータ |
|---|---|
df["precip_mm"] |
降水量の Series |
df[["precip_mm"]] |
降水量の 1 列からなる DataFrame |
df[["month", "precip_mm"]] |
月と降水量の 2 列からなる DataFrame |
4.6 条件に合う行を取り出す
まずは,雨の少なかった月として,降水量が 100 mm 以下の月を探してみよう.各行の降水量が 100 mm 以下かどうかを調べる.
condition = df["precip_mm"] <= 100
condition0 True
1 True
2 False
3 False
4 False
5 True
6 True
7 True
8 False
9 False
10 True
11 True
Name: precip_mm, dtype: bool
結果は,条件を満たす行が True,満たさない行が False となる Series である.これを df[...] に渡すと,True の行だけを取り出せる.
low_rain = df[condition]
low_rain| month | temp_mean_c | precip_mm | |
|---|---|---|---|
| 0 | 1 | 6.6 | 26.0 |
| 1 | 2 | 6.5 | 6.5 |
| 5 | 6 | 24.7 | 100.0 |
| 6 | 7 | 28.4 | 74.5 |
| 7 | 8 | 29.6 | 68.5 |
| 10 | 11 | 12.8 | 17.0 |
| 11 | 12 | 8.4 | 36.5 |
1,2,6,7,8,11,12 月の 7 か月が取り出される.左端のインデックスは元の表の 0, 1, 5, 6, 7, 10, 11 のままである.行を取り出しても,自動的に 0 から付け直されるわけではない.
条件を直接書いて,df[df["precip_mm"] <= 100] とすることもできる.
練習 4.1 平均気温が 25℃ 以上の月を取り出し,その表と月の数を表示せよ.月の数を求めるには,取り出した表に len() を使うとよい.
4.7 NumPy 配列に変換する
読み込んだ数値を NumPy で計算したいときは,to_numpy() を使って配列に変換できる.
precip_array = df["precip_mm"].to_numpy()
print(precip_array)
print(precip_array.shape)[ 26. 6.5 153. 154.5 206. 100. 74.5 68.5 203.5 106.5 17. 36.5]
(12,)
この配列の形状は (12,) であり,12 か月の降水量が入っている.列名やインデックスは配列に含まれない.
複数の数値列を選んでから変換すると,2 次元配列になる.
weather_array = df[["temp_mean_c", "precip_mm"]].to_numpy()
print(weather_array)
print(weather_array.shape)[[ 6.6 26. ]
[ 6.5 6.5]
[ 10.7 153. ]
[ 15.6 154.5]
[ 19.2 206. ]
[ 24.7 100. ]
[ 28.4 74.5]
[ 29.6 68.5]
[ 26.5 203.5]
[ 18.5 106.5]
[ 12.8 17. ]
[ 8.4 36.5]]
(12, 2)
形状は (12, 2) となる.各行が 1 か月,1 列目が平均気温,2 列目が降水量に対応する.
4.8 リストから DataFrame を作る
ここまでは,ファイルを読み込んで DataFrame を用意した.数行程度の小さな表なら,pd.DataFrame() を使って,コードの中で直接作ることもできる.次章以降では,この方法で練習用の表を作ることがある.
次のコードは,tokyo_monthly.csv と同じ内容の表を作る.
weather_df = pd.DataFrame(
[
[1, 6.6, 26.0],
[2, 6.5, 6.5],
[3, 10.7, 153.0],
[4, 15.6, 154.5],
[5, 19.2, 206.0],
[6, 24.7, 100.0],
[7, 28.4, 74.5],
[8, 29.6, 68.5],
[9, 26.5, 203.5],
[10, 18.5, 106.5],
[11, 12.8, 17.0],
[12, 8.4, 36.5],
],
columns=["month", "temp_mean_c", "precip_mm"],
)
weather_df| month | temp_mean_c | precip_mm | |
|---|---|---|---|
| 0 | 1 | 6.6 | 26.0 |
| 1 | 2 | 6.5 | 6.5 |
| 2 | 3 | 10.7 | 153.0 |
| 3 | 4 | 15.6 | 154.5 |
| 4 | 5 | 19.2 | 206.0 |
| 5 | 6 | 24.7 | 100.0 |
| 6 | 7 | 28.4 | 74.5 |
| 7 | 8 | 29.6 | 68.5 |
| 8 | 9 | 26.5 | 203.5 |
| 9 | 10 | 18.5 | 106.5 |
| 10 | 11 | 12.8 | 17.0 |
| 11 | 12 | 8.4 | 36.5 |
4.8.1 欠損値を含む表を作る
欠損値があると表がどのように表示されるか,架空の降水量データで確かめよう.次の表では,3 日間のうち 2 日目の降水量が記録されていないものとし,その値に None を指定する.
rainfall = pd.DataFrame(
[
[1, 0.0],
[2, None],
[3, 12.0],
],
columns=["day", "precip_mm"],
)
rainfall| day | precip_mm | |
|---|---|---|
| 0 | 1 | 0.0 |
| 1 | 2 | NaN |
| 2 | 3 | 12.0 |
2 日目の降水量は,欠損値を表す NaN と表示される.各列の欠損値を数えてみよう.
rainfall.isna().sum()day 0
precip_mm 1
dtype: int64
day は 0 件,precip_mm は 1 件となる.1 日目の 0.0 mm は,降水量が 0 と記録されていることを表す.2 日目の欠損値は降水量がわからないことを表すので,0 と同じ意味ではない.実際のデータでの欠損値の確認と扱い方は,チャプター 11 で詳しく学ぶ.
4.9 Excel ファイルを読み込む
Excel の .xlsx ファイルも,pandas で読み込める.Colab を使う場合は,CSV と同じようにファイルをアップロードしてから,pd.read_excel() を実行する.
例えば,1 行目に列名がある tokyo_monthly.xlsx の最初のシートを読み込むには,次のようにする.このコードを試す場合は,別途 Excel ファイルを用意する.
excel_df = pd.read_excel("tokyo_monthly.xlsx")
excel_df.head()シート名を指定する場合は,sheet_name="東京" のように引数を追加する.読み込んだ後の確認や列の取り出しは,CSV の場合と同じである.
4.10 公開されているデータを読み込む
国や研究機関などが公開しているデータを使うときに役立つ方法を二つ紹介する.本書の練習で使えるデータは,付録 A にまとめている.
4.10.1 URL から読み込む
インターネット上で公開されている CSV ファイルは,ダウンロードやアップロードをしなくても読み込める.pd.read_csv() の引数に,ファイル名の代わりに URL を文字列で指定すればよい.例えば,本章の tokyo_monthly.csv は,次のように読み込める.
url = "https://zi-ang-liu.github.io/data-science-book/data/tokyo_monthly.csv"
df = pd.read_csv(url)
df.head()読み込まれる表は,アップロードしたファイルから読み込んだ場合と同じである.インターネットに接続していれば,Colab でも自分のパソコンでも同じコードを使える.
ただし,サイトによっては,プログラムからの読み込みが拒否され,HTTPError というエラーが出る.その場合は,ファイルをダウンロードしてから読み込む.
4.10.2 文字コードを指定する
コンピュータは,文字を数値に置き換えて保存している.その置き換え方の規則を文字コードという.pd.read_csv() は,ファイルが UTF-8 という文字コードで保存されているものとして読み込む.
日本の公的統計などの CSV ファイルには,Shift_JIS という文字コードで保存されたものが多い.このようなファイルをそのまま読み込むと,UnicodeDecodeError というエラーが出る.Shift_JIS のファイルは,encoding 引数に "cp932" を指定すると読み込める.cp932 は,Shift_JIS を Windows 向けに拡張した文字コードである.
df = pd.read_csv("ファイル名.csv", encoding="cp932")4.11 総合練習
練習 4.2 平均気温が 20℃ 以上で,降水量が 100 mm 以下の月を探したい.tokyo_monthly.csv を読み込み,次の処理を行え.
- 月の数(行数)と項目数(列数)を確認する.
- 平均気温が 20℃ 以上の月を取り出す.
- 2 で取り出した月のうち,降水量が 100 mm 以下のものを取り出す.
- 条件に合う月の
monthとprecip_mmの列を表示する. - 条件に合う月の降水量を NumPy の 1 次元配列に変換し,表示する.
4.12 まとめ
- CSV や Excel に保存された表を,pandas の DataFrame として読み込める.
- URL を指定すると,インターネット上の CSV ファイルを直接読み込める.UTF-8 以外の文字コードのファイルは,
encodingで文字コードを指定する. pd.DataFrame()を使うと,リストから DataFrame を直接作れる.- 読み込んだら,表の一部,行数と列数,列名,データ型,欠損値を確認する.
df["列名"]で一つの列を,df[["列名1", "列名2"]]で複数の列を取り出せる.- 条件を使うと,分析の対象とする行を選べる.
- 数値の列は,
to_numpy()で NumPy 配列に変換できる.
読み込んだデータの特徴を知るために,次章ではグラフを描いてみよう.