「みえない交差点」でPython学習!

警視庁が公開している交通事故統計情報のオープンデータを使って、データ分析の学習をしました!kaggle上のPythonを使えば、スマホのブラウザだけでPythonの記述と実行ができてしまい、超便利でした!処理自体はkaggleのクラウドリソースを使うので、動きも軽快!ごくたまに接続が切れることがありますが、保存もバッチリ👍

さて、今回使った警視庁の交通事故統計情報ですが、朝日新聞の「見えない交差点」という記事をきっかけに知りました!

この記事では、前述のオープンデータをデータ分析することで、警視庁がまだ見つけていない危険な交差点を見つけ出していました。このデータ分析は確かPythonで行われている(はず)ので、これはデータ分析の学習にピッタリでした!以下に、私が頑張って分析に使ったPythonコードを書きます!使用するオープンデータは、下記の警視庁のサイトです!

まずはpandasライブラリのインポートから!

import pandas as pd

次は使用するデータの取り込み!ここでクラウドならではの良さが発揮されます!使用するデータは50MB越えのファイルなのですが、Pythonを動かすクラウドリソースへ直接取り込まれるので、とても動きが速いです!

op_df=pd.read_csv\
("https://www.npa.go.jp/\
publications/\
statistics/koutsuu/\
opendata/2020/\
honhyo_2020.csv",\
 encoding="shift-jis")

ここで注意なのが、列名が日本語表記であること。このため、「encoding=“shift-jis”」を関数につけてあげないと、文字化けしてしまいます。

続いて、データを加工するにあたって、列名を確認していきます。以下のコードで列名を取得しました。

op_df.columns

取得結果は次のようになりました。

Index(['資料区分', '都道府県コード', '警察署等コード', '本票番号', '事故内容', '死者数', '負傷者数', '路線コード','上下線', '地点コード', '市区町村コード', '発生日時  年', '発生日時  月', '発生日時  日', '発生日時  時','発生日時  分', '昼夜', '天候', '地形', '路面状態', '道路形状', '環状交差点の直径', '信号機','一時停止規制 標識(当事者A)', '一時停止規制 表示(当事者A)', '一時停止規制 標識(当事者B)','一時停止規制 表示(当事者B)', '車道幅員', '道路線形', '衝突地点', 'ゾーン規制', '中央分離帯施設等', '歩車道区分','事故類型', '年齢(当事者A)', '年齢(当事者B)', '当事者種別(当事者A)', '当事者種別(当事者B)','用途別(当事者A)', '用途別(当事者B)', '車両形状(当事者A)', '車両形状(当事者B)','速度規制(指定のみ)(当事者A)', '速度規制(指定のみ)(当事者B)', '車両の衝突部位(当事者A)','車両の衝突部位(当事者B)', '車両の損壊程度(当事者A)', '車両の損壊程度(当事者B)', 'エアバッグの装備(当事者A)','エアバッグの装備(当事者B)', 'サイドエアバッグの装備(当事者A)', 'サイドエアバッグの装備(当事者B)','人身損傷程度(当事者A)', '人身損傷程度(当事者B)', '地点 緯度(北緯)', '地点 経度(東経)', '曜日(発生年月日)','祝日(発生年月日)'],dtype='object')

かなりたくさんの列があります。私はまだまだ初学者なので、一部のデータだけ使っていきます。そのデータとして、「都道府県コード」「市区町村コード」「路線コード」「曜日(発生年月日)」を選択します。併せて扱いやすくするため、列名を英語表記に変えておきます。

op_df_area=op_df[["都道府県コード",\
                 "市区町村コード",\
                 "路線コード",\
                 "地点コード",\
                 "曜日(発生年月日)"]]
op_df_area.columns=\
["pref_code",\
"city_code",\
"road_code",\
"place_code",\
"weekday"]
op_df_area.head(5)

実行の結果、得られたDataFrameの一部が次になります!これを「抽出データ」と呼ぶことにします。

続いて「都道府県コード」を都道府県名に変換していきます。変換には、上記の警視庁WEBサイトの「各種コード表」を使います。以下のコードで変換をかけます。

#convert_pref_code
pref_code_conv=\
[[10,"10_hokkaido_sapporo"],\
[11,"11_hokkaido_hakodate"],\
[12,"12_hokkaido_asahikawa"],\
[13,"13_hokkaido_kushiro"],\
[14,"14_hokkaido_kitami"],\
[20,"20_aomori"],\
[21,"21_iwate"],\
[22,"22_miyagi"],\
[23,"23_akita"],\
[24,"24_yamagata"],\
[25,"25_fukushima"],\
[30,"30_tokyo"],\
[40,"40_ibaraki"],\
[41,"41_tochigi"],\
[42,"42_gunma"],\
[43,"43_saitama"],\
[44,"44_chiba"],\
[45,"45_kanagawa"],\
[46,"46_niigata"],\
[47,"47_yamanashi"],\
[48,"48_nagano"],\
[49,"49_shizuoka"],\
[50,"50_toyama"],\
[51,"51_ishikawa"],\
[52,"52_fukui"],\
[53,"53_gifu"],\
[54,"54_aichi"],\
[55,"55_mie"],\
[60,"60_shiga"],\
[61,"61_kyoto"],\
[62,"62_osaka"],\
[63,"63_hyogo"],\
[64,"64_nara"],\
[65,"65_wakayama"],\
[70,"70_tottori"],\
[71,"71_shimane"],\
[72,"72_okayama"],\
[73,"73_hiroshima"],\
[74,"74_yamaguchi"],\
[80,"80_tokushima"],\
[81,"81_kagawa"],\
[82,"82_ehime"],\
[83,"83_kochi"],\
[90,"90_fukuoka"],\
[91,"91_saga"],\
[92,"92_nagasaki"],\
[93,"93_kumamoto"],\
[94,"94_oita"],\
[95,"95_miyazaki"],\
[96,"96_kagoshima"],\
[97,"97_okinawa"]]
conv_df=pd.DataFrame(pref_code_conv)
conv_df.columns=["pref_code","pref_name"]
conv_df

上記コードで変換用のDataFrameを作りました。以下が生成したDataFrameです。

上記DataFrameを「抽出データ」にmergeすることで、「都道府県コード」を都道府県名に変換します。

op_df_area=\
pd.merge(op_df_area,\
        conv_df,\
        on="pref_code",\
        how="left")
op_df_area

mergeした結果、以下のDataFrameが得られました。

これで、簡単な集計の準備が整いました。次のコードを実行することで、集計とグラフ化を行います。

op_df_area_g=\
op_df_area[["pref_name",\
           "weekday",\
           "city_code"]]\
.groupby(["pref_name",\
         "weekday"])\
.count().unstack()
op_df_area_g.plot.barh\
(stacked=True,figsize=(5,18))

上記コードで都道府県名と曜日でクロス集計を行った後、積み上げ棒グラフとして出力しています。出力結果は次のとおりです。

1:日曜、2:月曜、3:火曜、4:水曜、5:木曜、6:金曜、7:土曜

結果としては、当然人口の密集している首都圏中心に、栄えている都市で交通事故発生件数が多いことが示されました。では、曜日ごとに発生件数の違いってあるのでしょうか?

そこで、交通事故発生件数のうちの曜日ごとの比率を出し、同じくグラフ化してみました。都道府県ごとに交通事故と曜日で発生頻度に関連性はあるのでしょうか?

op_df_area_g_rate=\
op_df_area_g.copy()
for n in range(1,8):
    op_df_area_g_rate["city_code",n]=\
    op_df_area_g_rate["city_code",n]/\
    (op_df_area_g["city_code",1]+\
    op_df_area_g["city_code",2]+\
    op_df_area_g["city_code",3]+\
    op_df_area_g["city_code",4]+\
    op_df_area_g["city_code",5]+\
    op_df_area_g["city_code",6]+\
    op_df_area_g["city_code",7])

op_df_area_g_rate.plot.barh\
(stacked=True,figsize=(5,18))

上記コードでは、1週間通しての事故発生件数で各曜日の発生件数を割っています。DataFrameはあらかじめコピーして、新しい変数の中で扱っています。

1:日曜、2:月曜、3:火曜、4:水曜、5:木曜、6:金曜、7:土曜

グラフを出力した結果、地域を問わず、曜日ごとの事故発生件数の比率の大差はないように見えます。意外でした。地域ごとに大きな差がありそうな気がしていたのですけども、予想外の結果でした。ただ全体を通して共通に言えるのは、日曜の交通事故発生件数が比較的他の曜日よりも少ないことでした。皆さん家にいるからですかね。細かく分析すれば何か出てくるかもしれませんが、今回はそこまでしません。

今回のデータ分析はここまでです。朝日新聞さんの「みえない交差点」ではまだまだたくさんの分析がなされているので、これからもそういった分析を自分でできるよう、Pythonを学習していきたいです!

この記事が気に入ったらサポートをしてみませんか?