import imfp
import pandas as pd
# Set float format to 2 decimal places for pandas display output
'display.float_format', lambda x: '%.2f' % x)
pd.set_option(
imfp.imf_dataset(database_id)
Working with Parameters
Filtering IMF Dataset Requests with Parameters
Once you have a database_id
, it’s possible to make a call to imf_dataset
to fetch the entire database:
However, while this will succeed for a few small databases, it will fail for all of the larger ones. And even in the rare case when it succeeds, fetching an entire database can take a long time. You’re much better off supplying additional filter parameters to reduce the size of your request.
Requests to databases available through the IMF API are complicated by the fact that each database uses a different set of parameters when making a request. (At last count, there were 43 unique parameters used in making API requests from the various databases!) You also have to have the list of valid input codes for each parameter. The imf_parameters
function solves this problem. Use the function to obtain the full list of parameters and valid input codes for a given database.
Understanding Filter Parameters
Each database available through the IMF API has its own set of parameters that can be used to filter and specify the data you want to retrieve.
Each parameter will be a column in the data. Each row in the data will contain a value for that parameter. The parameter will always be a categorical variable, meaning that it can take only a limited set of values. We refer to these values as “input codes,” because you can input them in your API request to filter the data.
What this means, though, is that before making an API request to retrieve data, you need to know what the available filtering parameters are for the database, and what codes you can use for filtering the data by each parameter.
There are two main functions for working with parameters:
imf_parameters()
: Get the full list of parameters and valid input codes for a databaseimf_parameter_defs()
: Get text descriptions of what each parameter represents
Discovering Available Parameters
To get started, you’ll need to know what parameters are available for your chosen database. Use imf_parameters()
to get this information:
import imfp
# Fetch list of valid parameters for the Primary Commodity Price System database
= imfp.imf_parameters("PCPS")
params
# View the available parameter names
params.keys()
dict_keys(['freq', 'ref_area', 'commodity', 'unit_measure'])
The function returns a dictionary of data frames.
Each key in the dictionary corresponds to a parameter used in making requests from the database. The value for each key is a data frame with the following columns:
input_code
: The valid codes you can use for that parameterdescription
: A short text description of what each code represents
For example, to see the valid codes for the freq
(frequency) parameter:
# View the data frame of valid input codes for the frequency parameter
'freq'] params[
input_code | description | |
---|---|---|
0 | A | Annual |
1 | M | Monthly |
2 | Q | Quarterly |
Parameter Definitions
If the parameter name is not self-explanatory, you can use the imf_parameter_defs()
function to get a text description of what each parameter represents.
# Get descriptions of what each parameter means
= imfp.imf_parameter_defs("PCPS")
params_defs
params_defs
parameter | description | |
---|---|---|
0 | freq | Frequency |
1 | ref_area | Geographical Areas |
2 | commodity | Indicator |
3 | unit_measure | Unit |
Supplying Parameters
Basic Approach (Recommended for Most Users)
To make a request to fetch data from the IMF API, just call imf_dataset
with the database ID and keyword arguments for each parameter, where the keyword argument name is the parameter name and the value is the list of codes you want.
For instance, on exploring the freq
parameter of the Primary Commodity Price System database above, we found that the frequency can take one of three values: “A” for annual, “Q” for quarterly, and “M” for monthly. Thus, to request annual data, we can call imf_dataset
with freq = ["A"]
.
Here’s a complete example that fetches annual coal prices for the years 2000 through 2015:
# Example: Get annual coal prices
= imfp.imf_dataset(
df ="PCPS",
database_id=["A"], # Annual frequency
freq=["PCOAL"], # Coal prices
commodity=2000,
start_year=2015
end_year )
Advanced Approaches
For more complex queries, there are two programmatic ways to supply parameters to imf_dataset
. These approaches are particularly useful when you need to filter parameters based on their descriptions or when working with multiple parameter values.
1. List Arguments with Parameter Filtering
This approach uses string matching to find the correct parameter codes before passing them to imf_dataset
:
# Fetch the input code column of the freq parameter...
= list(
selected_freq 'freq']['input_code'][
params[# ...where the description contains "Annual"
'freq']['description'].str.contains("Annual")
params[
]
)
# Fetch the input code column of the commodity parameter...
= list(
selected_commodity 'commodity']['input_code'][
params[# ...where the description contains "Coal"
'commodity']['description'].str.contains("Coal")
params[
]
)
# Fetch the input code column of the unit_measure parameter...
= list(
selected_unit_measure 'unit_measure']['input_code'][
params[# ...where the description contains "Index"
'unit_measure']['description'].str.contains("Index")
params[
]
)
# Request data from the API using the filtered parameter code lists
= imfp.imf_dataset(
df ="PCPS",
database_id=selected_freq,
freq=selected_commodity,
commodity=selected_unit_measure,
unit_measure=2000,
start_year=2015
end_year
)
df.head()
freq | ref_area | commodity | unit_measure | unit_mult | time_format | time_period | obs_value | |
---|---|---|---|---|---|---|---|---|
0 | A | W00 | PCOAL | IX | 0 | P1Y | 2000 | 39.3510230293202 |
1 | A | W00 | PCOAL | IX | 0 | P1Y | 2001 | 49.3378587284039 |
2 | A | W00 | PCOAL | IX | 0 | P1Y | 2002 | 39.4949091648006 |
3 | A | W00 | PCOAL | IX | 0 | P1Y | 2003 | 43.2878876950788 |
4 | A | W00 | PCOAL | IX | 0 | P1Y | 2004 | 82.9185858052862 |
2. Parameters Dictionary Approach
This approach modifies the parameters dictionary directly and passes the entire filtered dictionary to imf_dataset
as a single parameters
keyword argument. This is more concise but requires understanding how the parameters dictionary works:
# Copy the params dictionary
= params.copy()
modified_params
# Overwrite the data frame for each parameter in the dictionary with filtered rows
'freq'] = params['freq'][
modified_params[# ...where the input code description for freq contains "Annual"
'freq']['description'].str.contains("Annual")
params[
]'commodity'] = params['commodity'][
modified_params[# ...where the input code description for commodity contains "Coal"
'commodity']['description'].str.contains("Coal")
params[
]'unit_measure'] = params['unit_measure'][
modified_params[# ...where the input code description for unit_measure contains "Index"
'unit_measure']['description'].str.contains("Index")
params[
]
# Pass the modified dictionary to imf_dataset
= imfp.imf_dataset(
df ="PCPS",
database_id=modified_params,
parameters=2000,
start_year=2015
end_year
)
df.head()
freq | ref_area | commodity | unit_measure | unit_mult | time_format | time_period | obs_value | |
---|---|---|---|---|---|---|---|---|
0 | A | W00 | PCOAL | IX | 0 | P1Y | 2000 | 39.3510230293202 |
1 | A | W00 | PCOAL | IX | 0 | P1Y | 2001 | 49.3378587284039 |
2 | A | W00 | PCOAL | IX | 0 | P1Y | 2002 | 39.4949091648006 |
3 | A | W00 | PCOAL | IX | 0 | P1Y | 2003 | 43.2878876950788 |
4 | A | W00 | PCOAL | IX | 0 | P1Y | 2004 | 82.9185858052862 |
Note that when using the parameters dictionary approach, you cannot combine it with individual parameter arguments. If you supply a parameters
argument, any other keyword arguments for individual parameters will be ignored.