1949年から2013年までの、UFOを発見したという情報をまとめたデータセットがあるようです(有名のようです)。
- 基本的に発見日時
- 発見した町
- 州
- 国名
- UFOの形
- (おそらく)目撃した時間[sec]
- (おそらく)目的した時間[hours or min]
- 目撃談(コメント)
- 情報提供日
- 発見した場所の緯度
- 発見した場所の経度
なので、このデータセットの国名の列を使って、「国別UFO発見件数の年間推移グラフ」を作ってみたいと思います。
試すにあたり、以下の分析事例を参考にしました。
やってみる
データセットの準備
データセットはここにあります。(Kaggleのアカウントを作成する必要があります。無料です。)
データセットは以前セットアップしたときに用意したdataフォルダに配置。
データ読み込みおよびクリーンアップ
まずデータを読み込み。
import pandas as pd
#CSVファイル読み込み
df= pd.read_csv('../data/ufo_sighting/scrubbed.csv')
print(df_area.head())
Warningが出ますがそのまま進みます。
datetime列の時刻において、深夜0時の表記が24:00になっているため、今後時間データとして利用しやすくするため、これを00:00に変換。
また、Country列には空白セルも含まれるため、そこには「Unknown」という文字列を挿入。
df['datetime'] = df['datetime'].str.replace('24:00', '00:00')
df['country'].fillna('Unknown')
print(df.info())
出力結果は以下。
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 80332 entries, 0 to 80331
Data columns (total 11 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 datetime 80332 non-null object
1 city 80332 non-null object
2 state 74535 non-null object
3 country 70662 non-null object
4 shape 78400 non-null object
5 duration (seconds) 80332 non-null object
6 duration (hours/min) 80332 non-null object
7 comments 80317 non-null object
8 date posted 80332 non-null object
9 latitude 80332 non-null object
10 longitude 80332 non-null float64
dtypes: float64(1), object(10)
memory usage: 6.7+ MB
None
datetime列は今のところobjectタイプのため、これをdatetime型に変換して、さらにインデックスに指定。
df['datetime'] = pd.to_datetime(df['datetime'])
df = df.set_index('datetime')
print(df.info())
出力結果は以下。
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 80332 entries, 1949-10-10 20:30:00 to 2013-09-09 23:00:00
Data columns (total 11 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 city 80332 non-null object
<略>
これでdatetime列を時系列として扱えるようになりました。
全体でみるUFO目撃数の年毎の推移
ここでとりあえず、国別ではなく、全体で見た年間のUFO目撃件数を出してみる。
import matplotlib
import matplotlib.pyplot as plt
# 日本語フォントを指定(文字化け対策)。
matplotlib.rcParams['font.family'] = 'MS Gothic'
# データセットにcount列を追加し、すべてのセルに1を代入。(この次の集計用に使う)
df['count'] = 1
# count列を、年毎にグループ化し、それにグラフのタイトルと汎用を付けて折れ線グラフとしてプロット。
df['count'].groupby(pd.Grouper(freq='A')).sum().plot(label="年毎のUFO目撃件数").legend()
すると以下のグラフを得られる。
1970年ごろにじわじわと報告が上がり始め、1995年から急激に目撃件数が増えている模様。
国別のUFO目撃件数年毎推移
count列を追加し、年毎にその値(すなわち1)を合計することで、年毎のレコード件数合計を出す作戦。
df_temp = pd.DataFrame()
# データセットのCountry列から、重複排除して国名を取得
for column_name,item in df['country'].drop_duplicates().reset_index().iterrows():
print(item[1])
# 取得した国名のみ該当するデータフレームを取得
df_country = df[df['country'] == item[1]]
# 取得した国名に絞って、先と同様年間件数を集計し、df_tempに国名をインデックスとして格納する。
df_temp[item[1]] = df_country['count'].groupby([pd.Grouper(freq='A')]).sum()
# この時点で国別、年毎のレコード合計件数が揃ったことになる。そのままplotしてみる。
df_temp.plot(title="国別UFO発見件数の年間推移").legend()
すると以下のグラフが得られる。
us(米国)のUFO発見件数ががダントツ。1995年からの急激な伸びも、米国のデータが牽引していた模様。このデータと出自はNUFORC(National UFO Reporting Center)という組織らしいのですが、組織のURLにアクセスしてみたけど、タイムアウトでアクセスできませんでした。(データを本格的に収集したのが1995年から、、とか理由を探ってみたかったです)
あとおまけで、国別のUFO発見合計件数も出してみました。
df[['country']].groupby('country').value_counts().plot.bar(title="国別UFO発見件数").grid()
年毎などの単位ではなく、国ごとに全件集計ということであれば、value_counts()が便利な模様。以下のグラフが得られる。
終わりに
このデータセットにはほかにも緯度経度や、発見したUFOに関する概要、UFOの形状などもあるので、また別の切り口でも分析を続けてみたいです。(ここまでの分析プロセスもやっぱりエクセルのほうが絶対速いので、ジオデータから地図上にプロットなどができるとこういう分析ツールの優位性を実感できると思いました)