『改訂第3版 基礎からわかる情報リテラシー』第13章のPython版

『改訂第3版 基礎からわかる情報リテラシー』第13章「Rによるデータ処理」をPythonに焼き直したものです。

Pythonのインストール・実行についてはお品書きをご覧ください。以下では Google Colaboratory か Jupyter Notebook を仮定しています。

グラフの描画

ライブラリ matplotlibnumpy を使っています。

2次関数 $y = x^2$ のグラフを $-3 \leqq x \leqq 3$ の範囲で描きます:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-3, 3, 101)
plt.plot(x, x ** 2)

x = np.linspace(-3, 3, 101) は区間 $-3 \leqq x \leqq 3$ を100等分する101個の x を計算します。101 という値に特に意味はありませんが,あまり小さすぎると滑らかに表示されません。

縦横比を 1 にするには plt.plot(x, x ** 2) の後に plt.axis("scaled") または plt.axis("equal") という行を追加してください。

2次関数 $y = x^3 - x$ のグラフを $x$ 軸($y = 0$ の線)とともに $-1.2 \leqq x \leqq 1.2$ の範囲で描きます:

x = np.linspace(-1.2, 1.2, 101)
plt.plot(x, x ** 3 - x)
plt.axhline()

データファイルの読み方

ライブラリ pandas を使っています。Excel ファイルを読むために pandas から openpyxl が呼び出されます。

import pandas as pd

birthdeath = pd.read_excel("https://okumuralab.org/literacy3/birthdeath.xlsx")
birthdeath.head()

データのグラフ化

plt.plot(birthdeath["年"], birthdeath["出生数"], "o-")
plt.plot(birthdeath["年"], birthdeath["死亡数"], "o-")

CSVファイルの読み込みと直線のあてはめ

気象庁のデータを読み込んでプロットします:

df = pd.read_csv("https://www.data.jma.go.jp/cpdinfo/temp/list/csv/an_wld.csv",
                 encoding="sjis")
plt.plot(df["年"], df["世界全体"], "o-")

直線をあてはめます。

slope, intercept = np.polyfit(df["年"], df["世界全体"], 1)
print("傾き", slope, "y切片", intercept)

前のプロットに続けて次のように打ち込むと,予測直線が重ね書きされます(Jupyter Notebookでは上の plt.plot(df["年"], df["世界全体"], "o-") と同じセルの最後に付け加えてください):

plt.plot(df["年"], df["年"] * slope + intercept)

より詳しい説明および別のやり方については気象庁の「世界の年平均気温偏差」データの回帰分析をご覧ください。

データの集計

学生のデータを読み込み,学部ごとに集計して棒グラフを描きます(Google Colaboratory など日本語フォントが設定されていない環境では文字化けしますが無視するか,あるいはプロットの項を見て環境設定してください):

students = pd.read_csv("https://okumuralab.org/literacy3/students.csv")
s = students.groupby("学部")["学生数"].sum()
plt.bar(s.index, s)

学年ごとに集計するには,上の「学部」を「学年」に変えます。

多数のファイルの集計

以下はそのまま打ち込んでも実行できません。実際に集計したいExcelファイル群が存在するディレクトリを指定して実行してください。

まずディレクトリ名(ここではカレントディレクトリ ".")を与えてファイル名一覧を取得します(Excel で開いているとファイル名の頭に ~$ の付いたテンポラリファイル名を拾ってしまうことがあるので要注意):

import pathlib

path = pathlib.Path(".")
names = [p for p in path.iterdir() if p.match("*.xlsx")]

ファイル名を与えると,ワークブックを開いて,最初のワークシートのセル B2,B3,B4,C2,C3,C4 の中身をリストとして返す関数を定義します。

def f(n):
    a = pd.read_excel(n, usecols="B:C", header=None, skiprows=1, nrows=3, engine="openpyxl")
    return a.values.flatten("F")

縦横に並んだセルを1列に並べる flatten() を使っています。デフォルトでは B2,C2,B3,C3,B4,C4 の順に並びますが,"F" を与えると,縦読み(Fortran流)の B2,B3,B4,C2,C3,C4 の順になります。これを次々に呼び出して,リストのリストを作ります。

x = [f(n) for n in names]

CSV形式で保存します。

pd.DataFrame(x).to_csv("x.csv", index=False, header=False, encoding="sjis")

openpyxl ライブラリを直接使えばもっと細かいこともできます(この例ではたいして変わりませんが Excel と同じ形でセル範囲が書けます):

from openpyxl import load_workbook

def f(n):
    wb = load_workbook(n, read_only=True)
    ws = wb.worksheets[0]
    return [ws["B2:C4"][i][j].value for j in range(2) for i in range(3)]
# あるいは return [x.value for x in np.array(ws["B2:C4"]).flatten("F")]