ExcelファイルをPythonでデータ分析する
1.Excelファイルの読み込み - 2.グラフ - 3.度数分布 - 4.ランキングチャート - 5.相関 - 6.ディシジョンツリー
「ExcelファイルをPythonでデータ分析する」は上のような一連の記事になっており、2~6までは事前に1.Excelファイルの読み込みと事前処理が行われていることを前提としています。
都道府県の人口ランキングチャート
ランキングチャートとは、1位、2位といった順位の変動を示すものです。ここでは人口の多さをランキングとして表し、1920年から2020年までのその順位変動をグラフ化してみたいと思います。
ランキングの列を新たにDaraFrameに追加する
全データのdf0をそのまま使用しても良いのですが、何かあって元に戻す時、再度Excelファイルを読み込むのは面倒なので、df0は変更せずに新たにdf1を作成したいと思います。
以下のプログラムは、prefsで指定された県の、yearsで指定された年の人口のみをdf1として抽出するものです。
prefs = ["新潟県","宮城県","長野県"]
years = ['1920年_総数', '1925年_総数', '1930年_総数', '1935年_総数', '1940年_総数', '1945年_総数', '1950年_総数',
'1955年_総数', '1960年_総数', '1965年_総数', '1970年_総数', '1975年_総数', '1980年_総数', '1985年_総数',
'1990年_総数', '1995年_総数', '2000年_総数', '2005年_総数', '2010年_総数', '2015年_総数', '2020年_総数']
# 総数だけを抜き出した data0 を作成する。
df1 = df0.loc[prefs,years]
print(df1)
実行すると以下のように表示されます。
1920年_総数 1925年_総数 1930年_総数 1935年_総数 1940年_総数 1945年_総数 1950年_総数 \
新潟県 1776474 1849807 1933326 1995777 2064402 2389653.0 2460997
宮城県 961768 1044036 1142784 1234801 1271238 1462254.0 1663442
長野県 1562722 1629217 1717118 1714000 1710729 2121050.0 2060831
1955年_総数 1960年_総数 1965年_総数 ... 1975年_総数 1980年_総数 1985年_総数 \
新潟県 2473492 2442037 2398931 ... 2391938 2451357 2478470
宮城県 1727065 1743195 1753126 ... 1955267 2082320 2176295
長野県 2021292 1981433 1958007 ... 2017564 2083934 2136927
1990年_総数 1995年_総数 2000年_総数 2005年_総数 2010年_総数 2015年_総数 2020年_総数
新潟県 2474583 2488364 2475733 2431459 2374450 2304264 2201272
宮城県 2248558 2328739 2365320 2360218 2348165 2333899 2301996
長野県 2156627 2193984 2215168 2196114 2152449 2098804 2048011
[3 rows x 21 columns]
次に、ランキングを計算します。計算した結果は、df1の新しい列として保存します。
for year in years:
for i,row in enumerate(df1.sort_values(by=year,ascending=False).iterrows()):
df1.loc[row[0],f"{year}_ranking"] = i+1
print(df1)
ランキングは各年で計算されるため、まずyearsでループします。2つ目のfor文のdf1.sort_valuesが人口でソートする処理です。by=yearによってソート対象の年を指定し、ascending=Falseで降順(大きい順)にします。iterrowsはその順番でソートされたデータを順番に取り出すというものです。取り出された順位が i , 県の名前が rowに入っています。そしてdf1.locによって新しいデータを追加しています。
実行すると次のように表示されます。
1920年_総数 1925年_総数 1930年_総数 1935年_総数 1940年_総数 1945年_総数 1950年_総数 \
新潟県 1776474 1849807 1933326 1995777 2064402 2389653.0 2460997
宮城県 961768 1044036 1142784 1234801 1271238 1462254.0 1663442
長野県 1562722 1629217 1717118 1714000 1710729 2121050.0 2060831
1955年_総数 1960年_総数 1965年_総数 ... 1975年_総数_ranking 1980年_総数_ranking \
新潟県 2473492 2442037 2398931 ... 1.0 1.0
宮城県 1727065 1743195 1753126 ... 3.0 3.0
長野県 2021292 1981433 1958007 ... 2.0 2.0
1985年_総数_ranking 1990年_総数_ranking 1995年_総数_ranking 2000年_総数_ranking \
新潟県 1.0 1.0 1.0 1.0
宮城県 2.0 2.0 2.0 2.0
長野県 3.0 3.0 3.0 3.0
2005年_総数_ranking 2010年_総数_ranking 2015年_総数_ranking 2020年_総数_ranking
新潟県 1.0 1.0 2.0 2.0
宮城県 2.0 2.0 1.0 1.0
長野県 3.0 3.0 3.0 3.0
df1に新しく列を追加したので、前からあった1920年_総数、などの列に加えて、xxxx年_総数_rankingという列が追加されています。1.0, 2.0, 3.0 のそれぞれの数値がランキングです。
最後にラインキングを描画します。
import matplotlib.pyplot as plt
import japanize_matplotlib
plot_data = df1.loc[:,filter(lambda l:"ranking" in l,df1.columns)].transpose().sort_values(by="2020年_総数_ranking",axis="columns")
print(plot_data)
fig,ax = plt.subplots(figsize=(6,4))
ax.plot(plot_data)
ax.set_xticks(range(len(years)))
ax.set_xticklabels(years,rotation=90)
ax.invert_yaxis()
ax.legend(plot_data.columns,bbox_to_anchor=(1.1,0.97))
plt.show()
まずはプロット用データとしてplot_dataを作成しています。これは、df1からランキングの列だけを抽出し、かつ、転置(transpose)をしています。転置とは行列の行と列を入れ替える処理です。さらに最後の年である2020年_総数_rankingでソートしています。このソートをしている理由は、ランキングチャートを描画したとき、グラフの最も右側になる最新のランキングの順番で各都道府県が並んでいた方が見やすいからです。
実行するとまず、描画用データ(plot_data)が表示されます。
宮城県 新潟県 長野県
1920年_総数_ranking 3.0 1.0 2.0
1925年_総数_ranking 3.0 1.0 2.0
1930年_総数_ranking 3.0 1.0 2.0
1935年_総数_ranking 3.0 1.0 2.0
1940年_総数_ranking 3.0 1.0 2.0
1945年_総数_ranking 3.0 1.0 2.0
1950年_総数_ranking 3.0 1.0 2.0
1955年_総数_ranking 3.0 1.0 2.0
1960年_総数_ranking 3.0 1.0 2.0
1965年_総数_ranking 3.0 1.0 2.0
1970年_総数_ranking 3.0 1.0 2.0
1975年_総数_ranking 3.0 1.0 2.0
1980年_総数_ranking 3.0 1.0 2.0
1985年_総数_ranking 2.0 1.0 3.0
1990年_総数_ranking 2.0 1.0 3.0
1995年_総数_ranking 2.0 1.0 3.0
2000年_総数_ranking 2.0 1.0 3.0
2005年_総数_ranking 2.0 1.0 3.0
2010年_総数_ranking 2.0 1.0 3.0
2015年_総数_ranking 1.0 2.0 3.0
2020年_総数_ranking 1.0 2.0 3.0
そしてそのあとにランキングチャートが表示されます。
完成版のプログラム
以下のプログラムは、すべての都道府県、すべての年におけるランキングチャートを描画するものです。prefs、years変数をデータ(df0)から抽出しています。グラフを描画するときには、xxxx年_rankingという列だけを抽出し、横軸が年、縦軸が順位となるようにデータを転置(行と列を入れ替えること)します。そして凡例とグラフ上の線との対応付けが少しでも分かりやすくなるようにグラフの右端になる2020年のランキングでデータをソートし、その順序で列になっている都道府県をソートします。
import matplotlib.pyplot as plt
import japanize_matplotlib
import re
# 全国を除外した都道府県名を作成する。
prefs = list(filter(lambda l:"全国" not in l,df0.index))
# 人口総数の取得年を作成する。
years = list(map(lambda l:re.findall(r"(.*)_.*",l)[0],
filter(lambda l:"総数" in l,df0.columns)))
# 都道府県ごとの人口総数のデータを抽出する。
data = df0.loc[prefs,filter(lambda l:"総数" in l,df0.columns)]
# 年ごとの人口ランキングを作成する。
for year in years:
# DataFrame.sort_valuesによって指定された年(year)の総数でソートする。
for i,row in enumerate(data.sort_values(by=f"{year}_総数",ascending=False).iterrows()):
# DataFrameに例えば1920年の人口ランキングならば「1920年_ranking」という名前の列を作成し、順位をセットする。
data.loc[row[0],f"{year}_ranking"] = i+1
# ここでDataFrameを確認すると、xxxx年_rankingという列が1920年から2020年までのが作成され、順位が数値として与えられている。
# print(data.head())
# print(data.loc[:,"2020年_ranking"].sort_values())
# 描画するためのデータは、rankingという名前の入った列を抽出してデータを転置する。
# 転置する前に列だったxxxx年_rankingは行になり、列は各都道府県となる。
# データは最後の年である2020年のランキングに従って列名(都道府県名)をソートする。これによりグラフ凡例との対応がしやすくなる。
plot_data = data.loc[:,filter(lambda l:"ranking" in l,data.columns)].transpose().sort_values(by="2020年_ranking",axis="columns")
# print(plot_data.head())
# ランキングチャートを描画する。
fig,ax = plt.subplots(figsize=(18,14))
ax.plot(plot_data)
# タイトルを設定する。
ax.set_title("人口の多さランキングチャート")
# x軸の軸メモリを設定する。
ax.set_xticks(range(len(years)))
ax.set_xticklabels(years,rotation=90)
# y軸ラベルは1と10の倍数とし、また反転してランキング上位が上になるようにする。
ax.set_yticks([1]+[10*(n+1) for n in range(int(len(prefs)/10))])
ax.invert_yaxis()
ax.set_ylabel("ランキング")
# 縦の補助線を入れる。
ax.grid(axis="x")
# 凡例を表示する。
ax.legend(plot_data.columns,bbox_to_anchor=(1.1,0.97))
plt.show()
実行すると次のようなグラフが表示されます。
東京都は1945年に一度だけ2位になっていますがそれ以外は1位をキープしています。2020年の2位である神奈川県は、1965年ごろから順位が上がり2010年にそれまで2位をキープしていた大阪府を抜いていることが分かります。