Блог им. Albus

Качаем данные Питоном: Всемирный банк

Всемирный банк выкладывает в открытый доступ тонны экономической статистики. Её можно скачивать, используя язык программирования Питон. Для этого Всемирный банк разработал питоновскую библиотеку wbank. Опишу как ею пользоваться. Писать буду так, чтобы получилось даже у человека, который из этого поста впервые узнал про Питон и Всемирный банк.
Полная документация (в этом посте она не понадобится)
---
Если вы не хотите программировать, то и не надо. Все данные можно получить и без питона и построить красивый график:
Вот, к примеру, ВВП России и Италии:
Качаем данные Питоном: Всемирный банк
Ссылка на этот показатель. Там можно выбирать любые страны. 
Но мы пойдём другим путём! Сложным! Этот путь позволяет строить графики любого вида и анализировать данные так гибко, как только вы захотите.
На выходе у нас получится такой график: ВВП по паритету крупнейших 10 стран мира. Скрипт сам понимает, какие страны крупнейшие:
Качаем данные Питоном: Всемирный банк
1. Устанавливаем Питон с сайта python.org
2. Открываем встроенную среду разработки. Это блокнот, в котором можно писать код и запускать его:
Качаем данные Питоном: Всемирный банк
Я этой средой разработки не пользуюсь, потому что она примитивная. Я использую Visual Studio 2019 (там есть питон) или Notepad++. Но для новичка подойдёт и эта. 
3. Устанавливаем библиотеки, которые потребуются при работе: matplotlib, wbdata. Для этого запускаем чёрное окошко cmd.exe  и пишем там:
pip install matplotlib (жмём Enter, ждём пока поставится)
а потом
pip install wbdata (жмём Enter, ждём пока поставится)
4. Подготовительная работа сделана. Теперь достаточно просто запустить код. Я его снабдил описанием почти в каждой строчке. Бросаем код в среду разработки (CTRL+V не работает, надо через Вставить)
Сохраняем код с любым названием, например вот так:
Качаем данные Питоном: Всемирный банк

Жмём F5 или запускаем как у меня:
Качаем данные Питоном: Всемирный банк
Всё должно заработать!
# -*- coding: utf-8 -*-
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter
import wbdata as wb
from datetime import *
import time
import collections
import operator

indicator="NY.GDP.MKTP.PP.KD" #код нужного индикатора. В данном случае это ВВП по паритету. Этот код можно взять с сайта Всемирного банка. Буквы в конце адреса: https://data.worldbank.org/indicator/NY.GDP.MKTP.PP.KD
all_countries=[] #в этот список положим все страны, которые есть в базе Всемирного банка.
bulk_years={} #сюда положим все страны и годы, за которые есть история по этому показателю.
for item in wb.get_country(): #wb.get_country()-функция позволяет закачать описание всех стран.
    region=item['region']['value'] #получаем географический регион
    if region!='Aggregates': #если прилетела не страна, а "Страны Африки" или "Ближний Восток", то в описании этого параметра будет слово 'Aggregates'. Игнорируем такие данные. Нам нужны только страны.  
        all_countries.append(item['iso2Code']) #добавили в all_countries очередной тикер страны.
print('Получили список всех стран')
print(all_countries)
print("Начинаем закачку большого массива данных с сайта Всемирного Банка. Ожидайте...")
for item in wb.get_data(indicator=indicator):#функцией wb.get_data получаем огромный объём сырых данных по этому индикатору (там много не нужного). Там будут все страны и регионы, все годы по выбранному показателю+куча левых полей. Сюда снова прольются не только страны, но и регионы типа "Юго-Восточная Азия". Их надо будет выбрасывать.
    id=item['country']['id'] #получаем id прилетевшей страны или региона. 
    if id in all_countries: #если этот id есть в нашем заготовленном списке стран all_countries, значит это страна. Мы его берём. Иначе - это регион, и он нам не нужен.
        strana=item['country']['value'] #получаем название страны.
        god=int(item['date']) #получаем прилетевший год
        znach=item['value'] #получаем прилетевшее значение ВВП по паритету. 
        if znach: #в некоторых случаях в качестве ВВП прилетает не цифра, а None - нет значения. None игнорируем.
            try: #в большом словаре bulk_years будут маленькие словари для каждой страны
                bulk_years[strana][god]=znach
            except KeyError: 
                bulk_years[strana]={}
                bulk_years[strana][god]=float(znach)
#Первая очистка данных завершена. bulk_years содержит полезные данные: страна, год, ВВП за этот год.  	
#Очистка данных продолжается. Сейчас самый свежий год, за который есть данные - 2017. Но полно стран, у которых последний год, за который подсчитан ВВП - 2011, 2013 или ещё раньше. Нам надо взять самый свежий год и составить более короткий словарь: "страна : самый свежий ВВП"
country_values={} #это и будет словарь "страна : самый свежий ВВП"
for k,v in bulk_years.items(): #перебираем предыдущий словарь.
	#здесь k - это страна, например Афганистан, v - мини-словарь "год : ВВП за этот год"
    max_year=0 #задаём обнуление года
    for x,y in v.items(): #перебираем мини-словарь. Ищем самый свежий год.
        if x>max_year:
            max_year=x
            value=y
    country_values[k]=float(value) #записываем ВВП за самый свежий год.
#Очистка данных полностью завершена. У нас получился словарь country_values с такими данными: {Страна : самый свежий ВВП}
print("Очистка завершена. Чистый словарь:")
for k,v in country_values.items():
	print(k+" : "+str(v))

#теперь полученный чистый массив надо отсортировать по убыванию. Самые крупные страны в начале, самые мелкие в конце:
sorted_d = sorted(country_values.items(), key=operator.itemgetter(1), reverse = True)
#нам нужны не все страны, а только 10 самых крупных.
sorted_d=sorted_d[0:10] #это новый список из 10 самых крупных стран. Внутри списка сидят кортежи вида "страна, ВВП". Кортеж - это список, который нельзя изменить.
print("Самые крупные страны определены:")
print(sorted_d) #
x=[] #в этот список запишем названия стран. Это горизонтальная ось.
y=[] #в этот список запишем значения ВВП. Это вертиальная ось.
for _tuple in sorted_d: #перебираем кортежи внутри списка. 
    strana=_tuple[0] #получили страну
    if strana=='Russian Federation': 
        strana='Russia'
    pokazatel=_tuple[1] #получили ВВП
    y.append(pokazatel) #записали ВВП для рисования на вертикальной оси.
    x.append(strana) #записали страну для рисования на горизонтальной оси.

#Эта функция превратит триллионы на вертикальной оси в надписи 5 Trill, 10 Trill 
def trillions(x, pos):
    'The two args are the value and tick position'
    return '$%1.1i Trill' % (x * 1e-12) #trillions
formatter = FuncFormatter(trillions)
fig, ax = plt.subplots()
ax.yaxis.set_major_formatter(formatter)
plt.xlabel('Страны', fontsize=10) #рисуем подпись на горизонтальной оси.
plt.ylabel('ВВП', fontsize=10)#рисуем подпись на вертикальной оси.
plt.bar(x, y) #формируем столбики диаграммы.
plt.title('ВВП по ППС (Всемирный банк), трлн.$', fontsize=20) #заголовок графика

for i, v in enumerate(x): #в центр каждого столбика запишем значение ВВП.
    val=round(y[i]/1000000000000,1)
    plt.text(i,y[i]/2, val, color='white', ha='center', fontweight='bold', fontsize=18)
plt.show() #показать график на экране.
#ВСЁ!
Удачи в освоении Питона!
★48
26 комментариев
Плюс. А в торговле используете? Или практики ради?
avatar
fireburned, использую в работы на ТВ, но не в торговле. 
Эх, если б не развал СССР и не 90-е...
Картинка с Италией прям в душу ударила.
avatar
VladMih, да, у Италии в экономике жесть конкретная.
Albus (Игорь Китаев), а я html css на старости лет начал осваивать))
Дед Панас, если хотите научится программировать, начинайте с «настоящего» программирования. Это будет проще, потому что «простые языки», типа языков разметки и CSS, на самом деле не учат настоящему программированию, а изучать вы это запаритесь потому что они забубенные. Их и программисты толком не знают, это вообще отдельная профессия верстальщика
Для программирования в браузере можете взять джаваскрипт, там все так же подключается как и в этом Вашем CSS.
sortarray sortarray, именно джаваскрипт следующий этап
VladMih, плюсую виртуально. Очень жестко нас об стенку шарахнули.
avatar
максимальная гибкость достигается как раз отрисовкой сырых данных, а не API языка или библиотекой. Последние всегда содержат фиксированный набор возможностей.
Что дали, тем и пользуетесь, какие функции реализованы, такие доступны
sortarray sortarray,

ну давай-ка попробуй сделать тоже самое без wbdata api 
Сергей Пупкин, всегда есть какой то API, чем выше, тем менее гибкий:)
Можно anaconda поставить, но весит больше, там эти библиотеки должны и так быть, а за код спасибо!
Отличная тема :)
avatar
да, питон хорош.
я ещё jupyter notebook освоил. рекомендую.
позволяет исполнять код по кусочкам,
ставится не сложнее самого питона.
после этого можно импортить всякие датасайенс проекты прямо в виде jupyther notebook
avatar
ПBМ, поддерживаю!!.. с помощью панды, матплотлиба и сиборна можно много чего посмотреть и графики получить…
avatar
большие данные это мирные данные

big data is peace data
Ничего не понял
avatar
TypeError                                 Traceback (most recent call last)
<ipython-input-4-c9c4a134e93c> in <module>
     12 all_countries=[] #в этот список положим все страны, которые есть в базе Всемирного банка.
     13 bulk_years={} #сюда положим все страны и годы, за которые есть история по этому показателю.
---> 14 for item in wb.get_country(): #wb.get_country()-функция позволяет закачать описание всех стран.
     15     region=item['region']['value'] #получаем географический регион
     16     if region!='Aggregates': #если прилетела не страна, а "Страны Африки" или "Ближний Восток", то в описании этого параметра будет слово 'Aggregates'. Игнорируем такие данные. Нам нужны только страны.

TypeError: 'NoneType' object is not iterable<br /><br />Ошибку где-то выдает
 
Ходжа Насреддин, странно
wb.get_country()
выдала значение None (пустота). Может быть у вас интернет прерывается и комп не может достучаться до сервера.
Ходжа Насреддин, попробуйте запустить код из 2 строчек

import wbdata as wb
print(wb.get_country())

что он интересно выдаст.
Albus (Игорь Китаев), ABW Aruba AFG Afghanistan A ( список стран) XZN Sub-Saharan Africa excluding South Africa and Nigeria YEM Yemen, Rep. ZAF South Africa ZMB Zambia ZWE Zimbabwe None
На этом программа прервалась
Ходжа Насреддин, не понимаю в чём может быть проблема. У меня этот код из 2 строчек отрабатывает как надо, а у вас после слова Zimbabwe идёт почему то None — отсутствующее значение.



Снес первую часть кода со странами, дальше прога пошла. Но данных нет. Выдал пустой график с ППС. Если найду ошибку, выложу код.
Ходжа Насреддин, эту строчку:

Перепишите в таком виде:

И скорее всего заработает, но выдаст рейтинг вместе с регионами типа «Весь мир», «Страны Америки», «Ближний Восток»
Albus (Игорь Китаев), Запустил в Spyder 3, все пошло. Jypter тупит где-то, возможно из-за запуска в браузере

теги блога Albus (Игорь Китаев)

....все тэги



UPDONW
Новый дизайн