<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Paul Natsuo Kishimoto - article</title><link href="https://paul.kishimoto.name/" rel="alternate"/><link href="https://paul.kishimoto.name/feeds/article.atom.xml" rel="self"/><id>https://paul.kishimoto.name/</id><updated>2026-08-25T00:00:00+02:00</updated><entry><title>Codes of conduct</title><link href="https://paul.kishimoto.name/2026/08/coc" rel="alternate"/><published>2026-08-25T00:00:00+02:00</published><updated>2026-08-25T00:00:00+02:00</updated><author><name>Paul Natsuo Kishimoto</name></author><id>tag:paul.kishimoto.name,2026-08-25:/2026/08/coc</id><summary type="html">&lt;p&gt;Over the last year and a half, I've watched with growing horror
as &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Vibe_coding"&gt;“vibe coding”&lt;/a&gt; and similar practices
have grown from niche to widespread, especially within Free Software communities.
(This is only one facet of the concerted push by moneyed and powerful people
to normalize LLM products like “generative AI” and their use. &lt;a class="footnote-reference" href="#footnote-1" id="footnote-reference-1"&gt;[1]&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;There are a few kinds of responses that are notable:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;People eagerly &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Jonestown#massacre"&gt;drinking the Kool-Aid&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Those who've had a sip or gulp, but have expressed regret and stopped using the products.
(See &lt;a class="reference external" href="https://brettcodes.com/im-done-using-ai/"&gt;one recent example&lt;/a&gt;.)&lt;/li&gt;
&lt;li&gt;People and groups making strong statements &lt;em&gt;against&lt;/em&gt; the use of LLM …&lt;/li&gt;&lt;/ol&gt;</summary><content type="html">&lt;p&gt;Over the last year and a half, I've watched with growing horror
as &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Vibe_coding"&gt;“vibe coding”&lt;/a&gt; and similar practices
have grown from niche to widespread, especially within Free Software communities.
(This is only one facet of the concerted push by moneyed and powerful people
to normalize LLM products like “generative AI” and their use. &lt;a class="footnote-reference" href="#footnote-1" id="footnote-reference-1"&gt;[1]&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;There are a few kinds of responses that are notable:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;People eagerly &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Jonestown#massacre"&gt;drinking the Kool-Aid&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Those who've had a sip or gulp, but have expressed regret and stopped using the products.
(See &lt;a class="reference external" href="https://brettcodes.com/im-done-using-ai/"&gt;one recent example&lt;/a&gt;.)&lt;/li&gt;
&lt;li&gt;People and groups making strong statements &lt;em&gt;against&lt;/em&gt; the use of LLM products,
for instance &lt;a class="reference external" href="https://greatscottgadgets.com/2026/06-17-llms-generate-code-communities-build-projects/"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;(3) in particular have spoken to me because they include positive statements
about what is &lt;em&gt;good&lt;/em&gt;, valuable, and rewarding about both programming as a solo pursuit,
and participation in Free Software projects and the communities that surround them.
Many of these have resonated.
On the individual side,
in 2021 I named a project &lt;a class="reference external" href="https://genno.readthedocs.io/en/latest/#name"&gt;‘genno’&lt;/a&gt; after a Japanese type of hammer.
This was a nod to the &lt;a class="reference external" href="https://www.acorntoarabella.com/vessel"&gt;Acorn to Arabella&lt;/a&gt; project to build a wooden boat from scratch,
whose videos helped me through many days of long COVID-19 lockdowns,
and helped me appreciate the joy of focused and patient work,
whether carpentry or coding. &lt;a class="footnote-reference" href="#footnote-2" id="footnote-reference-2"&gt;[2]&lt;/a&gt;
On the collective side, my work developing research software has increasingly been driven by a desire
to serve other researchers, especially those without the privileges I've enjoyed.
Developing and maintaining research tools for (and with!) these people—rather than for well-resourced people and organizations—guides many of my choices.
It's also immensely rewarding &lt;em&gt;per se&lt;/em&gt;.&lt;/p&gt;
&lt;a class="reference external image-reference" href="https://caolan.uk/doodles/"&gt;
&lt;object class="align-right" data="https://caolan.uk/doodles/ai_no_thanks.svg" style="width: 50%;" type="image/svg+xml"&gt;A palm held outwards in a 'stop' command. On it is written "AI. No, thanks!". The hand has six fingers. Image by Caolan McMahon.&lt;/object&gt;
&lt;/a&gt;
&lt;p&gt;As lovely as it is to see expressions of these shared values,
there are still too many people in category (1),
and they are inflicting severe and growing harms on Free Software projects both small and large.
At least until the ‘AI’ bubble pops—and still then—it's clear that defensive measures are necessary
to prevent unthinking or wilful behaviour &lt;a class="footnote-reference" href="#footnote-3" id="footnote-reference-3"&gt;[3]&lt;/a&gt; from undermining the labour I and we have done and want to be doing.&lt;/p&gt;
&lt;p&gt;To this end I took a stab at drafting &lt;a class="reference external" href="https://codeberg.org/khaeru/py/src/branch/main/CONTRIBUTING.md#code-of-conduct"&gt;a Code of Conduct&lt;/a&gt; (CoC),
one that I'll adopt for my own repositories and in cases where I am sole or lead maintainer with authority to make that change.
In the text, I try to make clear the human values motivating what I do,
which should also motivate anyone who I'd be happy to collaborate with.
Refusal of LLM usage and users then comes as a direct and simple consequence of these values.
I like this ordering because it starts with principles that should be stable,
and then interprets how these apply to the current malaise,
which may (one hopes) dissipate, but may also metastatize, or linger. &lt;a class="footnote-reference" href="#footnote-4" id="footnote-reference-4"&gt;[4]&lt;/a&gt;
The values can remain stable even if the context does not.
The list of references includes examples from other projects that were inspiring.&lt;/p&gt;
&lt;p&gt;I'm mulling further steps,
like moving more fully to &lt;a class="reference external" href="https://codeberg.org/khaeru"&gt;Codeberg&lt;/a&gt;,
&lt;a class="reference external" href="https://sr.ht/~khaeru/"&gt;Sourcehut&lt;/a&gt;,
or self-hosting of code and infrastructure.
Creating this CoC was a more basic step,
and can help signal the ‘why’ and guide the ‘what’ and ‘how’ of the next ones.&lt;/p&gt;
&lt;p&gt;I'll insist that contributors to my projects read it,
but would also be grateful to anyone else who may want to share constructive comments or ideas.&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="footnote-1" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-1"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;This post isn't about the broader phenomenon,
but you might check out Dan McQuillan's 2022 book
&lt;a class="reference external" href="https://bristoluniversitypress.co.uk/resisting-ai"&gt;“Resisting AI: An anti-fascist approach to artificial intelligence”&lt;/a&gt;
(yes, that's pre-ChatGPT; it holds up)
or this essay by S.K. Winnicki titled
&lt;a class="reference external" href="https://www.skwinnicki.com/single-post/i-would-be-so-ashamed-to-use-generative-ai-here-s-why"&gt;“I would be so ashamed to use generative AI, here's why”&lt;/a&gt;.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="footnote-2" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-2"&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="https://carpentries.org/about-us/#our-history"&gt;Software Carpentry&lt;/a&gt; is an organization whose name made this association explicit back in 1998.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="footnote-3" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-3"&gt;[3]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Bad, even rancid, vibes, if you will.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="footnote-4" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-4"&gt;[4]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;The same folks who pushed crypto and NFTs before moving on to ‘AI’ will,
unless stopped, certainly find another mechanism for their aims of extraction and amassing power.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</content><category term="article"/><category term="free software"/><category term="code of conduct"/><category term="llm"/></entry><entry><title>Tutorial: Moderation, facilitation, and public speaking</title><link href="https://paul.kishimoto.name/2026/08/moderation" rel="alternate"/><published>2026-08-11T00:00:00+02:00</published><updated>2026-08-11T00:00:00+02:00</updated><author><name>Paul Natsuo Kishimoto</name></author><id>tag:paul.kishimoto.name,2026-08-11:/2026/08/moderation</id><content type="html">&lt;p&gt;At the request of the IIASA Early Career Researchers (ECR) group
and Capacity Development and Academic Training (CDAT) unit,
I prepared and gave a 90 minute tutorial on
&lt;strong&gt;“Moderation, facilitation, and public speaking”&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;About 20 people attended.&lt;/p&gt;
&lt;p&gt;LaTeX source for the slides is in my &lt;tt class="docutils literal"&gt;doc&lt;/tt&gt; repository,
&lt;a class="reference external" href="https://codeberg.org/khaeru/doc/src/branch/main/2026/08-11_moderation.tex"&gt;here&lt;/a&gt;.
I will update this post to link to a PDF shortly.&lt;/p&gt;
</content><category term="article"/></entry><entry><title>“…for all!”</title><link href="https://paul.kishimoto.name/2025/07/for-all" rel="alternate"/><published>2025-07-20T00:00:00+02:00</published><updated>2025-10-10T12:50:00+02:00</updated><author><name>Paul Natsuo Kishimoto</name></author><id>tag:paul.kishimoto.name,2025-07-20:/2025/07/for-all</id><summary type="html">&lt;p&gt;Last year I was fortunate to get to work with a new team of co-authors
on a paper titled &lt;a class="reference external" href="https://doi.org/10.1016/j.erss.2025.104306"&gt;“Quantifying minimum mobility needs: the Who, the Where, and the Why.”&lt;/a&gt;
The project afforded a little space to think about the concept of &lt;strong&gt;wellbeing&lt;/strong&gt;,
in particular how it relates to mobility,
and to engage with some fascinating early literature on fundamental human needs.&lt;/p&gt;
&lt;p&gt;This is a new kind of post for me,
in which I'll share some commentary or spare thoughts on this paper.
These are links and connections to other topics, authors, and ideas
that didn't fit into the paper …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Last year I was fortunate to get to work with a new team of co-authors
on a paper titled &lt;a class="reference external" href="https://doi.org/10.1016/j.erss.2025.104306"&gt;“Quantifying minimum mobility needs: the Who, the Where, and the Why.”&lt;/a&gt;
The project afforded a little space to think about the concept of &lt;strong&gt;wellbeing&lt;/strong&gt;,
in particular how it relates to mobility,
and to engage with some fascinating early literature on fundamental human needs.&lt;/p&gt;
&lt;p&gt;This is a new kind of post for me,
in which I'll share some commentary or spare thoughts on this paper.
These are links and connections to other topics, authors, and ideas
that didn't fit into the paper itself,
yet were in my mind during and after the writing process
and a source of motivation.
To be clear, these are entirely my own thoughts;
please don't attach them to my co-authors,
or think that they've been through peer review.&lt;/p&gt;
&lt;div class="section" id="a-thought-experiment"&gt;
&lt;h2&gt;A thought experiment&lt;/h2&gt;
&lt;p&gt;Suppose we could ask every person in the world a single, simple question:
“Do you have wellbeing?” (or “Do you consider yourself to be well?”)
and get from each a ‘yes’ or ‘no’ answer.
Let's call this question &lt;strong&gt;Q1&lt;/strong&gt;.
Their answers would be Boolean (1 or 0, true or false) values
that we could label &lt;span class="formula"&gt;&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;1&lt;/sub&gt; ∈ {1, 0}&lt;/span&gt; for the first person we ask,
&lt;span class="formula"&gt;&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;2&lt;/sub&gt;&lt;/span&gt; for the second person,
and so on to &lt;span class="formula"&gt;&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;8000000000&lt;/sub&gt;&lt;/span&gt; and eventually &lt;span class="formula"&gt;&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;&lt;i&gt;N&lt;/i&gt;&lt;/sub&gt;&lt;/span&gt;,
where &lt;span class="formula"&gt;&lt;i&gt;N&lt;/i&gt; &amp;gt; 8×10&lt;sup&gt;9&lt;/sup&gt;&lt;/span&gt; is the number of people on Earth.
We can write &lt;span class="formula"&gt;&lt;i&gt;X&lt;/i&gt;&lt;/span&gt; to denote a vector including all of these values or data points.&lt;/p&gt;
&lt;p&gt;Next, we compute the function or statistic:&lt;/p&gt;
&lt;div class="formula"&gt;
&lt;i&gt;W&lt;/i&gt;&lt;sup&gt;1&lt;/sup&gt;(&lt;i&gt;X&lt;/i&gt;) = &lt;i&gt;x&lt;/i&gt;&lt;sub&gt;1&lt;/sub&gt;∧&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;2&lt;/sub&gt;∧…∧&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;&lt;i&gt;N&lt;/i&gt;&lt;/sub&gt;
&lt;/div&gt;
&lt;p&gt;This is the &lt;em&gt;logical conjunction&lt;/em&gt; of every &lt;span class="formula"&gt;&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;, &lt;i&gt;i&lt;/i&gt; ∈ (1, &lt;i&gt;N&lt;/i&gt;)&lt;/span&gt;.
It is a very simple function
that has the value ‘yes’/1/true if—and &lt;em&gt;only&lt;/em&gt; if!—every &lt;span class="formula"&gt;&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;&lt;/span&gt; is ‘yes’;
in other words, if every person in the world says, “Yes—I have wellbeing.”
If &lt;em&gt;even one person&lt;/em&gt; says, “No—I do not have wellbeing,” then &lt;span class="formula"&gt;&lt;i&gt;W&lt;/i&gt;&lt;sup&gt;1&lt;/sup&gt;(&lt;i&gt;X&lt;/i&gt;) = 0&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;I want to set up a few straw-man claims around this thought experiment,
question, and function.
To be clear, these are only sketches;
I do not aim to give a full defense or discuss all the implications.
The hope is rather to invite some responses and pointers:
Is there already good writing on any of these ideas,
or research that uses similar framing?
If so, where?&lt;/p&gt;
&lt;p&gt;Briefly:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;W¹(X) is the &lt;strong&gt;most parsimonious and direct&lt;/strong&gt; representation
of the background notions and widely used language
that both express and inform our shared understanding of “universal wellbeing.”&lt;/li&gt;
&lt;li&gt;X and thus W¹ would be &lt;strong&gt;very hard to measure&lt;/strong&gt; directly.&lt;/li&gt;
&lt;li&gt;We can imagine alternatives to W¹(X),
which we can label W²(…), W³(…), etc.
These are different functions,
that may be computed on the same data (&lt;span class="formula"&gt;&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;&lt;/span&gt;)
or on different data (labeled &lt;span class="formula"&gt;&lt;i&gt;y&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;&lt;/span&gt;, &lt;span class="formula"&gt;&lt;i&gt;z&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;&lt;/span&gt;, etc.)
whose values might approximate or proxy for values of X or W¹
that we do not observe directly.
These &lt;strong&gt;alternate measures inevitably involve value judgements&lt;/strong&gt;
that replace the subjectivity of individuals with those of (the) researcher(s).&lt;/li&gt;
&lt;li&gt;However convenient or useful,
the alternate data or functions in (3) are “wellbeing indicators”
only to the extent they (a) have &lt;strong&gt;precise definitions&lt;/strong&gt;
and (b) &lt;strong&gt;clear, empirical relationships&lt;/strong&gt; with X/W¹.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tension exists between fidelity to X/W¹ and ease of operationalization.&lt;/strong&gt;
Researchers face incentives to choose alternate data that seem more accessible,
and to pick alternate measures W² etc. that can be computed on such data.
Following these incentives blindly would tend to worsen the divergence from W¹.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These overlap, but I'll try to treat each in a separate section.&lt;/p&gt;
&lt;p&gt;I also want to emphasize at the outset that,
although the thought experiment may sound vaguely utilitarian
(“the greatest good for the greatest number”),
I am very much opposed to the so-called &lt;a class="reference external" href="https://en.wikipedia.org/wiki/TESCREAL"&gt;‘TESCREAL’&lt;/a&gt;
bundle of ideologies and the way they are deployed in public discourse and research.
This essay is in fact motivated by my worry that there is a risk
of normalizing these ideologies through incautious choices (5).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="universal-wellbeing"&gt;
&lt;h2&gt;1. Universal wellbeing&lt;/h2&gt;
&lt;p&gt;Many well-known aspirational declarations, statements, targets, goals, and initiatives
use &lt;strong&gt;universal&lt;/strong&gt; language, either directly or by implying universality or totality.
One example is the &lt;a class="reference external" href="https://en.wikisource.org/wiki/Universal_Declaration_of_Human_Rights"&gt;Universal Declaration of Human Rights&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Article 3&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Everyone&lt;/strong&gt; has the right to life, liberty, and security of the person.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Others include many of the &lt;a class="reference external" href="https://sdgs.un.org/goals"&gt;Sustainable Development Goals (SDGs)&lt;/a&gt;,
for instance:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Goal 2: &lt;strong&gt;Zero&lt;/strong&gt; hunger&lt;/p&gt;
&lt;p&gt;End hunger, achieve food security and improved nutrition
and promote sustainble agriculture&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;or:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Goal 5: Gender equality&lt;/p&gt;
&lt;p&gt;Acheive gender equality and empower &lt;strong&gt;all&lt;/strong&gt; women and girls.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;…and the names and goals of initiatives like:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://seforall.org"&gt;Sustainable Energy for All&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://sum4all.org"&gt;Sustainable (Urban) Mobility for All&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is worthwhile to take these at face value.
In other words, I set aside the question of
whether any one or all of these are merely aspirational,
were made insincerely, and/or are promoted cynically:
whether the proponents (signatories, member states, secretariats, philanthropies)
don't &lt;em&gt;actually&lt;/em&gt; mean that ‘everyone’, ‘all’ etc. should enjoy the unimpaired rights,
material conditions, or capabilities described—merely that &lt;em&gt;most&lt;/em&gt; people should,
or perhaps &lt;em&gt;more&lt;/em&gt; than enjoy them today.
If we take these statements as written,
function &lt;strong&gt;W¹(X)&lt;/strong&gt; is clearly their most direct representation.
If &lt;em&gt;even one person&lt;/em&gt; lacks the thing in question
(“security of the person”, “sustainable energy”, etc.),
then &lt;span class="formula"&gt;&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt; = 0&lt;/span&gt; for some &lt;span class="formula"&gt;&lt;i&gt;i&lt;/i&gt;&lt;/span&gt;,
thus &lt;span class="formula"&gt;&lt;i&gt;W&lt;/i&gt;&lt;sup&gt;1&lt;/sup&gt;(&lt;i&gt;X&lt;/i&gt;) = 0&lt;/span&gt;,
and the stated, universal goal or target is not met: &lt;em&gt;not everyone&lt;/em&gt; has the thing.
For instance, if one woman or girl is not empowered,
then the goal to “empower all women and girls” is not achieved.&lt;/p&gt;
&lt;p&gt;The case of a single exception sounds extreme,
but is itself a well-known thought experiment.
In the classic short story
&lt;a class="reference external" href="https://en.wikipedia.org/wiki/The_Ones_Who_Walk_Away_from_Omelas"&gt;The Ones Who Walk Away From Omelas&lt;/a&gt;
by Ursula K. LeGuin
(which won Locus and Hugo awards in 1974)
and Isabel J. Kim's &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Why_Don%27t_We_Just_Kill_the_Kid_In_the_Omelas_Hole"&gt;Why Don't We Just Kill The Kid In The Omelas Hole&lt;/a&gt;
(Nebula 2024, Locus 2025, Hugo nominee 2025),
the “Omelas child” is a person for whom &lt;span class="formula"&gt;&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;&lt;span class="text"&gt;Omelas child&lt;/span&gt;&lt;/sub&gt; = 0&lt;/span&gt;
—in a very stark and tragic sense.
Many positive things are said about the quality of life for everyone else in the city of Omelas,
yet &lt;span class="formula"&gt;&lt;i&gt;W&lt;/i&gt;&lt;sup&gt;1&lt;/sup&gt;(&lt;i&gt;X&lt;/i&gt;) = 0&lt;/span&gt; for Omelas in particular, and for the world in which it exists.
In pop philosophy the so-called &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Trolley_problem"&gt;trolley problem&lt;/a&gt;
and other devices are sometimes used to frame similiar discussions:
some frivolous, some useful.&lt;/p&gt;
&lt;p&gt;It's not my aim here to discuss all these.
It's only to observe that a statement like
“Everyone &lt;em&gt;except for the kid in the Omelas hole&lt;/em&gt; has the right to liberty,”
is not what was endorsed by the signatories to the UDHR.
On the other hand, if we say that
a variable &lt;span class="formula"&gt;&lt;i&gt;y&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;&lt;/span&gt; is 1 if and only if (‘iff’) a person enjoys their right to liberty,
then &lt;span class="formula"&gt;&lt;i&gt;W&lt;/i&gt;&lt;sup&gt;1&lt;/sup&gt;(&lt;i&gt;y&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;) = 1&lt;/span&gt;
is unambiguously consistent with “universally enjoyed human rights.”
&lt;span class="formula"&gt;&lt;i&gt;W&lt;/i&gt;&lt;sup&gt;1&lt;/sup&gt;(&lt;i&gt;y&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;) = 0&lt;/span&gt; just as clearly indicates
that those rights are &lt;em&gt;not&lt;/em&gt; universally enjoyed:
they may be ‘widely’ enjoyed, or enjoyed by a lucky few, but not by ‘all’.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="practical-realities-the-no-answer-and-q2"&gt;
&lt;h2&gt;2. Practical realities, the ‘no’ answer, and Q2&lt;/h2&gt;
&lt;p&gt;If we tried to carry out the thought experiment,
we would immediately run into difficulties.
Some include:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;It is not easy to translate &lt;strong&gt;Q1&lt;/strong&gt; from English into the native language of each person in the world.
A word with the same denotation and connotation as ‘wellbeing’ may not exist (more on this shortly).&lt;/li&gt;
&lt;li&gt;‘Yes’ and ‘no’ responses may not be very natural in each language.&lt;/li&gt;
&lt;li&gt;The questioner and respondent inevitably stand in some social relationship to one another.
&lt;a class="reference external" href="https://en.wikipedia.org/wiki/Social-desirability_bias"&gt;Social desirability&lt;/a&gt;,
power dynamics,
and other well-known forms of response bias would interfere
in obtaining a genuine answer from each person.&lt;/li&gt;
&lt;li&gt;It would be very expensive to ask every person directly and collate the data.
I'll come back to this in section 5, below.&lt;/li&gt;
&lt;li&gt;Even if we did collect all &lt;span class="formula"&gt;&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;1&lt;/sub&gt;…&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;&lt;i&gt;N&lt;/i&gt;&lt;/sub&gt;&lt;/span&gt;,
this would be only a snapshot at a certain point in time;
and we would not have information on &lt;em&gt;changes&lt;/em&gt; to each individual &lt;span class="formula"&gt;&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;&lt;/span&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Another problem we would quickly meet is that
many people would answer Q1 with a ‘no’,
and that a ‘no’ answer, on its own, is not readily actionable.
Surely we also want to know:
what it is that &lt;em&gt;prevents&lt;/em&gt; a person from feeling that they have wellbeing?
Are they not empowered?
Do they not have food, water, health, sanitation, mobility, or the enjoyment of certain rights?
This supports our intention (surely virtuous) to help them address those barriers,
and in so doing enable them, and eventually all, to have wellbeing.&lt;/p&gt;
&lt;p&gt;To get this information we add a second question, &lt;strong&gt;Q2&lt;/strong&gt;: “Why not?”&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="subjectivity-and-objectivity"&gt;
&lt;h2&gt;3. Subjectivity and objectivity&lt;/h2&gt;
&lt;p&gt;Q2 leads directly into a vast and murky swamp where things get &lt;em&gt;very&lt;/em&gt; complicated.
Q1 is constructed to, as far as possible, get a Boolean answer.
In contrast,
valid answers to Q2 must include the entire scope of human experience.
Consider a very short selection of possible answers
(for an exercise, write 10 or 100 more of your own):&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;No—I do not have wellbeing, because I am hungry and thirsty.&lt;/li&gt;
&lt;li&gt;… I am cold.&lt;/li&gt;
&lt;li&gt;… I am sick and can't get health care.&lt;/li&gt;
&lt;li&gt;… my child is sick and can't get health care.&lt;/li&gt;
&lt;li&gt;… my neighbour's child is sick and can't get health care.&lt;/li&gt;
&lt;li&gt;… I hate my neighbour and wish to kill him, but the law forbids me and he remains alive.&lt;/li&gt;
&lt;li&gt;… I want to own a sports car, but I don't.&lt;/li&gt;
&lt;li&gt;… I want to own a private jet, but I don't.&lt;/li&gt;
&lt;li&gt;… the &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Slender-billed_curlew"&gt;slender-billed curlew&lt;/a&gt; is extinct,
and I am inconsolably sad about this.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The core idea here is that &lt;em&gt;every person has a subjective notion of their own ‘wellbeing’&lt;/em&gt;.
When we ask Q1 to measure &lt;span class="formula"&gt;&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;&lt;/span&gt; and compute W¹(X), this is what we measure:
whether every person has what &lt;em&gt;they consider&lt;/em&gt; to be ‘wellbeing’.&lt;/p&gt;
&lt;p&gt;Here's a passage from &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Max_Horkheimer"&gt;Max Horkheimer&lt;/a&gt; in a
“Seminar on Needs” in 1942,
&lt;a class="reference external" href="https://jamescrane.substack.com/p/translation-excerpts-from-the-isr"&gt;translated by James Crane&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Thesis I.&lt;/strong&gt;
The juxtaposition of &lt;em&gt;material&lt;/em&gt; and &lt;em&gt;ideal&lt;/em&gt; needs proves untenable upon closer inspection.
The unchanging adherence to such cissions [&lt;em&gt;Scheidungen&lt;/em&gt;] leads to serious theoretical and political errors.&lt;/p&gt;
&lt;p&gt;[…]&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Thesis II.&lt;/strong&gt; To speak generally,
the ideal needs one might strive to fulfill are nothing other than the social form,
the manner and mode, in which material needs are to be satisfied.
When the demand for a pint of milk is raised, even from the mouth of a government official,
it contains a number of “formal” elements, which are not expressly stated:
that the milk is delivered in a clean container,
that it contains no dangerous bacteria, that it has a certain fat content, etc.
If one stuck strictly to the wording, the demand could be fulfilled;
nevertheless, the child would be cheated.
Dialectics recognizes that it is not only [elements such as] the nutritional value,
the kind of container, and so forth, which play a role in whether the child is cheated.
It is also crucial, for instance,
that the father and mother do not suffer under the burden of senseless labor,
and the child under the fear of losing them to it;
that the child lives in an orderly house,
that they have a good family doctor,
that there is no exploitative [and terroristic] domination—which
would necessarily be reflected in the very faces and being of the parents,
and throughout the child’s whole environment, and which, in the long run,
would spoil the milk so much more than a dirty container ever could.
&lt;strong&gt;The social order is as much a part of the milk as its fat content.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In the drafting of our paper up through December 2024
we discussed for many hours very similar questions.
This translation was published later, in March 2025.
Our focus was on the needs-and-satisfiers frameworks of
&lt;a class="reference external" href="https://en.wikipedia.org/wiki/Manfred_Max-Neef's_Fundamental_human_needs"&gt;Max-Neef&lt;/a&gt;,
Doyal &amp;amp; Gough, and others from the 1970s and 1980s.
It seems clear to me that these authors were influenced (directly or indirectly) by,
and attempting to elaborate,
the earlier work of Horkheimer and his colleagues in the Frankfurt School.&lt;/p&gt;
&lt;p&gt;The researcher/questioner in our thought experiment might face the temptation
to depart from X and W¹ when they hear a Q1 ‘no’
and Q2 “…because my milk was not delivered in a clean container.”
They might wish to respond:
“Well, this matter of the cleanliness of milk containers is too complicated;
I'm mainly trying to gather Q1 data and that's hard enough already.
I will put you down as ‘yes’ on Q1, and I'll make a little asterisk here
and a note: ‘adequate nutrition, but doesn't like the smudges on the bottle’.”
In this case, the researcher &lt;strong&gt;has not measured&lt;/strong&gt; &lt;span class="formula"&gt;&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;&lt;/span&gt;.
They have chosen to substitute something else that we can call &lt;span class="formula"&gt;&lt;i&gt;z&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;&lt;/span&gt;:
“wellbeing—notwithstanding food container cleanliness.”
They use this to &lt;strong&gt;approximate&lt;/strong&gt; &lt;span class="formula"&gt;&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;&lt;/span&gt;.
In many cases &lt;span class="formula"&gt;&lt;i&gt;z&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;&lt;/span&gt; and &lt;span class="formula"&gt;&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;&lt;/span&gt; may have the same value, but not always.&lt;/p&gt;
&lt;p&gt;I'll come back to alternates and approximations in the next section.
For now, let's focus on what the researcher has done.
Lists of fundamental human needs or rights often include ‘autonomy’ or related terms and concepts.
Surely one essential aspect of autonomy is the autonomy to choose &lt;em&gt;what matters to us&lt;/em&gt;;
to construct meaning, including the meaning of ‘wellbeing’.
People who &lt;em&gt;lack&lt;/em&gt; the capability or freedom to do this
—who are told by powerful people to not to complain,
even though they do not have wellbeing—
would surely answer Q1 with ‘no’,
and might say to Q2 “…because I am denied the right to my own subjectivity
and expression of what is essential to my wellbeing.”&lt;/p&gt;
&lt;p&gt;This also is why we pose Q1 and Q2 &lt;strong&gt;to every person&lt;/strong&gt;:
if we asked a dictator to give us data &lt;span class="formula"&gt;&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;&lt;/span&gt; for each of his subjects,
he could give ‘yes’ for every one without even consulting them.
If asked directly, many of them would no doubt answer Q1 with ‘no’ and Q2
“…because I live under a dictator!”&lt;/p&gt;
&lt;p&gt;Every possible answer to Q2 falls on an ethical continuum
from unobjectionable to unconscionable.
From the list of 10 answers above,
few would object to (1),
especially since the stated unmet needs align with
some of the widely (not to say universally!) agreed SDGs.
A researcher who says “I judge you to be well (&lt;span class="formula"&gt;&lt;i&gt;z&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt; = 1&lt;/span&gt;)
even though you say you do not have enough food to eat”
would need to give a very strong justification for this choice.
At the far extreme, accepting (6) would lead to a world of unpunished murder and assault
in which the victims would certainly not have wellbeing.
In this case,
hopefully few would object to the researcher/questioner overruling the respondent.
In the middle, (7) might trigger debate:
do we accept that a person who has everything &lt;em&gt;except&lt;/em&gt; a sports car can &lt;em&gt;not&lt;/em&gt; be well?
Do we psychoanalyze them and say, “What you &lt;em&gt;actually&lt;/em&gt; lack is self-esteem;
we can give you another way to achieve that, one that's less destructive.
If that's your only complaint, we judge you to be otherwise well.”&lt;/p&gt;
&lt;p&gt;My claim 3 is simply that reckoning with this spectrum is unavoidable.
No matter how ‘objective’ or morally ‘neutral’ an approximation &lt;span class="formula"&gt;&lt;i&gt;z&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;&lt;/span&gt; is claimed to be,
it encodes value judgements on the part of the researcher;
ones that data subjects and readers are asked to accept.
At the very least, I hope,
we can do better to acknowledge, name, enumerate, and debate these judgements.
To paraphrase another recent paper,
&lt;a class="reference external" href="https://doi.org/10.31219/osf.io/ga5fb_v1"&gt;“[acknowledging] subjectivity is a feature, not a flaw.”&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="approximations-and-usefulness"&gt;
&lt;h2&gt;4. Approximations and usefulness&lt;/h2&gt;
&lt;p&gt;Let's imagine a couple more kinds of alternates and approximations.
One is:&lt;/p&gt;
&lt;div class="formula"&gt;
&lt;i&gt;W&lt;/i&gt;&lt;sup&gt;2&lt;/sup&gt;(&lt;i&gt;X&lt;/i&gt;) = &lt;i&gt;N&lt;/i&gt;&lt;sup&gt; − 1&lt;/sup&gt;⋅&lt;span class="limits"&gt;&lt;sup class="limit"&gt; &lt;/sup&gt;&lt;span class="limit"&gt;&lt;span class="bigoperator"&gt;∑&lt;/span&gt;&lt;/span&gt;&lt;sub class="limit"&gt;&lt;i&gt;i&lt;/i&gt; ∈ &lt;i&gt;N&lt;/i&gt;&lt;/sub&gt;&lt;/span&gt;&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;
&lt;/div&gt;
&lt;p&gt;…that is, the &lt;em&gt;share&lt;/em&gt; of people in the world for whom &lt;span class="formula"&gt;&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt; = 1&lt;/span&gt;.
This is a different function from W¹, computed on the same data,
but with a continuous value in the range (0, 1).&lt;/p&gt;
&lt;p&gt;A second kind of approximation is to replace the infinite space of Q2 answers
with a small, finite set of variables that express necessary conditions of wellbeing.
(This is the link to the literature on fundamental/universal human needs,
which tries to enumerate these, or at least give a finite number of categories.)
For instance, suppose:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;span class="formula"&gt;&lt;i&gt;b&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt; = 1&lt;/span&gt; if a person has adequate nutrition (even milk from a clean bottle!)&lt;/li&gt;
&lt;li&gt;&lt;span class="formula"&gt;&lt;i&gt;c&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt; = 1&lt;/span&gt; if a person has access to health care.&lt;/li&gt;
&lt;li&gt;&lt;span class="formula"&gt;&lt;i&gt;d&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt; = 1&lt;/span&gt; if a person has access to clean water.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then define another variable &lt;span class="formula"&gt;&lt;i&gt;a&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt; = &lt;i&gt;b&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;∧&lt;i&gt;c&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;∧&lt;i&gt;d&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;&lt;/span&gt;.
We can either compute &lt;span class="formula"&gt;&lt;i&gt;W&lt;/i&gt;&lt;sup&gt;1&lt;/sup&gt;(&lt;i&gt;A&lt;/i&gt;)&lt;/span&gt;, which is 1 if and only if
all &lt;span class="formula"&gt;&lt;i&gt;b&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt; = &lt;i&gt;c&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt; = &lt;i&gt;d&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt; = 1&lt;/span&gt;,
or &lt;span class="formula"&gt;&lt;i&gt;W&lt;/i&gt;&lt;sup&gt;2&lt;/sup&gt;(&lt;i&gt;A&lt;/i&gt;)&lt;/span&gt;, the share of people for whom &lt;span class="formula"&gt;&lt;i&gt;a&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt; = 1&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;These approximations can certainly be more convenient and useful than x and W¹.
For instance, W¹ will remain 0 until universal wellbeing is achieved;
when the last person (the Omelas child) finally has wellbeing, W¹ will suddenly flip to 1.
This makes it not much help as an ‘indicator’ or ‘metric’ for measuring progress,
or to examine claims like “Action P will do more towards W¹ than action Q.”
In contrast, it is much more helpful and tractable to be able to say:
“Currently, W²(A) = 0.456.
With Action P, W²(A) could increase to 0.6 in 10 years.
With Action Q, W²(A) could increase to 0.7 in 20 years.”
For this reason it is valid and valuable to establish, measure, and compute these
alternate measures.&lt;/p&gt;
&lt;p&gt;However, can be W²(X), W¹(A), or W²(A) be a “measure of [universal] wellbeing”?
For W²(X), trivially yes: this function has the value 1.0 iff every &lt;span class="formula"&gt;&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt; = 1&lt;/span&gt;,
which then directly implies W¹(X) = 1.
But suppose every &lt;span class="formula"&gt;&lt;i&gt;a&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt; = 1&lt;/span&gt;,
such that every person has water, health care, and calories,
and thus &lt;span class="formula"&gt;&lt;i&gt;W&lt;/i&gt;&lt;sup&gt;1&lt;/sup&gt;(&lt;i&gt;A&lt;/i&gt;) = 1&lt;/span&gt; and &lt;span class="formula"&gt;&lt;i&gt;W&lt;/i&gt;&lt;sup&gt;2&lt;/sup&gt;(&lt;i&gt;A&lt;/i&gt;) = 1.0&lt;/span&gt;.
Is universal wellbeing necessarily achieved?
Just as trivially, no:
every human in a pod in the world of &lt;a class="reference external" href="https://en.wikipedia.org/wiki/The_Matrix#Plot"&gt;The Matrix&lt;/a&gt;
has water, health care, and calories,
but that is a dystopia, not a world of universal human wellbeing.&lt;/p&gt;
&lt;p&gt;To avoid confusing readers and one another,
here are some simple practices that researchers can adopt:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;If the topic of research is ‘[universal] wellbeing’ but X and W¹ are not used,
define clearly the measures (data Y, Z, … and/or functions W³, W⁴, …) used instead.&lt;/li&gt;
&lt;li&gt;Cite or provide evidence about how the chosen measures relate to X and W¹.
If possible, give quantitative relationship(s) with specific parameters.&lt;/li&gt;
&lt;li&gt;If such evidence does not exist or cannot be obtained:&lt;ul&gt;
&lt;li&gt;Don't refer to the alternate measures as measures of ‘wellbeing’.
Choose a descriptive name that does not create ambiguity.&lt;/li&gt;
&lt;li&gt;At least give some qualitative discussion:
In what ways might the measures depart from X and W¹?&lt;/li&gt;
&lt;li&gt;What real or imaginable conditions might exist such that, for instance,
W²(X) is low, but the chosen alternate W³(Y) is high?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Acknowledge the subjective judgements encoded in researchers' choice of alternates.
What is omitted or excluded?
Is it proper for the researchers to make such exclusions?&lt;/li&gt;
&lt;li&gt;Discuss other possible choices,
and if possible test robustness of conclusions against these.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="convenient-data-and-lock-in"&gt;
&lt;h2&gt;5. Convenient data and lock-in&lt;/h2&gt;
&lt;p&gt;In section (2) I noted that &lt;span class="formula"&gt;&lt;i&gt;N&lt;/i&gt; &amp;gt; 8×10&lt;sup&gt;9&lt;/sup&gt;&lt;/span&gt; is a large number.
Even for subpopulations, like smaller countries or cities,
it would be difficult to talk to every person in order to collect all &lt;span class="formula"&gt;&lt;i&gt;x&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;&lt;/span&gt;
and compute W¹ for that population.
In section (4) I noted that it is valuable, even necessary, to seek approximations.
However, this doesn't mean that &lt;em&gt;any&lt;/em&gt; chosen approximation is valid or helpful.
It's entirely possible for such choices to be bad.&lt;/p&gt;
&lt;p&gt;At one end of a spectrum of resolution, aggregate economic statistics such as GDP
have been taken as measures related to wellbeing, directly or via functions with
similarly coarse resolution.
As we noted in our paper,
the early literature on fundamental human needs, nearly 50 years ago,
already pointed out the inadequacy of this approach.&lt;/p&gt;
&lt;p&gt;At the far extreme of resolution, ‘big data’ have gained popularity in recent years
because of their convenience:
they afford to researchers the possibility
of getting a large number of data points at a relatively low cost (to the researcher).
Particularly, access to such data seems to remove any need for researchers to have direct contact with “data subjects.”&lt;/p&gt;
&lt;p&gt;Anyone who has worked with such data can attest that
there is a trade-off between the number of data points
and fitness for whatever purpose(s) a researcher has in mind
(here, measuring individual and collective wellbeing).
The data have usually been amassed through a system,
constructed and controlled by some other entity
(often a large, for-profit company)
that has a purpose different from the researchers.
For example, the goal of Alphabet/Google
in collecting map data and users' location data is ultimately
to make a profit by selling advertisements,
for instance to businesses in the same area.
They collect data that can be used to this end,
or to attendant ends like drawing in ad-viewers with free services.
In some cases, researchers can overcome this divergence in purpose with methodological creativity,
deriving measures for quantities of interest in ways that can be validated and tested.
In other cases, researchers abandon their original goals and questions,
and instead devise new ones that are answerable with the data
offered to or obtained by them.
For instance, Q1/Q2 above might get replaced with “Has this user visited a McDonald's in the past N days?”
Sometimes these choices are later rationalized, more or less weakly:
“visiting McDonald's might mean eating;
eating is part of getting adequate nutrition;
and this is a fundamental human need and a component of wellbeing.”&lt;/p&gt;
&lt;p&gt;Even if (a big if!) valid and empirically grounded of measures of wellbeing
can be constructed from such data, there is substantial risk of &lt;strong&gt;lock-in&lt;/strong&gt;.
If wellbeing is chiefly measured through the particular form of location data
collected and provided by Alphabet (or whomever), and methods built on those data,
then it is constructed as a thing that both
(a) is not measurable without Alphabet's cooperation and system of data collection,
and (b) can be known without ever asking any person Q1 directly.
Both of these seem to be immense flaws:
(a) because it creates total dependency on the data-gathering apparatus and the people who control it;
and (b) because the subjectivity of “data subjects” is entirely alienated. &lt;a class="footnote-reference" href="#footnote-1" id="footnote-reference-1"&gt;[1]&lt;/a&gt;
Researchers risk becoming cheerleaders for total surveillance and its practitioners,
even if—like the dictator in section (3) above—the very existence and harms of such systems
would be cited by many as the reason for a lack of wellbeing.&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="footnote-1" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-1"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;At some point I'll write more on these two very different uses of ‘subject’.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
</content><category term="article"/><category term="data"/><category term="metrology"/><category term="mobility"/><category term="research"/><category term="wellbeing"/></entry><entry><title>Please don't feed me slop</title><link href="https://paul.kishimoto.name/2025/02/no-slop" rel="alternate"/><published>2025-02-18T00:00:00+01:00</published><updated>2025-02-18T00:00:00+01:00</updated><author><name>Paul Natsuo Kishimoto</name></author><id>tag:paul.kishimoto.name,2025-02-18:/2025/02/no-slop</id><summary type="html">&lt;div class="section" id="a-parable"&gt;
&lt;h2&gt;A parable&lt;/h2&gt;
&lt;p&gt;Imagine you make a new acquaintance through friends, and through a brief conversation learn that the other person shares your love of food and cooking.
They invite you to come over one evening for a “home cooked meal,” and you gladly accept!&lt;/p&gt;
&lt;a class="reference external image-reference" href="https://commons.wikimedia.org/wiki/File:Spam_Treet_and_Great_Value_Luncheon_Meat.jpg"&gt;
&lt;img alt="Side by side comparison of Spam (L), Treet (C), and Walmart Great Value Luncheon Meat (R). Image from Wikimedia Commons." class="align-right" src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7e/Spam_Treet_and_Great_Value_Luncheon_Meat.jpg/960px-Spam_Treet_and_Great_Value_Luncheon_Meat.jpg" style="width: 50%;" /&gt;
&lt;/a&gt;
&lt;p&gt;Once you arrive and sit down for dinner, they hand you a plate with some…shapes on it.
These shapes &lt;em&gt;look&lt;/em&gt; like food, more or less: one seems potato-shaped, another is shaped like a chicken wing.&lt;/p&gt;
&lt;p&gt;“Er, thanks,” you stammer. “You, um, made this?”&lt;/p&gt;
&lt;p&gt;“Yes!” your host beams.&lt;/p&gt;
&lt;p&gt;Too polite to say anything else, you take …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="section" id="a-parable"&gt;
&lt;h2&gt;A parable&lt;/h2&gt;
&lt;p&gt;Imagine you make a new acquaintance through friends, and through a brief conversation learn that the other person shares your love of food and cooking.
They invite you to come over one evening for a “home cooked meal,” and you gladly accept!&lt;/p&gt;
&lt;a class="reference external image-reference" href="https://commons.wikimedia.org/wiki/File:Spam_Treet_and_Great_Value_Luncheon_Meat.jpg"&gt;
&lt;img alt="Side by side comparison of Spam (L), Treet (C), and Walmart Great Value Luncheon Meat (R). Image from Wikimedia Commons." class="align-right" src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7e/Spam_Treet_and_Great_Value_Luncheon_Meat.jpg/960px-Spam_Treet_and_Great_Value_Luncheon_Meat.jpg" style="width: 50%;" /&gt;
&lt;/a&gt;
&lt;p&gt;Once you arrive and sit down for dinner, they hand you a plate with some…shapes on it.
These shapes &lt;em&gt;look&lt;/em&gt; like food, more or less: one seems potato-shaped, another is shaped like a chicken wing.&lt;/p&gt;
&lt;p&gt;“Er, thanks,” you stammer. “You, um, made this?”&lt;/p&gt;
&lt;p&gt;“Yes!” your host beams.&lt;/p&gt;
&lt;p&gt;Too polite to say anything else, you take a few bites.
The ‘food’—well, it seems to be food, it's kind of hard to say what it tastes like, but at least nothing bad—has a sort of strange texture that's more or less the same for the ‘potato’ and the ‘chicken wing’, and again hard to place.&lt;/p&gt;
&lt;p&gt;Your host is eating with gusto, but increasingly you feel uneasy about &lt;em&gt;what&lt;/em&gt;, exactly, you're eating.
Finally you ask, “Sorry, but I'm a little curious—&lt;em&gt;how&lt;/em&gt; did you make this?”&lt;/p&gt;
&lt;p&gt;“Oh, I used this amazing new ‘generative cooking’ service that just popped up in this neighbourhood.
It's free and easy to use: you just put some ingredients into it—and I shop at a high-end grocer, so I've got only the finest produce, meat, spices, and such in my fridge—and out pops a cooked and plated meal!”&lt;/p&gt;
&lt;p&gt;“…”&lt;/p&gt;
&lt;p&gt;“Sometimes there are bones or it tastes a little off, but you just feed it back into the hopper a few times and eventually it gets it right—mostly.
It's such a life-saver; I was so busy today and thought I wouldn't have time to prepare the meal, yet here we are!”&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;p&gt;What exactly has happened here?
You took time to visit someone's home based on what you believed was a shared understanding of what “home cooked” food (per their verbal invitation) was.
Instead, you were fed some kind of slop or spam.&lt;/p&gt;
&lt;p&gt;Your host didn't ‘prepare’ it in the sense of cooking a meal themself, but rather used some machine—new and unknown to you, created or operated by some other person that you don't know—to extrude something that only superficially resembles food that might be prepared by a real person.&lt;/p&gt;
&lt;p&gt;They didn't tell you that they would or did do this, but allowed you to believe it was their “cooking,” in the end forcing &lt;em&gt;you&lt;/em&gt; to raise the topic and discover the truth.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="why"&gt;
&lt;h2&gt;Why?&lt;/h2&gt;
&lt;p&gt;I'm writing this because, with increasing frequency, I encounter people and try to interact with them as if they were fellow scholars, researchers, or scientists.
But, instead, I am sent slop that has been extruded by “generative artificial intelligence (genAI)” tools &lt;a class="footnote-reference" href="#genai" id="footnote-reference-1"&gt;[1]&lt;/a&gt; —often without mention that this is what the other person has done.
Other times, I begin to work with someone and invest my effort on my parts of the work, then later realize that one or more of my collaborators have been pasting genAI output into a shared document, instead of their own writing.&lt;/p&gt;
&lt;p&gt;I recognize that this is a contested area.
For a contrasting example, consider the long-established norms on plagiarism and citation in academic work.
These norms may not be &lt;em&gt;uniform&lt;/em&gt;, or universally and consistently obeyed, but nonetheless they cohere and can be explained and learned.
Most importantly, when we encounter other scholars, we can reasonably expect that they've learned and adhere to &lt;em&gt;some&lt;/em&gt; kind of norms against plagiarism, or for citation.
We may have to fish a little to understand precisely what they believe; if they are a student, they may need some coaching and reminders on what passes for normal behaviour in our shared fields.&lt;/p&gt;
&lt;p&gt;Because ‘genAI’ is new, none of this is the case; norms are still being formed.
So this post is not an attempt to speak for anyone beyond myself.
It is slightly normative in that I do &lt;em&gt;hope&lt;/em&gt; that other researchers, especially those I work with, will find this a valid and compelling perspective and approach.
But I have only limited ability to affect that; so this is mostly descriptive of what &lt;strong&gt;I&lt;/strong&gt;, myself, will and won't do, and why.&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="genai" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-1"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;usually based on large language models (LLMs) or other types of machine learning (ML).&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="section" id="tl-dr-1"&gt;
&lt;h2&gt;&lt;a class="reference external" href="https://en.wiktionary.org/wiki/tl;dr"&gt;tl;dr&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Even if you don't read the rest of this post, here are a few simple rules:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Please, if you &lt;em&gt;send&lt;/em&gt; me something—text of any kind, code, data, images, etc.—prepared using ‘AI’, tell me &lt;em&gt;up-front&lt;/em&gt; (a) that you've done this and (b) precisely how.&lt;/li&gt;
&lt;li&gt;If you &lt;em&gt;plan&lt;/em&gt; to do #1 in the course of a research project, collaboration, editorial process, etc., warn me in advance.&lt;/li&gt;
&lt;li&gt;Understand and respect that it is my prerogative to not engage or work with you because you have (or have not) done #1 or #2, or because of &lt;em&gt;how&lt;/em&gt; you've done them.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The title of this post may be easier to remember: &lt;strong&gt;please don't feed me slop.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="a-few-more-points"&gt;
&lt;h2&gt;A few more points&lt;/h2&gt;
&lt;p&gt;There's a lot to be said about ‘genAI’ and the people creating and promoting it—too much to write here.&lt;/p&gt;
&lt;div class="section" id="thinking-together"&gt;
&lt;h3&gt;Thinking together&lt;/h3&gt;
&lt;p&gt;To me, the core issue is the one illustrated by the parable above.
I became and remain a researcher because I enjoy thinking (about certain topics, in certain ways).
Research collaboration is enjoyable because the other humans whom I prefer to work with have interesting thoughts.
It's exciting and helpful for me to think together with them: I enjoy when I can make them understand an idea I've had, or when they show me a new way of thinking about a problem or phenomenon, a new way of doing something, etc.&lt;/p&gt;
&lt;p&gt;When I'm handed slop, I am deprived of the chance to do these things.
Eating slop means I am spending my time, instead, looking at a sequence of words or pixels that, although they may statistically resemble text written by a person, &lt;em&gt;do not capture any thinking on the far side&lt;/em&gt;.
My thoughts and ideas are not being stimulated by someone's genuine effort to communicate their ideas to me, but by the mental equivalent of junk food.
Eating slop also means I have to grapple with the awareness that the person who has sent the slop does not respect me enough to do the work of sharing their thoughts with me: that they think I'm not worth that effort.
This makes it impossible to build the kind of collegial relationship that, in the best case, exists between fellow researchers: why should I invest in trusting someone whose actions communicate that they don't trust me?&lt;/p&gt;
&lt;p&gt;Again, I understand that this is a novel area for many people.
A person may not &lt;em&gt;intend to&lt;/em&gt; or &lt;em&gt;be aware that&lt;/em&gt; sending me slop communicates a lack of trust. &lt;a class="footnote-reference" href="#footnote-1" id="footnote-reference-2"&gt;[2]&lt;/a&gt;
But the impact is what matters, not the intent.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="systemic-discrimination-and-exclusion"&gt;
&lt;h3&gt;Systemic discrimination and exclusion&lt;/h3&gt;
&lt;p&gt;I have worked with and know many excellent researchers from non-English backgrounds.
I know that it is a difficult language to learn and master (especially academic English); this is an obstacle unjustly faced by some researchers and not others merely by accident of where they were born.
Even after immense and hard work they may invest to learn a second/third/etc. language, people still face unfair discrimination for ‘non-native’ proficiency, or ignorance/lack of appreciation of that investment.&lt;/p&gt;
&lt;p&gt;However, using genAI tools to ‘fake’ such proficiency is not and can never be a real solution to these forms of systemic discrimination and disadvantage.
Systemic problems need systemic reform.
Worse: it actively gets in the way of the practice and effort necessary to improve one's own real skills.
It does not reclaim power for the disempowered, but rather transfers it (and much wealth) to the people who make and promote the use of ‘AI’ tools.&lt;/p&gt;
&lt;p&gt;The analogy of plagiarism to doping in sport has been made many times, but fits even better the use of ‘AI’: if scholarship and academic systems reward and select for people who can exploit ‘AI’ best, not only will actual research skills be devalued, but people who already have power, wealth, and other social advantages will find it easier to dope and to get away with doping.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="mentorship-and-training"&gt;
&lt;h3&gt;Mentorship and training&lt;/h3&gt;
&lt;p&gt;I choose to spend some of my time mentoring students so that those students can learn and develop their own skills.
I am especially excited if I can help them learn certain kinds of research thinking that I enjoy and believe should be more widely practiced, or help them to overcome discrimination based on gender, language, race, and other characteristics.
For this reason, I think I would be a poor mentor if I encouraged or permitted students to use ‘genAI’ tools—except in narrow, deliberative ways.&lt;/p&gt;
&lt;p&gt;For instance, there is a particular skill to closely read many papers from the literature, deeply understand what the authors are trying to say, and write a concise review/synthesis.
A student who only uses ‘genAI’ tools to produce ‘summaries’ is missing an important opportunity to learn and refine this skill.
In turn, that undermines &lt;em&gt;all&lt;/em&gt; the other academic skills built on top of it.
A mentor who permits or encourages a student to do this is sending the signal that what matters is the ‘content’, output, or text—when in fact what matters is the student's ability to do the &lt;em&gt;thinking&lt;/em&gt; that precedes any text.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-do-you-think"&gt;
&lt;h3&gt;What do &lt;em&gt;you&lt;/em&gt; think?&lt;/h3&gt;
&lt;p&gt;This is written off-the-cuff and to avoid repeating the same arguments in more e-mails.
I may come back to expand this text or add citations to more in-depth work and writing by others.
But—what do &lt;em&gt;you&lt;/em&gt; think?
Are you aware of other good examples (or counter-examples) of stated practice in research and scholarly behaviour that I can learn from?
If so, please do get in touch to share.&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="footnote-1" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-2"&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;In particular, some people view research not as I describe here, but as a process of producing products—articles, reports, data sets, etc.
In this view, it doesn't matter whether the products are &lt;em&gt;good&lt;/em&gt; in any sense—for instance whether they contain ideas or express thinking that are sound an interesting—only that they &lt;em&gt;appear to&lt;/em&gt;.
This is in tension with my view of scholarship-as-thinking; it depresses me that people think this way, and if they do I would rather not work with them.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="article"/></entry><entry><title>Effective strategies for multi-sectoral research using large-scale models</title><link href="https://paul.kishimoto.name/2021/06/issst" rel="alternate"/><published>2021-06-23T00:00:00+02:00</published><updated>2021-06-23T00:00:00+02:00</updated><author><name>Paul Natsuo Kishimoto</name></author><id>tag:paul.kishimoto.name,2021-06-23:/2021/06/issst</id><summary type="html">&lt;p&gt;A talk given at the &lt;a class="reference external" href="https://issst.net/issst-2021/"&gt;2021 meeting of the International Symposium for Sustainble Systems and Technology&lt;/a&gt;.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://pure.iiasa.ac.at/id/eprint/17286/1/slides.pdf"&gt;Slides&lt;/a&gt; (PDF, 436 kB) at IIASA PURE&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.youtube.com/watch?v=Osn1c3hQcmM"&gt;Recording&lt;/a&gt; on YouTube&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/khaeru/doc/tree/main/2021/06-23%20ISSST"&gt;TeX source and BibTeX citation&lt;/a&gt; on GitHub&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="section" id="abstract"&gt;
&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;p&gt;Large-scale integrated assessment models (IAMs) have become critical knowledge objects and tools for global-scope simulation of energy, economic, engineering, and environmental systems.
IAMs are widely used in assessment of climate change mitigation (for instance, within the IPCC) and other Sustainable Development Goals (SDGs). In order to sharpen the relevance of insights from large-scale modeling, researchers often link them into multi-model frameworks together with detailed sectoral (sub- …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;A talk given at the &lt;a class="reference external" href="https://issst.net/issst-2021/"&gt;2021 meeting of the International Symposium for Sustainble Systems and Technology&lt;/a&gt;.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://pure.iiasa.ac.at/id/eprint/17286/1/slides.pdf"&gt;Slides&lt;/a&gt; (PDF, 436 kB) at IIASA PURE&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.youtube.com/watch?v=Osn1c3hQcmM"&gt;Recording&lt;/a&gt; on YouTube&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/khaeru/doc/tree/main/2021/06-23%20ISSST"&gt;TeX source and BibTeX citation&lt;/a&gt; on GitHub&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="section" id="abstract"&gt;
&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;p&gt;Large-scale integrated assessment models (IAMs) have become critical knowledge objects and tools for global-scope simulation of energy, economic, engineering, and environmental systems.
IAMs are widely used in assessment of climate change mitigation (for instance, within the IPCC) and other Sustainable Development Goals (SDGs). In order to sharpen the relevance of insights from large-scale modeling, researchers often link them into multi-model frameworks together with detailed sectoral (sub-)models of, for instance, transport and mobility; the building stock; critical materials; or water use—or with models of narrower scope (e.g. national or sub-national) but finer resolution.
These links capture feedbacks and interactions that may strongly shape transitions to comprehensive sustainability.&lt;/p&gt;
&lt;p&gt;This presentation begins with current expectations that guide IAM-based research.
In particular, it is no longer satisfactory that individual models and 1-to-1 frameworks can analyse, for instance, (a) possible recoveries from the COVID-19 pandemic; (b) the long-term evolution of transport and mobility; and (c) the energy and climate impacts of changing materials flows.
Increasingly, stakeholders require assessments that are both integrated &lt;em&gt;and&lt;/em&gt; highly detailed in multiple sectors/areas such as these.
Teams are challenged to produce this knowledge while also progressing in openness, transparency, reproducibility, and validity of research.&lt;/p&gt;
&lt;p&gt;I argue that meeting these challenges requires systems researchers and modelers to acknowledge that they are engaged in processes of collaborative software development: models are, in an important sense, also complex, long-lived, and evolving pieces of software.
This perspective motivates the use of strategies that are common in professional software development, yet woefully underutilized in academia and research: standardization, testing, modularity and reuse, an emphasis on documentation, and iterative workflows with short cycle times.&lt;/p&gt;
&lt;p&gt;Using the example of the MESSAGEix-GLOBIOM family of models developed by the IIASA Energy, Climate, and Environment (ECE) Program, I demonstrate how adopting best practices of development translates to better science that uses people and resources more efficiently.
For instance, the practice of unit-testing code is also a scientific strategy for ensuring internal validity: when code implements research methods, then automated tests ensure that those methods are correct representations of the phenomena represented.
This in turn avoids exhausting researchers' time in performing manual validity checks.
Next, the practice of modularity entails clearly-defined interfaces: in multi-sectoral or cross-domain integrated assessment frameworks, this is achieved through clear definitions of the background concepts, measures, scales, and system boundaries.
Making these items explicit helps researchers see quickly and precisely what translation is required to make (sub-)models interoperable with one another.&lt;/p&gt;
&lt;p&gt;Finally, sustainability requires the very research processes that support the transition to be equitable and inclusive.
I explain how the practices of making software free and open source, writing complete documentation, and continuous development lower barriers to understanding and participating in IAM-based research, especially for those not privileged to work at the few institutions that have the resources to maintain large-scale models.
As well, a broad user base translates to a flow of contributions, improved model quality, and ultimately improved perceptions of legitimacy for modeling work.&lt;/p&gt;
&lt;/div&gt;
</content><category term="article"/><category term="research"/></entry><entry><title>Structuring data with SDMX</title><link href="https://paul.kishimoto.name/2021/02/structuring-data-with-sdmx" rel="alternate"/><published>2021-02-01T00:00:00+01:00</published><updated>2021-02-01T00:00:00+01:00</updated><author><name>Paul Natsuo Kishimoto</name></author><id>tag:paul.kishimoto.name,2021-02-01:/2021/02/structuring-data-with-sdmx</id><summary type="html">&lt;p&gt;This post expands on some text from the README of &lt;a class="reference external" href="https://github.com/IAMconsortium/units/#readme"&gt;iam-units&lt;/a&gt;, in order to illustrate some improved ways to structure data and metadata.
These are especially helpful in systems research, where data from multiple disciplines/domains/contexts are often combined.&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;iam-units&lt;/span&gt;&lt;/tt&gt; is a thin wrapper around the very useful &lt;a class="reference external" href="https://pint.readthedocs.io"&gt;pint&lt;/a&gt;, that I wrote with some colleagues to handle unit conversions for data from integrated assessment models (IAMs) of energy and climate, including &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Global_warming_potential"&gt;global warming potential&lt;/a&gt; (GWP) conversions between greenhouse gas (GHG) species:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;iam_units&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;convert_gwp&lt;/span&gt;

&lt;span class="c1"&gt;# Use a pint.UnitRegistry to convert from one unit to another …&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;This post expands on some text from the README of &lt;a class="reference external" href="https://github.com/IAMconsortium/units/#readme"&gt;iam-units&lt;/a&gt;, in order to illustrate some improved ways to structure data and metadata.
These are especially helpful in systems research, where data from multiple disciplines/domains/contexts are often combined.&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;iam-units&lt;/span&gt;&lt;/tt&gt; is a thin wrapper around the very useful &lt;a class="reference external" href="https://pint.readthedocs.io"&gt;pint&lt;/a&gt;, that I wrote with some colleagues to handle unit conversions for data from integrated assessment models (IAMs) of energy and climate, including &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Global_warming_potential"&gt;global warming potential&lt;/a&gt; (GWP) conversions between greenhouse gas (GHG) species:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;iam_units&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;convert_gwp&lt;/span&gt;

&lt;span class="c1"&gt;# Use a pint.UnitRegistry to convert from one unit to another&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;qty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;3500 t&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Mt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# The result has the expected magnitude: 3500 t = 3.5 kt = 0.035 Mt&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;qty&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Quantity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.0035&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;megametric_ton&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;# Convert from mass of N₂O to GWP-equivalent mass of CO₂,&lt;/span&gt;
&lt;span class="c1"&gt;# using the metric from the IPCC Fifth Assessment Report (AR5)&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;convert_gwp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;AR5GWP100&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;N2O&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;CO2&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Quantity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.9275&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;megametric_ton&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;
&lt;div class="contents local topic" id="contents"&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#concept-observation-quantity-magnitude-unit" id="toc-entry-1"&gt;Concept, observation, quantity, magnitude, unit&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#measurement-and-nominal-properties" id="toc-entry-2"&gt;Measurement and nominal properties&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#common-ways-to-handle-ghgs-and-gwp-equivalents" id="toc-entry-3"&gt;Common ways to handle GHGs and GWP-equivalents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#using-sdmx-to-be-explicit" id="toc-entry-4"&gt;Using SDMX to be explicit&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#specify-the-concepts-and-data-structure" id="toc-entry-5"&gt;Specify the concepts and data structure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#use-the-definitions-to-structure-the-data" id="toc-entry-6"&gt;Use the definitions to structure the data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#convert-carefully" id="toc-entry-7"&gt;Convert carefully&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#take-aways" id="toc-entry-8"&gt;Take-aways&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#further-topics" id="toc-entry-9"&gt;Further topics&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;Here's the text I'd like to expand on, with emphasis added:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;convert_gwp()&lt;/tt&gt; converts from from mass (or mass-related units) of one specific greenhouse gas (GHG) species to an equivalent quantity of second species, based on GWP &lt;em&gt;metrics&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The function also accepts input with the commonly-used combination of mass (or related) units and the identity of a particular GHG species:&lt;/p&gt;
&lt;p&gt;Strictly, &lt;strong&gt;the original species is not a unit but a “nominal property”&lt;/strong&gt;; see the &lt;a class="reference external" href="https://www.bipm.org/utils/common/documents/jcgm/JCGM_200_2008.pdf"&gt;International Vocabulary of Metrology&lt;/a&gt; (VIM) &lt;a class="footnote-reference" href="#footnote-1" id="footnote-reference-1"&gt;[1]&lt;/a&gt; used in the &lt;a class="reference external" href="https://en.wikipedia.org/wiki/International_System_of_Units"&gt;SI&lt;/a&gt;.
To avoid ambiguity, code handling GHG quantities should also track and output these nominal properties, including:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Original species.&lt;/li&gt;
&lt;li&gt;Species in which GWP-equivalents are expressed (e.g. CO₂ or C)&lt;/li&gt;
&lt;li&gt;GWP metric used to convert (1) to (2).&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is one of many cases where a little up-front effort to be precise—as opposed to loose and casual—about measurement can help us write code and produce data that is as interoperable as possible.
The investment pays dividends by reducing repeated work down the road in handling imprecise data.&lt;/p&gt;
&lt;div class="section" id="concept-observation-quantity-magnitude-unit"&gt;
&lt;h2&gt;Concept, observation, quantity, magnitude, unit&lt;/h2&gt;
&lt;p&gt;Before returning to GHGs, here's a second example: in transport research we often want to discuss the following &lt;em&gt;concept&lt;/em&gt;:&lt;/p&gt;
&lt;blockquote&gt;
total distance traveled by a person (or group of people)&lt;/blockquote&gt;
&lt;p&gt;For instance, if I walk to the corner store, ride my bike to a restaurant, and then take the train to visit a friend, I might travel in total 0.5 + 4 + 10 = 14.5 kilometres.
This is a &lt;em&gt;quantity&lt;/em&gt; that expresses one &lt;em&gt;observation&lt;/em&gt; of the above concept.
The observation was, hypothetically, obtained by a process of &lt;em&gt;measurement&lt;/em&gt; (more on that shortly).
The quantity consists of the &lt;em&gt;magnitude&lt;/em&gt; “14.5” and &lt;em&gt;unit reference&lt;/em&gt; “kilometre”.&lt;/p&gt;
&lt;p&gt;We might also say:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;14.5 km&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;mile&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Quantity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;9.00988229&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;mile&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is the very same &lt;em&gt;concept&lt;/em&gt;, &lt;em&gt;observation&lt;/em&gt;, and &lt;em&gt;quantity&lt;/em&gt;, but expressed in a different &lt;em&gt;unit&lt;/em&gt; and thus having a different &lt;em&gt;magnitude&lt;/em&gt;. &lt;a class="footnote-reference" href="#footnote-2" id="footnote-reference-2"&gt;[2]&lt;/a&gt;&lt;/p&gt;
&lt;div class="section" id="measurement-and-nominal-properties"&gt;
&lt;h3&gt;Measurement and nominal properties&lt;/h3&gt;
&lt;p&gt;Something is still missing in order to be unambiguous about the observation “the travel distance is 14.5 kilometres.”
We might ask:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Is this the actual distance traveled in a specific period of time?&lt;ul&gt;
&lt;li&gt;What period? A specific day? &lt;a class="footnote-reference" href="#footnote-3" id="footnote-reference-3"&gt;[3]&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Or, as in this case, a hypothetical, counterfactual, etc.?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Is it a computed statistic? For instance:&lt;ul&gt;
&lt;li&gt;The &lt;em&gt;mean&lt;/em&gt; or &lt;em&gt;average&lt;/em&gt; travel distance across 2+ periods, for just one person (me)?&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;sum&lt;/em&gt;/collective travel distance across 2+ people, but in the same period?&lt;/li&gt;
&lt;li&gt;Something else?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The VIM calls these &lt;strong&gt;nominal properties&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In systems research, it is common to combine data and knowledge from different streams of research that take place in different contexts, with different scope and resolution.
&lt;em&gt;Within&lt;/em&gt; any particular context, there can be certain natural choices for concepts, measurement process(es), and thus certain nominal properties of the data created/handled.
These will be understood implicitly by both author and audience as the background consensus, and don't vary within that context.
To list them explicitly doesn't achieve much, and might even be a distraction and barrier to clear communication; noise that buries the signal.&lt;/p&gt;
&lt;p&gt;However: when combining data from different contexts, problems can arise when we fail to notice that the concepts, measurement processes, and nominal properties differ.
A burden thus falls on the researcher to:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Make explicit the implicit features of measurement in the different domains supplying data that she wishes to combine,&lt;/li&gt;
&lt;li&gt;Identify any differences,&lt;/li&gt;
&lt;li&gt;Choose methods to adjust for (2), and&lt;/li&gt;
&lt;li&gt;Correctly implement (3).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These tasks consume resources and create opportunities for errors that could undermine the internal validity of research.
But they're also routine, so we can use some judicious automation to reduce the work involved while getting equally- or more-valid results.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="common-ways-to-handle-ghgs-and-gwp-equivalents"&gt;
&lt;h2&gt;Common ways to handle GHGs and GWP-equivalents&lt;/h2&gt;
&lt;p&gt;Suppose we have this data:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;pd&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;species&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;N2O&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;CH4&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;CO2&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;data_a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;[&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Emissions, N2O&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;kt&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Emissions, CH4&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;5.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;kt&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Emissions, CO2&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;100.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;kt&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;],&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;variable&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;value&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;unit&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;data_b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;[&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Emissions, N2O&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;291.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;kt&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Emissions, CH4&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;146.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;kt&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Emissions, CO2&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;100.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;kt&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;],&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;variable&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;value&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;unit&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let's be very precise about what we have:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Each observation in &lt;tt class="docutils literal"&gt;data_a&lt;/tt&gt; expresses a measured mass of emissions.&lt;/li&gt;
&lt;li&gt;Each observation in &lt;tt class="docutils literal"&gt;data_b&lt;/tt&gt; expresses a mass of CO₂ that, using the AR5 100-year metric, has the potential to contribute the same amount of global warming as the corresponding mass in &lt;tt class="docutils literal"&gt;data_a&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;The ‘value’ column contains &lt;em&gt;magnitudes&lt;/em&gt;; actual &lt;em&gt;quantities&lt;/em&gt; are given by the ‘value’ and ‘unit’ columns together.&lt;/li&gt;
&lt;li&gt;The ‘variable’ column mixes concepts: the thing measured is the [mass] emitted and is the same for all observations; the species emitted varies.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Clearly, it's wrong to do the following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;data_a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;value&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;data_b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;value&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; 
&lt;span class="mi"&gt;0&lt;/span&gt;    &lt;span class="mf"&gt;292.6&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;    &lt;span class="mf"&gt;151.7&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;    &lt;span class="mf"&gt;200.6&lt;/span&gt;
&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;float64&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;These magnitudes, as bare numbers, can of course be added togther.
But the results are scientifically meaningless, since the operands are conceptually incoherent: their units are the same, but they measure different things.&lt;/p&gt;
&lt;p&gt;There are some common ways to store information that is intended to help avoid errors like this.
Strategy A is to use a &lt;em&gt;unit-like expression&lt;/em&gt; that combines the actual &lt;em&gt;unit&lt;/em&gt; with a nominal property, i.e. the species:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;data_a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;kt &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;species&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; 
         &lt;span class="n"&gt;variable&lt;/span&gt;  &lt;span class="n"&gt;value&lt;/span&gt;    &lt;span class="n"&gt;unit&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt;  &lt;span class="n"&gt;Emissions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N2O&lt;/span&gt;    &lt;span class="mf"&gt;1.1&lt;/span&gt;  &lt;span class="n"&gt;kt&lt;/span&gt; &lt;span class="n"&gt;N2O&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;  &lt;span class="n"&gt;Emissions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CH4&lt;/span&gt;    &lt;span class="mf"&gt;5.2&lt;/span&gt;  &lt;span class="n"&gt;kt&lt;/span&gt; &lt;span class="n"&gt;CH4&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;  &lt;span class="n"&gt;Emissions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CO2&lt;/span&gt;  &lt;span class="mf"&gt;100.3&lt;/span&gt;  &lt;span class="n"&gt;kt&lt;/span&gt; &lt;span class="n"&gt;CO2&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;data_b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;kt CO2-eq&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; 
         &lt;span class="n"&gt;variable&lt;/span&gt;  &lt;span class="n"&gt;value&lt;/span&gt;       &lt;span class="n"&gt;unit&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt;  &lt;span class="n"&gt;Emissions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N2O&lt;/span&gt;  &lt;span class="mf"&gt;291.5&lt;/span&gt;  &lt;span class="n"&gt;kt&lt;/span&gt; &lt;span class="n"&gt;CO2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;eq&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;  &lt;span class="n"&gt;Emissions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CH4&lt;/span&gt;  &lt;span class="mf"&gt;146.5&lt;/span&gt;  &lt;span class="n"&gt;kt&lt;/span&gt; &lt;span class="n"&gt;CO2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;eq&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;  &lt;span class="n"&gt;Emissions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CO2&lt;/span&gt;  &lt;span class="mf"&gt;100.3&lt;/span&gt;  &lt;span class="n"&gt;kt&lt;/span&gt; &lt;span class="n"&gt;CO2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;eq&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;These expressions are a common prose shorthand or abbreviation, but are not standard.
For instance, ‘-e’/‘e’, ‘-eq’/‘eq’, ‘-equiv’, and other symbols are all in use in various contexts.&lt;/p&gt;
&lt;p&gt;Strategy B is to mash even more concepts into a column named something like ‘variable’, adding (3) and (4) to (1) and (2) here:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;The property that is measured, i.e. mass.&lt;/li&gt;
&lt;li&gt;The species emitted.&lt;/li&gt;
&lt;li&gt;The species in which a GWP-equivalent is expressed.&lt;/li&gt;
&lt;li&gt;The GWP metric used.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;data_a&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; 
         &lt;span class="n"&gt;variable&lt;/span&gt;  &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;unit&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt;  &lt;span class="n"&gt;Emissions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N2O&lt;/span&gt;    &lt;span class="mf"&gt;1.1&lt;/span&gt;   &lt;span class="n"&gt;kt&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;  &lt;span class="n"&gt;Emissions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CH4&lt;/span&gt;    &lt;span class="mf"&gt;5.2&lt;/span&gt;   &lt;span class="n"&gt;kt&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;  &lt;span class="n"&gt;Emissions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CO2&lt;/span&gt;  &lt;span class="mf"&gt;100.3&lt;/span&gt;   &lt;span class="n"&gt;kt&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;data_b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;variable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;data_b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;variable&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot; (CO₂ equivalent, AR5GWP100)&amp;quot;&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; 
                                     &lt;span class="n"&gt;variable&lt;/span&gt;  &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;unit&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt;  &lt;span class="n"&gt;Emissions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;N2O&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CO&lt;/span&gt;&lt;span class="err"&gt;₂&lt;/span&gt; &lt;span class="n"&gt;equivalent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AR5GWP100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="mf"&gt;291.5&lt;/span&gt;   &lt;span class="n"&gt;kt&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;  &lt;span class="n"&gt;Emissions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CH4&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CO&lt;/span&gt;&lt;span class="err"&gt;₂&lt;/span&gt; &lt;span class="n"&gt;equivalent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AR5GWP100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="mf"&gt;146.5&lt;/span&gt;   &lt;span class="n"&gt;kt&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;  &lt;span class="n"&gt;Emissions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CO2&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CO&lt;/span&gt;&lt;span class="err"&gt;₂&lt;/span&gt; &lt;span class="n"&gt;equivalent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AR5GWP100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="mf"&gt;100.3&lt;/span&gt;   &lt;span class="n"&gt;kt&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Both of these strategies have the same basic flaw: they &lt;em&gt;combine&lt;/em&gt; instead of &lt;em&gt;distinguishing&lt;/em&gt; different aspects of measurement.
Researchers might make choices that feel ‘natural’ in specific contexts, yet which differ from equally natural choices made by others.
This creates a proliferation of idiosyncratic formats, and entails further work in parsing and harmonizing.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="using-sdmx-to-be-explicit"&gt;
&lt;h2&gt;Using SDMX to be explicit&lt;/h2&gt;
&lt;p&gt;I maintain &lt;a class="reference external" href="https://sdmx1.readthedocs.io"&gt;sdmx1&lt;/a&gt;, a Python package that implements the SDMX Information Model, or ISO 17369:2013.
An “information model” (IM) is a &lt;em&gt;model&lt;/em&gt; (a set of concepts and their relationships) for talking about &lt;em&gt;information&lt;/em&gt; (data and metadata) and its representation.
(The documentation for the package links to some &lt;a class="reference external" href="https://sdmx1.readthedocs.io/en/latest/resources.html"&gt;learning resources for SDMX&lt;/a&gt;; the details aren't repeated here.)&lt;/p&gt;
&lt;p&gt;Because it is carefully developed, the SDMX IM allows us to precisely capture the concepts and relationships in our example data, including our choices in measurement and of units.&lt;/p&gt;
&lt;p&gt;The rest of this post gives a minimal demonstration.&lt;/p&gt;
&lt;div class="section" id="specify-the-concepts-and-data-structure"&gt;
&lt;h3&gt;Specify the concepts and data structure&lt;/h3&gt;
&lt;p&gt;We start by defining each of the distinct concepts that occur in our data:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sdmx&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sdmx.model.v21&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;model&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;emission&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Concept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;EMISSION&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Mass of greenhouse gas emitted&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;species_concept&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Concept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SPECIES&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Chemical species or substance&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;gwp_metric&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Concept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;GWP_METRIC&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Set of GWPs used to convert species&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 

&lt;span class="c1"&gt;# “UNIT_MEASURE” is commonly used in SDMX applications&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;unit_concept&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Concept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;UNIT_MEASURE&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Unit of measurement&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next, we define the structure of our data.
We start with the &lt;em&gt;primary measure&lt;/em&gt;, the concept that is measured:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;dsd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataStructureDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;GHG_DATA&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# - Refer to the concept&lt;/span&gt;
&lt;span class="c1"&gt;# - Use concept&amp;#39;s ID for the primary measure as well&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;pm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrimaryMeasure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;concept_identity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;emission&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;emission&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 

&lt;span class="c1"&gt;# Store in the DSD&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;dsd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;measures&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next, we specify that values for the &lt;tt class="docutils literal"&gt;gwp_metric&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;unit&lt;/tt&gt; concepts are stored as &lt;em&gt;attributes&lt;/em&gt;.
SDMX allows several options for where we attach these attributes.
Here, we specify that the attributes are attached to entire data sets.
This means that, in a particular data set, only one GWP metric can be used, and one unit: &lt;a class="footnote-reference" href="#footnote-4" id="footnote-reference-4"&gt;[4]&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# 1. Define the data attribute&lt;/span&gt;
&lt;span class="c1"&gt;#    - Refer to the concept&lt;/span&gt;
&lt;span class="c1"&gt;#    - Use concept&amp;#39;s ID for the attribute as well&lt;/span&gt;
&lt;span class="c1"&gt;#    - NoSpecifiedRelationship = attached to data set&lt;/span&gt;
&lt;span class="c1"&gt;# 2. Store in the DSD&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;concept&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gwp_metric&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unit_concept&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;da&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="n"&gt;concept_identity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;concept&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;concept&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="n"&gt;related_to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NoSpecifiedRelationship&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;dsd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;da&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally, we specify that our data has two dimensions.
Every observation in a data set must have a unique Key with values for these dimensions.&lt;/p&gt;
&lt;p&gt;Both dimensions refer to the same concept (species), but we give them different IDs and names to explain what these signify.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SPECIES&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Original species emitted&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="s2"&gt;&amp;quot;SPECIES_GWP&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="s2"&gt;&amp;quot;Species in which GWP equivalent is expressed&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;),&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;)):&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;dim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dimension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="n"&gt;concept_identity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;species_concept&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;dsd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dimensions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We now have a complete description of our data structure:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;dsd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;measures&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MeasureDescriptor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PrimaryMeasure&lt;/span&gt; &lt;span class="n"&gt;EMISSION&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;dsd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AttributeDescriptor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;DataAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;annotations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;GWP_METRIC&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;concept_identity&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Concept&lt;/span&gt; &lt;span class="n"&gt;GWP_METRIC&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Set&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;GWPs&lt;/span&gt; &lt;span class="n"&gt;used&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;convert&lt;/span&gt; &lt;span class="n"&gt;species&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;local_representation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;related_to&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="nc"&gt;sdmx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;v21&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NoSpecifiedRelationship&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;gt;, usage_status=None, concept_role=None); DataAttribute(annotations=[], id=&amp;#39;&lt;/span&gt;&lt;span class="n"&gt;UNIT_MEASURE&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;, uri=None, urn=None, concept_identity=&amp;lt;Concept UNIT_MEASURE: Unit of measurement&amp;gt;, local_representation=None, related_to=&amp;lt;class &amp;#39;&lt;/span&gt;&lt;span class="n"&gt;sdmx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;v21&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NoSpecifiedRelationship&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;gt;, usage_status=None, concept_role=None)&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;dsd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dimensions&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;DimensionDescriptor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;annotations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;urn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Dimension&lt;/span&gt; &lt;span class="n"&gt;SPECIES&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Dimension&lt;/span&gt; &lt;span class="n"&gt;SPECIES_GWP&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="use-the-definitions-to-structure-the-data"&gt;
&lt;h3&gt;Use the definitions to structure the data&lt;/h3&gt;
&lt;p&gt;Now we can create a data set that is &lt;em&gt;structured by&lt;/em&gt; this definition:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;29&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;ds_a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataSet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;structured_by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;dsd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We store the values of attributes attached to the data set:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# Define a function to create attribute values and store them.&lt;/span&gt;
&lt;span class="c1"&gt;# The `value_for` property links each value to the definition&lt;/span&gt;
&lt;span class="c1"&gt;# of the attribute in the DSD, and thus to a concept.&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;store_attributes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;concept_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="n"&gt;av&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AttributeValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;             &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;             &lt;span class="n"&gt;value_for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;dsd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;concept_id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="n"&gt;ds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attrib&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;concept_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;av&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;store_attributes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;ds_a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;GWP_METRIC&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;(None)&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;UNIT_MEASURE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;kt&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally we store the individual observations.
In the case of &lt;tt class="docutils literal"&gt;data_a&lt;/tt&gt;, the labels for the SPECIES and SPECIES_GWP dimensions are the same:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# 1. Discard redundant portion of the ‘variable’ column.&lt;/span&gt;
&lt;span class="c1"&gt;# 2. Create a key object from labels for each dimension.&lt;/span&gt;
&lt;span class="c1"&gt;# 3. Create the observation.&lt;/span&gt;
&lt;span class="c1"&gt;#    - The value is ‘for’ the primary measure, i.e. emissions.&lt;/span&gt;
&lt;span class="c1"&gt;# 4. Store in the data set.&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data_a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iterrows&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;variable&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Emissions, &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;dims&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SPECIES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SPECIES_GWP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dsd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;make_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dims&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;obs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Observation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;value&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;value_for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;pm&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;ds_a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;obs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We now have a complete data set.
&lt;tt class="docutils literal"&gt;sdmx1&lt;/tt&gt; provides features for converting to other data structures and file formats:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;ds_a&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;DataSet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;annotations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;valid_from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;described_by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;structured_by&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DataStructureDefinition&lt;/span&gt; &lt;span class="n"&gt;GHG_DATA&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;obs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Observation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attached_attribute&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;series_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SPECIES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;N2O&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SPECIES_GWP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;N2O&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;group_keys&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;value_for&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PrimaryMeasure&lt;/span&gt; &lt;span class="n"&gt;EMISSION&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Observation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attached_attribute&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;series_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SPECIES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CH4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SPECIES_GWP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CH4&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;5.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;group_keys&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;value_for&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PrimaryMeasure&lt;/span&gt; &lt;span class="n"&gt;EMISSION&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Observation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attached_attribute&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;series_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SPECIES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CO2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SPECIES_GWP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CO2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;100.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;group_keys&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;value_for&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PrimaryMeasure&lt;/span&gt; &lt;span class="n"&gt;EMISSION&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt; &lt;span class="n"&gt;series&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;attrib&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;GWP_METRIC&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AttributeValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;GWP_METRIC&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;UNIT_MEASURE&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AttributeValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UNIT_MEASURE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;kt&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;# pandas.DataFrame&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;34&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;sdmx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_pandas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ds_a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;od&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;34&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; 
&lt;span class="n"&gt;SPECIES&lt;/span&gt;  &lt;span class="n"&gt;SPECIES_GWP&lt;/span&gt;
&lt;span class="n"&gt;N2O&lt;/span&gt;      &lt;span class="n"&gt;N2O&lt;/span&gt;              &lt;span class="mf"&gt;1.1&lt;/span&gt;
&lt;span class="n"&gt;CH4&lt;/span&gt;      &lt;span class="n"&gt;CH4&lt;/span&gt;              &lt;span class="mf"&gt;5.2&lt;/span&gt;
&lt;span class="n"&gt;CO2&lt;/span&gt;      &lt;span class="n"&gt;CO2&lt;/span&gt;            &lt;span class="mf"&gt;100.3&lt;/span&gt;
&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;float64&lt;/span&gt;

&lt;span class="c1"&gt;# Standardized SDMX-ML format&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;sdmx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_xml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ds_a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pretty_print&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;lt;?xml version=&lt;/span&gt;&lt;span class="se"&gt;\&amp;#39;&lt;/span&gt;&lt;span class="s1"&gt;1.0&lt;/span&gt;&lt;span class="se"&gt;\&amp;#39;&lt;/span&gt;&lt;span class="s1"&gt; encoding=&lt;/span&gt;&lt;span class="se"&gt;\&amp;#39;&lt;/span&gt;&lt;span class="s1"&gt;utf-8&lt;/span&gt;&lt;span class="se"&gt;\&amp;#39;&lt;/span&gt;&lt;span class="s1"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;mes:DataSet xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; xmlns:com=&amp;quot;http://www.sdmx.org/resources/sdmxml/schemas/v2_1/common&amp;quot; xmlns:data=&amp;quot;http://www.sdmx.org/resources/sdmxml/schemas/v2_1/data/structurespecific&amp;quot; xmlns:footer=&amp;quot;http://www.sdmx.org/resources/sdmxml/schemas/v2_1/message/footer&amp;quot; xmlns:gen=&amp;quot;http://www.sdmx.org/resources/sdmxml/schemas/v2_1/data/generic&amp;quot; xmlns:md_ss=&amp;quot;http://www.sdmx.org/resources/sdmxml/schemas/v2_1/metadata/structurespecific&amp;quot; xmlns:md=&amp;quot;http://www.sdmx.org/resources/sdmxml/schemas/v2_1/metadata/generic&amp;quot; xmlns:mes=&amp;quot;http://www.sdmx.org/resources/sdmxml/schemas/v2_1/message&amp;quot; xmlns:reg=&amp;quot;http://www.sdmx.org/resources/sdmxml/schemas/v2_1/registry&amp;quot; xmlns:str=&amp;quot;http://www.sdmx.org/resources/sdmxml/schemas/v2_1/structure&amp;quot; structureRef=&amp;quot;GHG_DATA&amp;quot;&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;  &amp;lt;gen:Attributes&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;    &amp;lt;gen:Value id=&amp;quot;GWP_METRIC&amp;quot; value=&amp;quot;(None)&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;    &amp;lt;gen:Value id=&amp;quot;UNIT_MEASURE&amp;quot; value=&amp;quot;kt&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;  &amp;lt;/gen:Attributes&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;  &amp;lt;gen:Obs&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;    &amp;lt;gen:ObsKey&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;      &amp;lt;gen:Value id=&amp;quot;SPECIES&amp;quot; value=&amp;quot;N2O&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;      &amp;lt;gen:Value id=&amp;quot;SPECIES_GWP&amp;quot; value=&amp;quot;N2O&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;    &amp;lt;/gen:ObsKey&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;    &amp;lt;gen:ObsValue value=&amp;quot;1.1&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;  &amp;lt;/gen:Obs&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;  &amp;lt;gen:Obs&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;    &amp;lt;gen:ObsKey&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;      &amp;lt;gen:Value id=&amp;quot;SPECIES&amp;quot; value=&amp;quot;CH4&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;      &amp;lt;gen:Value id=&amp;quot;SPECIES_GWP&amp;quot; value=&amp;quot;CH4&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;    &amp;lt;/gen:ObsKey&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;    &amp;lt;gen:ObsValue value=&amp;quot;5.2&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;  &amp;lt;/gen:Obs&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;  &amp;lt;gen:Obs&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;    &amp;lt;gen:ObsKey&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;      &amp;lt;gen:Value id=&amp;quot;SPECIES&amp;quot; value=&amp;quot;CO2&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;      &amp;lt;gen:Value id=&amp;quot;SPECIES_GWP&amp;quot; value=&amp;quot;CO2&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;    &amp;lt;/gen:ObsKey&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;    &amp;lt;gen:ObsValue value=&amp;quot;100.3&amp;quot;/&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;  &amp;lt;/gen:Obs&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;/mes:DataSet&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="convert-carefully"&gt;
&lt;h3&gt;Convert carefully&lt;/h3&gt;
&lt;p&gt;Finally, we can convert &lt;tt class="docutils literal"&gt;ds_a&lt;/tt&gt; using &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;iam-units&lt;/span&gt;&lt;/tt&gt; while maintaining an explicit and unambiguous data structure.&lt;/p&gt;
&lt;p&gt;We create a second data set using the same data structure definition:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;ds_b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataSet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;structured_by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;dsd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Store attributes:&lt;/span&gt;
&lt;span class="c1"&gt;# GWP metric name to use in conversion&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;AR5GWP100&amp;quot;&lt;/span&gt;

&lt;span class="c1"&gt;# Unit used in both data sets&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;38&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;unit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ds_a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attrib&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;UNIT_MEASURE&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;39&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;store_attributes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;ds_b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GWP_METRIC&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UNIT_MEASURE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;unit&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For each observation, we convert its magnitude, and change &lt;em&gt;only&lt;/em&gt; the “SPECIES_GWP” key value:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# Target species for conversion&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;target_species&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;CO2&amp;quot;&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Store the original species.&lt;/span&gt;
&lt;span class="c1"&gt;# 2. Create a new key with SPECIES_GWP set to `target_species`.&lt;/span&gt;
&lt;span class="c1"&gt;# 3. Convert the magnitude using the metric and iam-units.&lt;/span&gt;
&lt;span class="c1"&gt;# 4. Create a new observation and store in `ds_b`.&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;41&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;obs&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ds_a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;obs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;species&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;obs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SPECIES&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dsd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;make_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SPECIES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;species&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SPECIES_GWP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;target_species&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;convert_gwp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Quantity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="n"&gt;species&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="n"&gt;target_species&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;magnitude&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;ds_b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;obs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Observation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;             &lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value_for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;pm&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The resulting data set has the same format as &lt;tt class="docutils literal"&gt;ds_a&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;ds_b&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;DataSet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;annotations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;valid_from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;described_by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;structured_by&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DataStructureDefinition&lt;/span&gt; &lt;span class="n"&gt;GHG_DATA&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;obs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Observation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attached_attribute&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;series_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SPECIES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;N2O&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SPECIES_GWP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CO2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;291.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;group_keys&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;value_for&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PrimaryMeasure&lt;/span&gt; &lt;span class="n"&gt;EMISSION&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Observation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attached_attribute&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;series_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SPECIES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CH4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SPECIES_GWP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CO2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;145.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;group_keys&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;value_for&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PrimaryMeasure&lt;/span&gt; &lt;span class="n"&gt;EMISSION&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Observation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attached_attribute&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;series_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dimension&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SPECIES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CO2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SPECIES_GWP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CO2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;100.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;group_keys&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;value_for&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PrimaryMeasure&lt;/span&gt; &lt;span class="n"&gt;EMISSION&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt; &lt;span class="n"&gt;series&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;attrib&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;GWP_METRIC&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AttributeValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;GWP_METRIC&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;AR5GWP100&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;UNIT_MEASURE&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AttributeValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UNIT_MEASURE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;kt&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;sdmx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_pandas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ds_b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;do&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; 
&lt;span class="n"&gt;SPECIES&lt;/span&gt;  &lt;span class="n"&gt;SPECIES_GWP&lt;/span&gt;
&lt;span class="n"&gt;N2O&lt;/span&gt;      &lt;span class="n"&gt;CO2&lt;/span&gt;            &lt;span class="mf"&gt;291.5&lt;/span&gt;
&lt;span class="n"&gt;CH4&lt;/span&gt;      &lt;span class="n"&gt;CO2&lt;/span&gt;            &lt;span class="mf"&gt;145.6&lt;/span&gt;
&lt;span class="n"&gt;CO2&lt;/span&gt;      &lt;span class="n"&gt;CO2&lt;/span&gt;            &lt;span class="mf"&gt;100.3&lt;/span&gt;
&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;float64&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="take-aways"&gt;
&lt;h2&gt;Take-aways&lt;/h2&gt;
&lt;p&gt;To review, by applying the SDMX Information Model, we were able to:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Define exactly the concepts relevant to our data.&lt;/li&gt;
&lt;li&gt;Use these to create a clear and unambigous structure, in which concepts were used for the primary measure, as attributes, or dimensions of multi-dimensional data.&lt;/li&gt;
&lt;li&gt;Unpack a ‘variable’ column into its constituent concepts, and avoid overloading it further with additional concepts.&lt;/li&gt;
&lt;li&gt;Store simple or bare SI units, parseable by &lt;tt class="docutils literal"&gt;pint&lt;/tt&gt;, for the “UNIT_MEASURE” attribute, and avoid overloading this with unrelated concepts.&lt;/li&gt;
&lt;li&gt;Access structured metadata and use it in the process of converting data.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="section" id="further-topics"&gt;
&lt;h3&gt;Further topics&lt;/h3&gt;
&lt;p&gt;The amount of code used to handle only 3 observations might seem excessive.
The up-front investment, however, unlocks further improvements in handling data and metadata.
As a sketch of these:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;Applications can additionally specify a &lt;em&gt;representation&lt;/em&gt; for any concept used for a measure, attribute, or dimension.&lt;/p&gt;
&lt;p&gt;For instance, we could specify that the “SPECIES” dimension represents the concept of species using only codes from a certain list of species understood to be GHGs: CH4, CO2, N2O, and so on.
The code list is a mechanism for communicating about the data:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;“This data contains codes that are invalid, not in the specified list” can flag errors in data preparation.&lt;/li&gt;
&lt;li&gt;A data provider can specify a subset of the codes that will appear in their published data sets or data flows.
Users then understand not to expect values outside this subset.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;The concepts and other structures can be shared and reused.
For instance, as described in footnote &lt;a class="footnote-reference" href="#footnote-4" id="footnote-reference-5"&gt;[4]&lt;/a&gt;, we could construct a &lt;em&gt;different&lt;/em&gt; data structure definition using the &lt;em&gt;same&lt;/em&gt; concepts, as required for a different application.&lt;/p&gt;
&lt;p&gt;The re-use of the same concepts tells users about links between multiple data sets and flows.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Published structures allow multiple data providers to prepare data that is guaranteed to be interoperable.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr class="docutils" /&gt;
&lt;p&gt;&lt;strong&gt;Footnotes&lt;/strong&gt;&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="footnote-1" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-1"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;The VIM is good reading and food for thought on these topics; more giant shoulders that we stand on, even if it seems as pedestrian as a dictionary.
I encourage everyone to skim it!&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="footnote-2" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-2"&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p class="first"&gt;It's very common to conflate concepts and units.
Do not do this.&lt;/p&gt;
&lt;p&gt;For instance, “passenger/person distance traveled” (PDT) is often called “PKT” (meaning “passenger kilometres travelled”) or “PMT” (“person-miles traveled”).
This conflates units (kilometres, miles) with the quantity (distance) measured.
Two data sets with observations labelled “PKT” and “PMT” might measure the same concept—that is, PDT—in the same way with the same nominal properties, but merely express the resulting quantities in different units.&lt;/p&gt;
&lt;p class="last"&gt;Always label dimensions or observations with the &lt;em&gt;concept measured&lt;/em&gt;, not the &lt;em&gt;units&lt;/em&gt; of particular measurements.&lt;/p&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="footnote-3" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-3"&gt;[3]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;…or, during this pandemic, month or year? 😭️&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="footnote-4" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;[4]&lt;/td&gt;&lt;td&gt;&lt;em&gt;(&lt;a class="fn-backref" href="#footnote-reference-4"&gt;1&lt;/a&gt;, &lt;a class="fn-backref" href="#footnote-reference-5"&gt;2&lt;/a&gt;)&lt;/em&gt; &lt;p&gt;This is simply for brevity, not a limitation of SDMX.&lt;/p&gt;
&lt;p class="last"&gt;We could equally, for instance, specify that &lt;tt class="docutils literal"&gt;gwp_metric&lt;/tt&gt; is attached to series keys or individual observations.
This would allow a single data set to contain the same measurements with magnitudes expressed in multiple ways via multiple GWP metrics.&lt;/p&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="article"/><category term="data"/><category term="integrated-assessment"/><category term="python"/><category term="research"/><category term="sdmx"/><category term="software"/></entry><entry><title>Handling country codes</title><link href="https://paul.kishimoto.name/2021/01/handling-country-codes" rel="alternate"/><published>2021-01-28T00:00:00+01:00</published><updated>2021-01-28T00:00:00+01:00</updated><author><name>Paul Natsuo Kishimoto</name></author><id>tag:paul.kishimoto.name,2021-01-28:/2021/01/handling-country-codes</id><summary type="html">&lt;p&gt;In research with global scope and country- or country-group resolution, it's common to handle data with one or more &lt;a class="footnote-reference" href="#footnote-1" id="footnote-reference-1"&gt;[1]&lt;/a&gt; dimension(s) identifying a country (countries) for each observation.
Problems can arise when inconsistent identifiers—“United States” vs. “United States of America”—are used to label this dimension, either across different data sets, or within one data set.&lt;/p&gt;
&lt;p&gt;The best precaution against these problems is to convert idiosyncratic identifiers to short, standard ones, as soon as possible.
&lt;a class="reference external" href="https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes"&gt;ISO 3166 alpha-2 or alpha-3 codes&lt;/a&gt; (&lt;tt class="docutils literal"&gt;CA&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;CAN&lt;/tt&gt; for Canada) are a natural choice for standard identifiers. &lt;a class="footnote-reference" href="#footnote-2" id="footnote-reference-2"&gt;[2]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In this post, I …&lt;/p&gt;</summary><content type="html">&lt;p&gt;In research with global scope and country- or country-group resolution, it's common to handle data with one or more &lt;a class="footnote-reference" href="#footnote-1" id="footnote-reference-1"&gt;[1]&lt;/a&gt; dimension(s) identifying a country (countries) for each observation.
Problems can arise when inconsistent identifiers—“United States” vs. “United States of America”—are used to label this dimension, either across different data sets, or within one data set.&lt;/p&gt;
&lt;p&gt;The best precaution against these problems is to convert idiosyncratic identifiers to short, standard ones, as soon as possible.
&lt;a class="reference external" href="https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes"&gt;ISO 3166 alpha-2 or alpha-3 codes&lt;/a&gt; (&lt;tt class="docutils literal"&gt;CA&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;CAN&lt;/tt&gt; for Canada) are a natural choice for standard identifiers. &lt;a class="footnote-reference" href="#footnote-2" id="footnote-reference-2"&gt;[2]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In this post, I show a way to do this in a few lines of performant Python code, using some common packages and tools.
The sections are titled with some general points of advice that also apply to other programming tasks.&lt;/p&gt;
&lt;div class="contents local topic" id="contents"&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#find-and-use-well-tested-tools" id="toc-entry-1"&gt;1. Find and use well-tested tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#understand-the-standard-library" id="toc-entry-2"&gt;2. Understand the standard library&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#dict-get" id="toc-entry-3"&gt;&lt;tt class="docutils literal"&gt;dict.get()&lt;/tt&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#decorate-with-functools-lru-cache" id="toc-entry-4"&gt;Decorate with &lt;tt class="docutils literal"&gt;functools.lru_cache()&lt;/tt&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#find-and-use-optimized-code" id="toc-entry-5"&gt;3. Find and use optimized code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#wrapping-up" id="toc-entry-6"&gt;Wrapping up&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#concluding-thoughts" id="toc-entry-7"&gt;Concluding thoughts&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="find-and-use-well-tested-tools"&gt;
&lt;h2&gt;1. Find and use well-tested tools&lt;/h2&gt;
&lt;p&gt;In this example, we'll want to use &lt;a class="reference external" href="https://pypi.org/project/pycountry/"&gt;pycountry&lt;/a&gt;, a package that has existed since 2008 and, per its documentation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;…provides the ISO databases for the standards:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;3166 Countries&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The package includes a copy from Debian’s pkg-isocodes and makes the data accessible through a Python API.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It's easy to use and fast:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pycountry&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;countries&lt;/span&gt;

&lt;span class="c1"&gt;# Get a country by its code&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;countries&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alpha_2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;CA&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;Country&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alpha_2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;CA&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alpha_3&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;CAN&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;🇨🇦&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Canada&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numeric&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;124&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Lookup on any field: alpha_2, alpha_3, or name:&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;countries&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lookup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Canada&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;Country&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alpha_2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;CA&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alpha_3&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;CAN&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;🇨🇦&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Canada&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numeric&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;124&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Fuzzy search returns a list() of results&lt;/span&gt;
&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;countries&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search_fuzzy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Korea&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; 
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Country&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alpha_2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;KP&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alpha_3&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;PRK&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;common_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;North Korea&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;🇰🇵&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Korea, Democratic People&amp;#39;s Republic of&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numeric&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;408&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;official_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Democratic People&amp;#39;s Republic of Korea&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
 &lt;span class="n"&gt;Country&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alpha_2&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;KR&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alpha_3&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;KOR&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;common_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;South Korea&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;🇰🇷&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Korea, Republic of&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numeric&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;410&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;pycountry&lt;/tt&gt; is downloaded about 56,000 times &lt;em&gt;every day&lt;/em&gt;:&lt;/p&gt;
&lt;img alt="Rate of PyPI downloads" src="https://img.shields.io/pypi/dd/pycountry" /&gt;
&lt;p&gt;As with &lt;tt class="docutils literal"&gt;pandas&lt;/tt&gt;, below, heavy usage is both an indicator of and contributor to quality.
Hypothetically, we could copy the ISO 3166 table from Wikipedia into a CSV file and write some code to query it.
But there's no point in doing this.
The result will certainly be slower, more likely to contain bugs, and have fewer features than &lt;tt class="docutils literal"&gt;pycountry&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="understand-the-standard-library"&gt;
&lt;h2&gt;2. Understand the standard library&lt;/h2&gt;
&lt;p&gt;Some example data:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;pd&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Austria&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2021&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Bosnia&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2021&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2.2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Canada&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2021&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3.3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;UK&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2021&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;4.4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;UK&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2022&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;5.5&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;country&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;year&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;value&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; 
   &lt;span class="n"&gt;country&lt;/span&gt;  &lt;span class="n"&gt;year&lt;/span&gt;  &lt;span class="n"&gt;value&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt;  &lt;span class="n"&gt;Austria&lt;/span&gt;  &lt;span class="mi"&gt;2021&lt;/span&gt;    &lt;span class="mf"&gt;1.1&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;   &lt;span class="n"&gt;Bosnia&lt;/span&gt;  &lt;span class="mi"&gt;2021&lt;/span&gt;    &lt;span class="mf"&gt;2.2&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;   &lt;span class="n"&gt;Canada&lt;/span&gt;  &lt;span class="mi"&gt;2021&lt;/span&gt;    &lt;span class="mf"&gt;3.3&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;       &lt;span class="n"&gt;UK&lt;/span&gt;  &lt;span class="mi"&gt;2021&lt;/span&gt;    &lt;span class="mf"&gt;4.4&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;       &lt;span class="n"&gt;UK&lt;/span&gt;  &lt;span class="mi"&gt;2022&lt;/span&gt;    &lt;span class="mf"&gt;5.5&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What is in the &amp;quot;country&amp;quot; column/dimension?&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;“Canada” and “Austria” are direct matches for the ‘name’ field of the ISO 3166-1 database.&lt;/li&gt;
&lt;li&gt;“Bosnia” is only a partial match for the name “Bosnia and Herzegovina”.&lt;/li&gt;
&lt;li&gt;“UK” is an idiosyncratic identifier: the ISO 3166-1 codes for the United Kingdom are &lt;tt class="docutils literal"&gt;GB&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;GBR&lt;/tt&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We create a mapping with the idiosyncrasies of this data set:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;country_map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="s2"&gt;&amp;quot;Bosnia&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Bosnia and Herzegovina&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="s2"&gt;&amp;quot;UK&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;United Kingdom&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This allows us to look up a correct value for an incorrect one:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;country_map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;UK&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;United Kingdom&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="section" id="dict-get"&gt;
&lt;h3&gt;&lt;tt class="docutils literal"&gt;dict.get()&lt;/tt&gt;&lt;/h3&gt;
&lt;p&gt;Do we need to include “Austria” and “Canada” in this dictionary?
No.
The standard &lt;a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#dict.Get"&gt;dict.get()&lt;/a&gt; method allows a &lt;cite&gt;default&lt;/cite&gt; argument:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;country&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;country_map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
&lt;span class="n"&gt;Austria&lt;/span&gt;
&lt;span class="n"&gt;Bosnia&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Herzegovina&lt;/span&gt;
&lt;span class="n"&gt;Canada&lt;/span&gt;
&lt;span class="n"&gt;United&lt;/span&gt; &lt;span class="n"&gt;Kingdom&lt;/span&gt;
&lt;span class="n"&gt;United&lt;/span&gt; &lt;span class="n"&gt;Kingdom&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When &lt;tt class="docutils literal"&gt;name&lt;/tt&gt; is “Canada”, the lookup fails; “Canada” is not a key in the dictionary.
The &lt;cite&gt;default&lt;/cite&gt; argument is returned: “Canada”.
This is a &lt;strong&gt;no-op&lt;/strong&gt; or &lt;strong&gt;pass-through&lt;/strong&gt;; it does nothing.
Code that passes through some values while altering others will always perform better than code that does comparisons (&lt;tt class="docutils literal"&gt;if name == &amp;quot;UK&amp;quot;: …&lt;/tt&gt;).&lt;/p&gt;
&lt;p&gt;Undersetanding that &lt;tt class="docutils literal"&gt;get()&lt;/tt&gt; takes a &lt;cite&gt;default&lt;/cite&gt; argument allows us to make &lt;tt class="docutils literal"&gt;country_map&lt;/tt&gt; &lt;strong&gt;parsimonious&lt;/strong&gt; and easy to read.
It includes only important information (the incorrect labels appearing in this data set) and does not obscure them with unnecessary information.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="decorate-with-functools-lru-cache"&gt;
&lt;h3&gt;Decorate with &lt;tt class="docutils literal"&gt;functools.lru_cache()&lt;/tt&gt;&lt;/h3&gt;
&lt;p&gt;A real data set, unlike our example &lt;tt class="docutils literal"&gt;data&lt;/tt&gt;, will contain many rows, sometimes with the same incorrect identifiers repeated many times.
To speed up any operation we want to do with this data, we can use &lt;a class="reference external" href="https://docs.python.org/3/library/functools.html#functools.lru_cache"&gt;lru_cache()&lt;/a&gt;, &lt;a class="footnote-reference" href="#footnote-3" id="footnote-reference-3"&gt;[3]&lt;/a&gt; a function from the &lt;tt class="docutils literal"&gt;functools&lt;/tt&gt; module of Python's standard library.&lt;/p&gt;
&lt;p&gt;Go read the documentation! I'll wait.&lt;/p&gt;
&lt;p&gt;We use this to &lt;strong&gt;decorate&lt;/strong&gt; a function.
It matches return values to input, and avoids running the (potentially slow) function when it sees a value for which a result has already been computed:&lt;/p&gt;
&lt;!-- NB use the "In […]:" syntax here to prevent the ipython.sphinxext code from eating the @lru_cache() --&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;functools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;lru_cache&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nd"&gt;@lru_cache&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fix_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;country_map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;country&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fix_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
&lt;span class="n"&gt;Austria&lt;/span&gt;
&lt;span class="n"&gt;Bosnia&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Herzegovina&lt;/span&gt;
&lt;span class="n"&gt;Canada&lt;/span&gt;
&lt;span class="n"&gt;United&lt;/span&gt; &lt;span class="n"&gt;Kingdom&lt;/span&gt;
&lt;span class="n"&gt;United&lt;/span&gt; &lt;span class="n"&gt;Kingdom&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can inspect the cache that is created as &lt;tt class="docutils literal"&gt;fix_name()&lt;/tt&gt; is called multiple times:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;fix_name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cache_info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;CacheInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;misses&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;maxsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;currsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;currsize=4&lt;/tt&gt; tells us that 4 values have been cached over 5 calls.
&lt;tt class="docutils literal"&gt;hits=1&lt;/tt&gt; tells us that the second occurrence of “UK” was handled by returning a cached value, instead of running the body of &lt;tt class="docutils literal"&gt;fix_name()&lt;/tt&gt; again with the same input. &lt;a class="footnote-reference" href="#footnote-4" id="footnote-reference-4"&gt;[4]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="find-and-use-optimized-code"&gt;
&lt;h2&gt;3. Find and use optimized code&lt;/h2&gt;
&lt;p&gt;Our &lt;tt class="docutils literal"&gt;data&lt;/tt&gt; is a &lt;a class="reference external" href="https://pandas.pydata.org/docs/reference/index.html"&gt;pandas&lt;/a&gt; data structure.
Pandas is a very widely used library with many users and contributors. &lt;a class="footnote-reference" href="#footnote-5" id="footnote-reference-5"&gt;[5]&lt;/a&gt;
For these reasons, it is internally very sophisticated; many common operations—indeed, almost all operations that most of us will perform in daily use—have been optimized, some using low-level C code, for speed and memory performance.&lt;/p&gt;
&lt;p&gt;The simple upshot is that &lt;strong&gt;it is almost never necessary to write Python loops&lt;/strong&gt; (&lt;tt class="docutils literal"&gt;for …:&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;while …:&lt;/tt&gt;) when using pandas.
If you &lt;em&gt;do&lt;/em&gt; find yourself writing loops, it is likely that you can instead find and use existing, optimized functionality in pandas.&lt;/p&gt;
&lt;p&gt;I strongly recommend doing this: your code will be both simpler and more performant.&lt;/p&gt;
&lt;p&gt;Above, we looped over the values in the &amp;quot;country&amp;quot; column of &lt;tt class="docutils literal"&gt;data&lt;/tt&gt;.
(Remember: each column of a &lt;tt class="docutils literal"&gt;pandas.DataFrame&lt;/tt&gt; is a &lt;tt class="docutils literal"&gt;pandas.Series&lt;/tt&gt;.)
The feature we should use instead is &lt;a class="reference external" href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.apply.html"&gt;pandas.Series.apply()&lt;/a&gt;.
(Again: go read the documentation, all of it.)&lt;/p&gt;
&lt;p&gt;This looks like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;country&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fix_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; 
&lt;span class="mi"&gt;0&lt;/span&gt;                   &lt;span class="n"&gt;Austria&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;    &lt;span class="n"&gt;Bosnia&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Herzegovina&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;                    &lt;span class="n"&gt;Canada&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;            &lt;span class="n"&gt;United&lt;/span&gt; &lt;span class="n"&gt;Kingdom&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;            &lt;span class="n"&gt;United&lt;/span&gt; &lt;span class="n"&gt;Kingdom&lt;/span&gt;
&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;country&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Pandas takes care of calling &lt;tt class="docutils literal"&gt;fix_name()&lt;/tt&gt; many times, once for each value in this column, and assembling the result into a new series.
It internally speeds up and, where possible, parallelizes these calls: the point is &lt;em&gt;we don't need to think about how it does this&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Also, because we've memoized with &lt;tt class="docutils literal"&gt;lru_cache()&lt;/tt&gt;, after a certain point each call becomes as quick as a dictionary lookup, no matter how expensive &lt;tt class="docutils literal"&gt;fix_name()&lt;/tt&gt; is:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;fix_name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cache_info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;CacheInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;misses&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;maxsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;currsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;More cache hits have occurred.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="wrapping-up"&gt;
&lt;h2&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;Now we finally bring in &lt;tt class="docutils literal"&gt;pycountry&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nd"&gt;@lru_cache&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;code_for_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;countries&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;country_map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alpha_3&lt;/span&gt;
   &lt;span class="o"&gt;....&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This function first uses &lt;tt class="docutils literal"&gt;country_map&lt;/tt&gt; to correct data set idiosyncrasies, then uses &lt;tt class="docutils literal"&gt;pycountry.get()&lt;/tt&gt; to look up a record using the ‘name’ field.
Finally, it returns the ‘alpha_3’ code from the record.&lt;/p&gt;
&lt;p&gt;We &lt;tt class="docutils literal"&gt;apply()&lt;/tt&gt; this new function to the ‘country’ column:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;country&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code_for_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; 
&lt;span class="mi"&gt;0&lt;/span&gt;    &lt;span class="n"&gt;AUT&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;    &lt;span class="n"&gt;BIH&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;    &lt;span class="n"&gt;CAN&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;    &lt;span class="n"&gt;GBR&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;    &lt;span class="n"&gt;GBR&lt;/span&gt;
&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;country&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt;

&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;code_for_name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cache_info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;CacheInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;misses&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;maxsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;currsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And we can even update the data, discarding &lt;a class="footnote-reference" href="#footnote-6" id="footnote-reference-6"&gt;[6]&lt;/a&gt; the full names:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;country&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;country&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code_for_name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; 
  &lt;span class="n"&gt;country&lt;/span&gt;  &lt;span class="n"&gt;year&lt;/span&gt;  &lt;span class="n"&gt;value&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt;     &lt;span class="n"&gt;AUT&lt;/span&gt;  &lt;span class="mi"&gt;2021&lt;/span&gt;    &lt;span class="mf"&gt;1.1&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;     &lt;span class="n"&gt;BIH&lt;/span&gt;  &lt;span class="mi"&gt;2021&lt;/span&gt;    &lt;span class="mf"&gt;2.2&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;     &lt;span class="n"&gt;CAN&lt;/span&gt;  &lt;span class="mi"&gt;2021&lt;/span&gt;    &lt;span class="mf"&gt;3.3&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;     &lt;span class="n"&gt;GBR&lt;/span&gt;  &lt;span class="mi"&gt;2021&lt;/span&gt;    &lt;span class="mf"&gt;4.4&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;     &lt;span class="n"&gt;GBR&lt;/span&gt;  &lt;span class="mi"&gt;2022&lt;/span&gt;    &lt;span class="mf"&gt;5.5&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="section" id="concluding-thoughts"&gt;
&lt;h3&gt;Concluding thoughts&lt;/h3&gt;
&lt;p&gt;The three points of advice here:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Find and use well-tested tools.&lt;/li&gt;
&lt;li&gt;Understand the standard library.&lt;/li&gt;
&lt;li&gt;Find and use optimized code.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;…fit two themes.&lt;/p&gt;
&lt;p&gt;One is that &lt;strong&gt;time spent developing fluency with basic tasks pays dividends&lt;/strong&gt;.
For instance, we practice taking derivatives and performing integrals over and over, so that we can do them automatically and combine steps in the course of tackling more complex mathematical problems.
Writing code for research is no different: we want to minimize the space and attention taken up by routine tasks, so that the real content—the methods and theory we are trying to implement—stands out prominently.&lt;/p&gt;
&lt;p&gt;The second is that &lt;strong&gt;we follow paths blazed and walked by others&lt;/strong&gt;.
While our codes may investigate a new question in a novel way, the elemental building blocks of that code are shared with many others.
Almost always, someone has put in work to create an elegant and performant way to do these atomic tasks.
We ought to discover, understand, and use the tools they provide us.&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;p&gt;&lt;strong&gt;Footnotes&lt;/strong&gt;&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="footnote-1" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-1"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Trade data, for instance, can have two country dimensions: origin and destination.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="footnote-2" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-2"&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p class="first"&gt;These are sometimes called “ISO codes.”
&lt;strong&gt;Do not&lt;/strong&gt; do this.&lt;/p&gt;
&lt;p&gt;The ISO publishes (and &lt;tt class="docutils literal"&gt;pycountry&lt;/tt&gt; supports) standard code lists for languages, currencies, and many other concepts.
As soon as your software needs to handle data with both country and ≥1 of these other concepts—for instance, measures of economic activity denoted in local currency—the dimension label “ISO code” becomes ambiguous.&lt;/p&gt;
&lt;p&gt;Label dimensions with the &lt;em&gt;concept represented&lt;/em&gt;, not the &lt;em&gt;kind of representation&lt;/em&gt;.&lt;/p&gt;
&lt;p class="last"&gt;As well, &lt;strong&gt;do not&lt;/strong&gt; invent new codes.&lt;/p&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="footnote-3" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-3"&gt;[3]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="https://docs.python.org/3/library/functools.html#functools.cache"&gt;cache()&lt;/a&gt; is also available from Python 3.9.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="footnote-4" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-4"&gt;[4]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;The code examples in this post are all fairly fast to begin with, so the gain from using &lt;tt class="docutils literal"&gt;lru_cache()&lt;/tt&gt; is not very large.
However, this is a good pattern to learn and apply when the repeated function (here &lt;tt class="docutils literal"&gt;country_code&lt;/tt&gt;) has some slow steps, or the data is big.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="footnote-5" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-5"&gt;[5]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;There have been &lt;a class="reference external" href="https://github.com/pandas-dev/pandas"&gt;over 25,000 commits&lt;/a&gt; modifying the &lt;tt class="docutils literal"&gt;pandas&lt;/tt&gt; code!&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="footnote-6" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-6"&gt;[6]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;p class="first"&gt;Exercise: with what we've covered here, write a simple function that restores ‘country’ to the ‘name’ field of each record.&lt;/p&gt;
&lt;p class="last"&gt;Again following the principle of parsimony, it is better to keep only the short, ISO 3166 alpha codes in ‘internal’ data throughout most of a program.
Restore the ‘country’ dimension to the full name(s) only if and when necessary, e.g. to make output more intelligible to a user.&lt;/p&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="article"/><category term="pandas"/><category term="python"/><category term="research"/><category term="software"/></entry></feed>