Skip to content

Commit 771d492

Browse files
committed
adding parser for econdb
1 parent b9f809f commit 771d492

File tree

4 files changed

+129
-1
lines changed

4 files changed

+129
-1
lines changed

docs/source/readers/econdb.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Econdb
2+
--------
3+
4+
.. py:module:: pandas_datareader.econdb
5+
6+
.. autoclass:: EcondbReader
7+
:members:
8+
:inherited-members:

pandas_datareader/data.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from pandas_datareader.av.sector import AVSectorPerformanceReader
1010
from pandas_datareader.av.time_series import AVTimeSeriesReader
1111
from pandas_datareader.bankofcanada import BankOfCanadaReader
12+
from pandas_datareader.econdb import EcondbReader
1213
from pandas_datareader.enigma import EnigmaReader
1314
from pandas_datareader.eurostat import EurostatReader
1415
from pandas_datareader.exceptions import DEP_ERROR_MSG, \
@@ -310,7 +311,7 @@ def DataReader(name, data_source=None, start=None, end=None,
310311
"tiingo", "yahoo-actions", "yahoo-dividends",
311312
"av-forex", "av-daily", "av-daily-adjusted",
312313
"av-weekly", "av-weekly-adjusted", "av-monthly",
313-
"av-monthly-adjusted"]
314+
"av-monthly-adjusted", "econdb"]
314315

315316
if data_source not in expected_source:
316317
msg = "data_source=%r is not implemented" % data_source
@@ -466,6 +467,11 @@ def DataReader(name, data_source=None, start=None, end=None,
466467
retry_count=retry_count, pause=pause,
467468
session=session, api_key=access_key).read()
468469

470+
elif data_source == "econdb":
471+
return EcondbReader(symbols=name, start=start, end=end,
472+
retry_count=retry_count, pause=pause,
473+
session=session).read()
474+
469475
else:
470476
msg = "data_source=%r is not implemented" % data_source
471477
raise NotImplementedError(msg)

pandas_datareader/econdb.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import requests
2+
import pandas as pd
3+
import pandas.compat as compat
4+
5+
from pandas_datareader.base import _BaseReader
6+
7+
8+
class EcondbReader(_BaseReader):
9+
"""Get data for the given name from Econdb."""
10+
11+
_URL = 'https://www.econdb.com/api/series/'
12+
_format = None
13+
_show = 'labels'
14+
15+
@property
16+
def url(self):
17+
"""API URL"""
18+
if not isinstance(self.symbols, compat.string_types):
19+
raise ValueError('data name must be string')
20+
21+
return ('{0}?{1}&format=json&page_size=500&expand=meta'
22+
.format(self._URL, self.symbols))
23+
24+
def read(self):
25+
""" read one data from specified URL """
26+
results = requests.get(self.url).json()['results']
27+
df = pd.DataFrame({'dates': []}).set_index('dates')
28+
29+
for entry in results:
30+
head = entry['additional_metadata']
31+
series = (pd.DataFrame(entry['data'])[['dates', 'values']]
32+
.set_index('dates'))
33+
if self._show == 'labels':
34+
def show_func(x): return x.split(':')[1]
35+
elif self._show == 'codes':
36+
def show_func(x): return x.split(':')[0]
37+
38+
series.columns = pd.MultiIndex.from_tuples(
39+
[[show_func(x) for x in head.values()]],
40+
names=[show_func(x) for x in head.keys()])
41+
42+
if not df.empty:
43+
df = df.join(series, how='outer')
44+
else:
45+
df = series
46+
df.index = pd.to_datetime(df.index, errors='ignore')
47+
df.index.name = 'TIME_PERIOD'
48+
df = df.truncate(self.start, self.end)
49+
return df
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import numpy as np
2+
import pandas as pd
3+
import pandas.util.testing as tm
4+
import pandas_datareader.data as web
5+
6+
7+
class TestEcondb(object):
8+
9+
def test_get_cdh_e_fos(self):
10+
# EUROSTAT
11+
# Employed doctorate holders in non managerial and non professional
12+
# occupations by fields of science (%)
13+
df = web.DataReader(
14+
'dataset=CDH_E_FOS&GEO=NO,PL,PT,RU&FOS07=FOS1&Y_GRAD=TOTAL',
15+
'econdb',
16+
start=pd.Timestamp('2005-01-01'),
17+
end=pd.Timestamp('2010-01-01'))
18+
assert isinstance(df, pd.DataFrame)
19+
assert df.shape == (2, 4)
20+
21+
df = df['Natural sciences']['Annual'][
22+
['Norway', 'Poland', 'Portugal', 'Russia']]
23+
24+
exp_col = pd.MultiIndex.from_product(
25+
[['Norway', 'Poland', 'Portugal', 'Russia'],
26+
['Percentage'], ['Total']],
27+
names=['Geopolitical entity (reporting)', 'Unit of measure',
28+
'Year of graduation'])
29+
exp_idx = pd.DatetimeIndex(['2006-01-01', '2009-01-01'],
30+
name='TIME_PERIOD')
31+
32+
values = np.array([[25.49, np.nan, 39.05, np.nan],
33+
[20.38, 25.1, 27.77, 38.1]])
34+
expected = pd.DataFrame(values, index=exp_idx, columns=exp_col)
35+
tm.assert_frame_equal(df, expected)
36+
37+
def test_get_tourism(self):
38+
# OECD
39+
# TOURISM_INBOUND
40+
41+
df = web.DataReader(
42+
'dataset=OE_TOURISM_INBOUND&COUNTRY=JPN,USA&'
43+
'VARIABLE=INB_ARRIVALS_TOTAL', 'econdb',
44+
start=pd.Timestamp('2008-01-01'), end=pd.Timestamp('2012-01-01'))
45+
df = df.astype(np.float)
46+
jp = np.array([8351000, 6790000, 8611000, 6219000,
47+
8368000], dtype=float)
48+
us = np.array([175702309, 160507417, 164079732, 167600277,
49+
171320408], dtype=float)
50+
index = pd.date_range('2008-01-01', '2012-01-01', freq='AS',
51+
name='TIME_PERIOD')
52+
for label, values in [('Japan', jp), ('United States', us)]:
53+
expected = pd.Series(values, index=index,
54+
name='Total international arrivals')
55+
tm.assert_series_equal(df[label]['Total international arrivals'],
56+
expected)
57+
58+
def test_bls(self):
59+
# BLS
60+
# CPI
61+
df = web.DataReader(
62+
'ticker=BLS_CU.CUSR0000SA0.M.US', 'econdb',
63+
start=pd.Timestamp('2010-01-01'), end=pd.Timestamp('2013-01-27'))
64+
65+
assert df.loc['2010-05-01'][0] == 217.3

0 commit comments

Comments
 (0)