4  データの読み込み

これまでは,リストや NumPy 配列に値を書き込んでデータを用意してきた.実際のデータ分析では,CSV ファイルや Excel ファイルに保存されたデータを読み込むことが多い.

本章では,東京の気温と降水量の表を使い,データを読み込み,内容を確認し,必要な部分を取り出す方法を学ぶ.ここで学ぶ操作は,後の章でデータを分析するときの準備になる.

4.1 表形式のデータ

表 4.1 は,気象庁が東京で観測した 2025 年の月ごとの平均気温と降水量である.平均気温は,その月の毎日の平均気温を平均した値である.降水量は,降った雨や雪をすべて水としてためたときの深さで表し,単位は mm(ミリメートル)を用いる.この表では,その月の合計を示す.

表 4.1: 2025 年の東京の月平均気温と月降水量
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 という別名を付けてインポートする.

import pandas as 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 となる.

ヒントファイルが見つからないとき

FileNotFoundError が出たら,アップロードが完了しているか,ファイル名が一致しているかを確認しよう.例えば,ダウンロード時に名前が tokyo_monthly (1).csv に変わっていた場合は,名前を戻すか,コード中のファイル名を変更する.

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"]
precip
0      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 にまとめる.

表 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
condition
0      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 を読み込み,次の処理を行え.

  1. 月の数(行数)と項目数(列数)を確認する.
  2. 平均気温が 20℃ 以上の月を取り出す.
  3. 2 で取り出した月のうち,降水量が 100 mm 以下のものを取り出す.
  4. 条件に合う月の month と precip_mm の列を表示する.
  5. 条件に合う月の降水量を NumPy の 1 次元配列に変換し,表示する.

4.12 まとめ

  • CSV や Excel に保存された表を,pandas の DataFrame として読み込める.
  • URL を指定すると,インターネット上の CSV ファイルを直接読み込める.UTF-8 以外の文字コードのファイルは,encoding で文字コードを指定する.
  • pd.DataFrame() を使うと,リストから DataFrame を直接作れる.
  • 読み込んだら,表の一部,行数と列数,列名,データ型,欠損値を確認する.
  • df["列名"] で一つの列を,df[["列名1", "列名2"]] で複数の列を取り出せる.
  • 条件を使うと,分析の対象とする行を選べる.
  • 数値の列は,to_numpy() で NumPy 配列に変換できる.

読み込んだデータの特徴を知るために,次章ではグラフを描いてみよう.

ヒント気象データを調べる

気象庁の過去の気象データ検索では,全国の観測地点の気温や降水量などを,年・月・日ごとに確認できる.住んでいる地域のデータを調べてみよう.

ヒントさらに調べるには

pandas の公式チュートリアルには,表の読み込みと行・列の取り出しの例がある.Colab のファイル操作は,公式のサンプルノートブックも参考になる.