FACTFULNESSのチャートを再現する、、前処理

こちらのブログ(↓)に触発されて、私も FACTFULNESS で紹介されているチャートを自分で再現してみようと思い立ちました。
チャート再現:書籍「FACTFULNESS(ファクトフルネス)」やTED talkで有名なハンス・ロスリング

gapminder のサイトに行けば、各種データが用意されていますが、(私が探した限り)どの国が、どの大陸に属しているかという対照表は用意されていないようです。

仕方ないので、自分で対照表を作りました。作り方は、備忘録を兼ねて下に書きますが、対照表だけ欲しいという人もいるかもしれないので、DLできるようにしておきました。

データは、こんな具合になってます。

国と大陸対照表

A列は、特に意味がないので、読み込むときに削除してもらえればOKです。
B列が、英語の国名。gapminder のデータと対応しています。
C列は、国名を2文字に略したコード
D列は、その国が属する大陸を示す2文字のコード、となっています。

これを作るにあたり、Maxmind という会社が公開しているデータをお借りしました。ありがとうございました。

国名の2文字コードと大陸名の2文字コードの対応表
https://dev.maxmind.com/geoip/legacy/codes/country_continent/ 
国名の2文字コードと、国名の対応表 
https://dev.maxmind.com/geoip/legacy/codes/iso3166/

対照表作成手順

1.Maxmindの「国名の2文字コードと、国名の対応表 」上の国名と、
  gapminder のデータの「国名」が一致しているかを確認。

Maxmindの「国名の2文字コードと、国名の対応表 」 → country_list 
gapminder の各国の人口データ → ppl 
 へと読み込む。

この際、 keep_default_na=False というオプション設定が必要。
Namibiaの略称がNAなのだが、オプションを付けないと、NaN (Not A Number ) として扱われてしまうため、上手く処理できないのだ。

import pandas as pd

path = './data/iso3166.csv'
country_list = pd.read_csv(path, keep_default_na=False)

path = './data/population_total.csv'
ppl = pd.read_csv(path, index_col=0)

ちなみに、それぞれ、こんな形の DataFrameになっている。
country_list の1列目が、国名の略称
country_list の2列目が、国名  ですね。

画像3

画像2

ppl.index

Index(['Afghanistan', 'Albania', 'Algeria', 'Andorra', 'Angola',
      'Antigua and Barbuda', 'Argentina', 'Armenia', 'Australia', 'Austria',
      ...
      'United Kingdom', 'United States', 'Uruguay', 'Uzbekistan', 'Vanuatu',
      'Venezuela', 'Vietnam', 'Yemen', 'Zambia', 'Zimbabwe'],
     dtype='object', name='country', length=195)

ppl の country に記載された国名と、完全に一致するものが、country_list にあれば良いけれど、別の人が作ったリストなので、完全に一致するハズはない。
一致しているものと、そうでないものを選り分けてみる。

hit = []
no_hit = []
code = []

for country_name in ppl.index:
       if len(country_list[country_list['Anonymous Proxy']==country_name]) == 1:
           hit.append(country_name)
           code.append(country_list[country_list['Anonymous Proxy']==country_name].iloc[0,0])
       else:
           no_hit.append(country_name)

こうして処理すると、、ppl 上の国名 (195) の内、
country_list上にあるもの 174個
country_list上にないもの  21個  という結果に。

no_hit

['Brunei',
'Congo, Dem. Rep.',
'Congo, Rep.',
'Holy See',
'Iran',
'Kyrgyz Republic',
'Lao',
'Libya',
'Micronesia, Fed. Sts.',
'Moldova',
'North Korea',
'North Macedonia',
'Palestine',
'Russia',
'Slovak Republic',
'South Korea',
'St. Kitts and Nevis',
'St. Lucia',
'St. Vincent and the Grenadines',
'Syria',
'Tanzania']

21個のデータなら、手打ちで入力した方が速いので、まずは、一致したものをcsvに出力。(ちなみに、一致しなかったものは "Russia" vs "Russian Federation",   "South Korea" vs "Korea, Republic of" 等)

countryDF = pd.DataFrame({
   'name' : hit,
   'code' : code})

countryDF.to_csv('data/country_code.csv', encoding='cp932')

country_code.csv に、21件分のデータを手入力して
country_code2.csv  というファイルを作成し、読み込む。

countryDF2 = pd.read_csv('data/country_code2.csv', keep_default_na=False, encoding='cp932')


画像4

これでやっと、国名に2文字コードを対応させることができた。
次に、2文字コードと大陸のコードを対応させる。

path = './data/country_continent.csv'
continent_list = pd.read_csv(path, keep_default_na=False)
continent_list.columns = ['code', 'continent_code']

countryDF2 に格納されている 国名コードが、continent_list の code に含まれているかを確認。

continent_list_code = set(continent_list['code'])
countryDF2_code = set(countryDF2['code'])
countryDF2_code - continent_list_code

画像5

South Sudan の国名コード SS が、continent_list に含まれていなかった。

max(continent_list.index)
continent_list.loc[252]=['SS','AF']
continent_list[continent_list['code']=='SS']

画像6

あとは、countryDF2 とcontinent_list を結合すれば、対照表が出来上がる。

country_continentDF = pd.merge(countryDF2, continent_list, on='code', how='left')

country_continentDF.head()

画像7

country_continentDF.to_csv('data/country_to_ContinentCode.csv', encoding='cp932')

これを、csvに保存すれば、冒頭でDLできるようにした対照表の出来上がり!

欠損値の確認と穴埋めが、色々と大変でした~~


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