Fewer users, more coursework: how people in African countries use AI¶
Exposure versus actual use, with data from Microsoft and Anthropic
Emmanuel Edudzie, October 2026. Analysis code written with substantial help from Claude (Anthropic), under the author's direction.
The question. The first piece in this series found that few young workers in Ghana, Nigeria, Kenya, Egypt and South Africa hold jobs that generative AI could change. This piece asks the next question: how many people in African countries actually use AI, and what for?
Two sources, two questions.
- How many people use AI? Microsoft's AI Diffusion data estimate the share of 15–64-year-olds who used any generative AI product in a period, by country.
- What do they use it for? Anthropic's Economic Index publishes, by country, what people use Claude for. It is the only open dataset with that detail; it covers one product only.
Data sources¶
| File | What it is |
|---|---|
AI_Diffusion_Q22026_Update.csv |
Microsoft AI Diffusion data, H1 2025 to Q2 2026, 147 economies |
Microsoft-AI-Diffusion-Report-2026-Q2.pdf |
The Q2 2026 report, source of the World, Global North and Global South figures. Not needed to run the notebook; it is in the reports/ folder of github.com/microsoft/ai-diffusion-report |
aei_2026-06-26_country_extract.csv |
Anthropic Economic Index, release of 26 June 2026 (April and May 2026), cut down to country and global rows |
The Anthropic extract was made from aei_claude_ai_2026-06-26.csv (219 MB) by keeping the
overall rows for every country and the global total, plus occupation (SOC major group),
request (top level) and O*NET work-activity rows for African countries, ten comparison
countries and the global total. The script that made it is in code/00_extract_aei.py.
0. Set-up¶
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import pycountry
from scipy.stats import spearmanr
from decimal import Decimal, ROUND_HALF_UP
ROOT = Path.cwd()
RAW, CLEAN, FIG = ROOT / "data" / "raw", ROOT / "data" / "clean", ROOT / "outputs" / "figures"
for folder in (CLEAN, FIG):
folder.mkdir(parents=True, exist_ok=True)
pd.set_option("display.width", 160)
SURFACE, INK, INK_2, GRID = "#fcfcfb", "#0b0b0b", "#52514e", "#e4e3df"
BLUE, GREY, REFERENCE = "#2a78d6", "#c3c2b7", "#8a8984"
plt.rcParams.update({
"figure.facecolor": SURFACE, "axes.facecolor": SURFACE, "savefig.facecolor": SURFACE,
"axes.edgecolor": GRID, "axes.labelcolor": INK_2, "xtick.color": INK_2, "ytick.color": INK,
"text.color": INK, "font.size": 10, "axes.spines.top": False, "axes.spines.right": False,
})
def frame(fig, title, subtitle, source):
"""Title and subtitle at the top left, source line at the bottom left."""
fig.text(0.01, 0.985, title, fontsize=12, fontweight="bold", color=INK, va="top")
fig.text(0.01, 0.925, subtitle, fontsize=9.5, color=INK_2, va="top")
fig.text(0.01, 0.01, source, fontsize=7.5, color=INK_2, va="bottom")
def half_up(x, places=2):
"""Round halves up (0.335 -> 0.34). Python's round() can go either way on averaged values."""
return float(Decimal(str(round(float(x), 6))).quantize(Decimal(1).scaleb(-places), rounding=ROUND_HALF_UP))
FOCUS = {"GHA": "Ghana", "NGA": "Nigeria", "KEN": "Kenya", "EGY": "Egypt", "ZAF": "South Africa"}
AFRICA = ["DZA", "AGO", "BEN", "BWA", "BFA", "BDI", "CPV", "CMR", "CAF", "TCD", "COM", "COD", "COG", "CIV",
"DJI", "EGY", "GNQ", "ERI", "SWZ", "ETH", "GAB", "GMB", "GHA", "GIN", "GNB", "KEN", "LSO", "LBR",
"LBY", "MDG", "MWI", "MLI", "MRT", "MUS", "MAR", "MOZ", "NAM", "NER", "NGA", "RWA", "STP", "SEN",
"SYC", "SLE", "SOM", "ZAF", "SSD", "SDN", "TZA", "TGO", "TUN", "UGA", "ZMB", "ZWE"]
1. How many people use AI? (Microsoft)¶
Microsoft's measure is the share of 15–64-year-olds who used a generative AI product during the period, estimated from anonymised Microsoft telemetry and adjusted for device market share, internet use and population (Misra et al., 2025). The report does not list which products are counted.
1a. Load and match country names to ISO codes¶
ms = pd.read_csv(RAW / "AI_Diffusion_Q22026_Update.csv", encoding="mac_roman") # the file uses Mac Roman encoding
for col in ms.columns[1:]:
ms[col] = ms[col].str.rstrip("%").astype(float)
ms.columns = ["economy", "h1_2025", "h2_2025", "q1_2026", "q2_2026"]
NAME_FIXES = {"Cote D'Ivoire": "CIV", "Democratic Republic Of The Congo": "COD", "Congo (DRC)": "COD", "Congo": "COG",
"South Korea": "KOR", "Russia": "RUS", "Turkey": "TUR", "Türkiye": "TUR", "Vietnam": "VNM", "Iran": "IRN",
"Laos": "LAO", "Bolivia": "BOL", "Venezuela": "VEN", "Tanzania": "TZA", "Moldova": "MDA",
"Syria": "SYR", "Palestine": "PSE", "Taiwan": "TWN", "Czech Republic": "CZE", "Eswatini": "SWZ",
"Cape Verde": "CPV", "Kosovo": "XKX", "Micronesia": "FSM", "Brunei": "BRN"}
def to_iso3(name):
if name in NAME_FIXES:
return NAME_FIXES[name]
try:
return pycountry.countries.lookup(name).alpha_3
except LookupError:
try:
return pycountry.countries.search_fuzzy(name)[0].alpha_3
except LookupError:
return None
ms["iso3"] = ms["economy"].map(to_iso3)
print("Unmatched:", ms.loc[ms["iso3"].isna(), "economy"].tolist())
ms_africa = ms[ms["iso3"].isin(AFRICA)].sort_values("q2_2026", ascending=False)
print(len(ms), "economies;", len(ms_africa), "in Africa")
ms_africa[["economy", "q1_2026", "q2_2026"]].head(12)
Unmatched: [] 147 economies; 46 in Africa
| economy | q1_2026 | q2_2026 | |
|---|---|---|---|
| 45 | South Africa | 23.1 | 23.9 |
| 72 | Gabon | 15.0 | 15.7 |
| 74 | Egypt | 14.8 | 15.5 |
| 71 | Libya | 15.0 | 15.5 |
| 70 | Namibia | 15.1 | 15.4 |
| 73 | Botswana | 14.8 | 15.0 |
| 78 | Senegal | 13.9 | 14.4 |
| 79 | Tunisia | 13.5 | 13.9 |
| 80 | Algeria | 13.2 | 13.8 |
| 82 | Cote D'Ivoire | 13.1 | 13.7 |
| 81 | Zambia | 13.1 | 13.3 |
| 89 | Morocco | 11.7 | 12.0 |
1b. A caveat: many African values look like regional estimates¶
Several groups of neighbouring countries share exactly the same value, which suggests they are estimated for a region rather than measured country by country. We count those groups.
clusters = ms_africa.groupby("q2_2026")["economy"].agg(list)
clusters = clusters[clusters.str.len() >= 3]
for value, names in clusters.items():
print(f"{value:.1f}%: {len(names)} economies, e.g. {', '.join(names[:6])}")
8.0%: 8 economies, e.g. Burundi, Eritrea, Ethiopia, Somalia, South Sudan, Sudan 9.1%: 5 economies, e.g. Cameroon, Central African Republic, Chad, Congo, Congo (DRC) 10.4%: 12 economies, e.g. Benin, Burkina Faso, Ghana, Guinea, Guinea-Bissau, Liberia 11.4%: 4 economies, e.g. Angola, Madagascar, Malawi, Mozambique
The report's own regional figures for Q2 2026 (from the report text, page 5): World 18.8%, Global North 28.8%, Global South 16.2%.
REGIONS = {"World": 18.8, "Global South": 16.2, "Global North": 28.8}
fig1_rows = (ms_africa[ms_africa["iso3"].isin(FOCUS)][["iso3", "economy", "q2_2026"]]
.rename(columns={"economy": "label", "q2_2026": "value"}).sort_values("value"))
fig1_rows
| iso3 | label | value | |
|---|---|---|---|
| 118 | KEN | Kenya | 8.9 |
| 109 | NGA | Nigeria | 10.4 |
| 102 | GHA | Ghana | 10.4 |
| 74 | EGY | Egypt | 15.5 |
| 45 | ZAF | South Africa | 23.9 |
fig, ax = plt.subplots(figsize=(8, 3.7))
fig.subplots_adjust(left=0.22, right=0.97, top=0.79, bottom=0.15)
accent = {"GHA", "NGA", "KEN"} # the countries the title is about
colours = [BLUE if i in accent else GREY for i in fig1_rows["iso3"]]
ax.barh(fig1_rows["label"], fig1_rows["value"], color=colours, height=0.65)
for y, v in enumerate(fig1_rows["value"]): # values beside the names, clear of the reference lines
ax.text(-0.5, y, f"{v:.1f}%", va="center", ha="right", fontsize=9.5, fontweight="bold", color=INK)
label_at = {"World": ("top", "left"), "Global South": ("bottom", "right"), "Global North": ("bottom", "right")}
for name, v in REGIONS.items():
ax.axvline(v, color=REFERENCE, linestyle=(0, (3, 2)), linewidth=1.3, ymin=0.0, ymax=1.0)
where, side = label_at[name]
ax.text(v + (0.3 if side == "left" else -0.3), 4.65 if where == "top" else -0.75, f"{name} {v:.1f}%",
ha=side, va="center", fontsize=8.5, color=INK_2)
ax.set_xlim(0, 31)
ax.set_ylim(-1.0, 4.9)
ax.set_xticks([])
ax.spines[["bottom", "left"]].set_visible(False)
ax.tick_params(axis="y", length=0, pad=48, labelsize=10)
frame(fig, "About 1 in 10 working-age adults uses generative AI in Ghana, Nigeria and Kenya",
"Share of people aged 15–64 who used a generative AI product, Q2 2026 (%)",
"Source: Microsoft AI Diffusion data, Q2 2026 update; World, Global North and Global South from the Q2 2026 report.\n"
"Ghana and Nigeria share the same value, as do ten other West African countries, which suggests a regional estimate.")
fig.savefig(FIG / "adoption_microsoft.png", dpi=200)
plt.show()
2. What do people use it for? (Anthropic Economic Index)¶
The Economic Index classifies a privacy-preserving sample of Claude conversations. The June 2026 release covers April and May 2026. For each country it publishes, among other things:
usage_per_capita_index: the country's share of Claude use divided by its share of the world's working-age population (1 = in proportion to population);use_case_work_pct,use_case_personal_pct,use_case_coursework_pct: what the conversation is for;collaboration_*_pct: how people work with Claude. Directive means handing over a task to be done; learning means using Claude to understand something;- request categories, such as Education & Learning.
A cell is published only if it has enough conversations, so smaller countries may be missing.
2a. Load and average the two months¶
aei = pd.read_csv(RAW / "aei_2026-06-26_country_extract.csv")
overall = aei[(aei["category_name"] == "overall") & aei["geo_level"].isin(["country", "global"])]
# Average April and May 2026 where both months are published; otherwise use the one available
by_geo = overall.groupby(["geo_id", "metric_id"])["value"].mean().unstack()
months = overall.groupby("geo_id")["date_start"].nunique()
countries = by_geo.drop(index="GLOBAL")
glob = by_geo.loc["GLOBAL"]
africa = countries.loc[countries.index.isin(AFRICA)].copy()
africa["name"] = [pycountry.countries.get(alpha_3=i).name for i in africa.index]
africa["name"] = africa["name"].replace({"Tanzania, United Republic of": "Tanzania", "Congo": "Congo (Rep.)",
"Côte d'Ivoire": "Côte d'Ivoire"})
print(len(countries), "countries published;", len(africa), "in Africa;",
"African countries with one month only:", sorted(months[months < 2].index.intersection(africa.index)))
121 countries published; 26 in Africa; African countries with one month only: ['BWA', 'COG', 'MOZ', 'NAM', 'TGO']
2b. How much Claude is used, relative to population¶
use = africa[["name", "usage_per_capita_index"]].sort_values("usage_per_capita_index")
print("African countries below the world average (index < 1):", (use["usage_per_capita_index"] < 1).sum(), "of", len(use))
use.assign(usage_per_capita_index=use["usage_per_capita_index"].map(half_up))
African countries below the world average (index < 1): 24 of 26
| metric_id | name | usage_per_capita_index |
|---|---|---|
| geo_id | ||
| TZA | Tanzania | 0.06 |
| MOZ | Mozambique | 0.08 |
| AGO | Angola | 0.09 |
| MDG | Madagascar | 0.10 |
| UGA | Uganda | 0.11 |
| BFA | Burkina Faso | 0.14 |
| ZMB | Zambia | 0.15 |
| RWA | Rwanda | 0.19 |
| ZWE | Zimbabwe | 0.20 |
| TGO | Togo | 0.22 |
| NGA | Nigeria | 0.23 |
| COG | Congo (Rep.) | 0.24 |
| CIV | Côte d'Ivoire | 0.29 |
| EGY | Egypt | 0.34 |
| CMR | Cameroon | 0.34 |
| KEN | Kenya | 0.34 |
| BEN | Benin | 0.37 |
| GHA | Ghana | 0.39 |
| SEN | Senegal | 0.40 |
| NAM | Namibia | 0.44 |
| ZAF | South Africa | 0.45 |
| DZA | Algeria | 0.48 |
| BWA | Botswana | 0.52 |
| MAR | Morocco | 0.88 |
| TUN | Tunisia | 1.32 |
| MUS | Mauritius | 1.62 |
fig, ax = plt.subplots(figsize=(8, 7.0))
fig.subplots_adjust(left=0.2, right=0.95, top=0.89, bottom=0.06)
colours = [BLUE if i in FOCUS else GREY for i in use.index]
bars = ax.barh(use["name"], use["usage_per_capita_index"], color=colours, height=0.7)
for bar, v in zip(bars, use["usage_per_capita_index"]):
ax.text(v + 0.02, bar.get_y() + bar.get_height() / 2, f"{half_up(v):.2f}", va="center", fontsize=8, color=INK)
ax.axvline(1, color=REFERENCE, linestyle=(0, (3, 2)), linewidth=1.5)
ax.text(1.03, 0.5, "World average = 1", fontsize=8.5, color=INK_2, va="center")
ax.set_xticks([])
ax.spines[["bottom", "left"]].set_visible(False)
ax.tick_params(axis="y", length=0, labelsize=8.5)
frame(fig, "Claude use per working-age person is below the world average in 24 of 26 African countries",
"Anthropic usage per capita index, April–May 2026 (share of use ÷ share of working-age population). Focus countries in blue",
"Source: Anthropic Economic Index, release of 26 June 2026. Countries with too few conversations are not published.")
fig.savefig(FIG / "claude_usage_index_africa.png", dpi=200)
plt.show()
2c. Does Claude use track wider AI adoption?¶
If countries that use Claude more also show higher AI adoption in Microsoft's data, the Claude figures are a reasonable guide to wider patterns, not just to one product's market share.
match = ms.set_index("iso3")[["q2_2026"]].join(countries[["usage_per_capita_index"]], how="inner").dropna()
rho, p = spearmanr(match["q2_2026"], match["usage_per_capita_index"])
print(f"{len(match)} countries in both datasets; Spearman rank correlation = {rho:.2f} (p = {p:.1e})")
109 countries in both datasets; Spearman rank correlation = 0.86 (p = 9.3e-34)
2d. What it is used for, and how¶
Across all 121 countries, we compare each measure with how intensively the country uses Claude. The Spearman rank correlation asks whether countries that use Claude less tend to have a higher (negative correlation) or lower (positive) value of the measure.
MEASURES = {"use_case_coursework_pct": "Coursework", "use_case_personal_pct": "Personal",
"use_case_work_pct": "Work", "collaboration_directive_pct": "Directive (hand over the task)",
"collaboration_learning_pct": "Learning (understand something)"}
log_use = np.log(countries["usage_per_capita_index"])
rows = []
for col, label in MEASURES.items():
ok = log_use.notna() & countries[col].notna()
r, pv = spearmanr(log_use[ok], countries.loc[ok, col])
rows.append({"measure": label, "global %": half_up(glob[col], 1), "Africa median %": half_up(africa[col].median(), 1),
"rho with usage": round(r, 2), "p": f"{pv:.0e}", "n": int(ok.sum())})
correlations = pd.DataFrame(rows)
correlations.to_csv(CLEAN / "use_measures_vs_usage.csv", index=False)
correlations
| measure | global % | Africa median % | rho with usage | p | n | |
|---|---|---|---|---|---|---|
| 0 | Coursework | 16.2 | 32.1 | -0.66 | 9e-17 | 121 |
| 1 | Personal | 39.3 | 29.2 | 0.63 | 9e-15 | 121 |
| 2 | Work | 44.4 | 39.7 | 0.21 | 2e-02 | 121 |
| 3 | Directive (hand over the task) | 31.6 | 39.0 | -0.74 | 2e-22 | 121 |
| 4 | Learning (understand something) | 16.7 | 14.7 | 0.47 | 5e-08 | 121 |
Reading this. In countries that use Claude less, a much larger share of use is coursework, a larger share is directive, and a smaller share is learning. These are country-level patterns: the data do not show how coursework conversations themselves are conducted.
is_af = countries.index.isin(AFRICA)
fig, ax = plt.subplots(figsize=(8, 5.4))
fig.subplots_adjust(left=0.08, right=0.97, top=0.8, bottom=0.14)
ax.scatter(countries.loc[~is_af, "usage_per_capita_index"], countries.loc[~is_af, "use_case_coursework_pct"],
s=28, color=GREY, label="Other countries", edgecolor=SURFACE, linewidth=0.6)
ax.scatter(countries.loc[is_af, "usage_per_capita_index"], countries.loc[is_af, "use_case_coursework_pct"],
s=34, color=BLUE, label="African countries", edgecolor=SURFACE, linewidth=0.6)
ax.scatter([1], [glob["use_case_coursework_pct"]], s=60, marker="D", color=INK, label="World")
focus_pts = countries.loc[list(FOCUS), ["usage_per_capita_index", "use_case_coursework_pct"]]
ax.scatter(focus_pts.iloc[:, 0], focus_pts.iloc[:, 1], s=46, color=BLUE, edgecolor=INK, linewidth=1.1, zorder=3)
offsets = {"GHA": (-48, 30), "NGA": (6, -10), "KEN": (6, -2), "EGY": (6, 2), "ZAF": (6, -8)}
for iso, name in FOCUS.items():
x0, y0 = focus_pts.loc[iso]
line = dict(arrowstyle="-", color=INK_2, linewidth=0.7, shrinkA=0, shrinkB=4) if iso == "GHA" else None
ax.annotate(name, (x0, y0), xytext=offsets[iso], textcoords="offset points", fontsize=8.5, color=INK,
fontweight="bold", arrowprops=line)
ax.set_xscale("log")
ax.set_xticks([0.05, 0.1, 0.25, 0.5, 1, 2, 4], ["0.05", "0.1", "0.25", "0.5", "1", "2", "4"])
ax.set_xlabel("Claude usage per capita index (log scale; world average = 1)")
ax.set_ylabel("Coursework share of conversations (%)")
ax.grid(color=GRID, linewidth=0.8)
ax.set_axisbelow(True)
ax.legend(frameon=False, loc="lower left", bbox_to_anchor=(0.0, 1.0), ncol=3, fontsize=8.5)
rho_c = correlations.set_index("measure").loc["Coursework", "rho with usage"]
frame(fig, "Where Claude is used less, coursework takes a bigger share of its use",
f"Each dot is a country, April–May 2026 (121 countries; Spearman rank correlation {rho_c:.2f}). Focus countries outlined",
"Source: Anthropic Economic Index, release of 26 June 2026.")
fig.savefig(FIG / "coursework_vs_usage.png", dpi=200)
plt.show()
2e. The focus countries side by side¶
SHOW = {"use_case_coursework_pct": "Coursework", "collaboration_directive_pct": "Directive: hand over the task",
"collaboration_learning_pct": "Learning: understand something"}
table = africa.loc[list(FOCUS), list(SHOW)].copy()
table.index = [FOCUS[i] for i in table.index]
table.loc["Africa (median of 26)"] = africa[list(SHOW)].median()
table.loc["World"] = glob[list(SHOW)]
table_raw = table.copy() # unrounded, for whole-number chart labels
table = table.apply(lambda col: col.map(lambda v: half_up(v, 1)))
table.to_csv(CLEAN / "focus_country_use.csv")
table
| metric_id | use_case_coursework_pct | collaboration_directive_pct | collaboration_learning_pct |
|---|---|---|---|
| Ghana | 35.8 | 41.9 | 16.5 |
| Nigeria | 17.5 | 36.1 | 12.6 |
| Kenya | 21.1 | 39.2 | 12.3 |
| Egypt | 25.8 | 32.2 | 17.5 |
| South Africa | 23.8 | 36.0 | 14.8 |
| Africa (median of 26) | 32.1 | 39.0 | 14.7 |
| World | 16.2 | 31.6 | 16.7 |
LABELS = {"use_case_coursework_pct": "Coursework", "collaboration_directive_pct": "Directive (hand over the task)",
"collaboration_learning_pct": "Learning (understand)"}
fig, axes = plt.subplots(1, 3, figsize=(8, 3.9), sharey=True)
fig.subplots_adjust(left=0.2, right=0.98, top=0.77, bottom=0.1, wspace=0.12)
order = [FOCUS[i] for i in FOCUS][::-1] + ["Africa (median of 26)"] # bottom to top; world is drawn as a line
for ax, (col, label) in zip(axes, LABELS.items()):
vals, world = table_raw.loc[order, col], table_raw.loc["World", col] # round once, from the raw values
colours = [BLUE if n.startswith("Africa") else GREY for n in order]
ax.barh(order, vals, color=colours, height=0.62)
for y, v in enumerate(vals):
ax.text(max(v, world) + 1.2, y, f"{half_up(v, 0):.0f}", va="center", fontsize=8.5, color=INK)
ax.axvline(world, color=REFERENCE, linestyle=(0, (3, 2)), linewidth=1.2, ymin=0.11) # stops above its label
ax.text(world, -0.95, f"World {half_up(world, 0):.0f}", ha="center", va="center", fontsize=8.5, color=INK_2)
ax.set_title(label, fontsize=9, loc="left", color=INK, fontweight="bold")
ax.set_xlim(0, 50)
ax.set_ylim(-1.3, len(order) - 0.5)
ax.set_xticks([])
ax.spines[["bottom", "left"]].set_visible(False)
ax.tick_params(axis="y", length=0)
for lab in axes[0].get_yticklabels():
if lab.get_text().startswith("Africa"):
lab.set_fontweight("bold")
frame(fig, "More coursework, more handing over, a little less learning: how Claude is used",
"Share of Claude conversations, April–May 2026 (%). Dashed line = world",
"Source: Anthropic Economic Index, release of 26 June 2026. Africa = median of the 26 African countries with published data.")
fig.savefig(FIG / "how_claude_is_used.png", dpi=200)
plt.show()
2f. What people ask for: request categories¶
req = aei[(aei["category_name"] == "request") & (aei["metric_id"] == "pct")]
req = req.groupby(["geo_id", "node_name"])["value"].mean().unstack("geo_id")
req_focus = req[["GLOBAL"] + list(FOCUS)].rename(columns=FOCUS).sort_values("GLOBAL", ascending=False)
req_focus = req_focus.apply(lambda col: col.map(lambda v: half_up(v, 1) if pd.notna(v) else v))
req_focus.to_csv(CLEAN / "request_categories_focus.csv")
req_focus.head(8)
| geo_id | GLOBAL | Ghana | Nigeria | Kenya | Egypt | South Africa |
|---|---|---|---|---|---|---|
| node_name | ||||||
| Content Creation & Copywriting | 22.2 | 25.6 | 38.4 | 28.6 | 19.0 | 23.6 |
| Education & Learning | 12.9 | 28.9 | 14.8 | 16.8 | 19.2 | 19.4 |
| Software Development | 11.8 | 12.0 | 13.0 | 15.8 | 20.3 | 12.0 |
| Research & Intelligence | 10.7 | 6.1 | 6.6 | 7.1 | 7.6 | 8.4 |
| Hobbies & Lifestyle | 8.9 | 3.8 | 3.8 | 4.1 | 6.3 | 6.4 |
| Business Process & Operations | 4.6 | 1.7 | 2.4 | 3.5 | 2.6 | 5.1 |
| Document Processing & Extraction | 4.1 | 5.4 | 3.9 | 5.0 | 5.4 | 4.5 |
| Data Analysis & Business Intelligence | 3.7 | 2.5 | 2.2 | 3.5 | 3.4 | 3.5 |
edu_af = req.loc["Education & Learning", [c for c in req.columns if c in AFRICA]]
print(f"Education & Learning requests: world {req.loc['Education & Learning', 'GLOBAL']:.1f}%, "
f"Africa median {edu_af.median():.1f}% across {edu_af.notna().sum()} countries")
Education & Learning requests: world 12.9%, Africa median 23.3% across 26 countries
3. Summary numbers for the brief¶
summary = {
"World AI adoption Q2 2026 (%)": 18.8, "Global South (%)": 16.2,
**{f"{n} adoption Q2 2026 (%)": float(ms.set_index("iso3").loc[i, "q2_2026"]) for i, n in FOCUS.items()},
**{f"{n} Claude usage index": half_up(countries.loc[i, "usage_per_capita_index"]) for i, n in FOCUS.items()},
"African countries below world Claude usage": int((use["usage_per_capita_index"] < 1).sum()),
"African countries published": len(use),
"Coursework share: world (%)": half_up(glob["use_case_coursework_pct"], 1),
"Coursework share: Africa median (%)": half_up(africa["use_case_coursework_pct"].median(), 1),
"Directive share: world (%)": half_up(glob["collaboration_directive_pct"], 1),
"Directive share: Africa median (%)": half_up(africa["collaboration_directive_pct"].median(), 1),
"Learning share: world (%)": half_up(glob["collaboration_learning_pct"], 1),
"Learning share: Africa median (%)": half_up(africa["collaboration_learning_pct"].median(), 1),
"Education & Learning requests: world (%)": half_up(req.loc["Education & Learning", "GLOBAL"], 1),
"Education & Learning requests: Ghana (%)": half_up(req.loc["Education & Learning", "GHA"], 1),
"Education & Learning requests: Africa median (%)": half_up(edu_af.median(), 1),
"Content creation requests: Nigeria (%)": half_up(req.loc["Content Creation & Copywriting", "NGA"], 1),
"Content creation requests: world (%)": half_up(req.loc["Content Creation & Copywriting", "GLOBAL"], 1),
"Microsoft vs Claude rank correlation": round(rho, 2), "Countries in both": len(match),
}
summary = pd.Series(summary)
summary.to_csv(ROOT / "outputs" / "summary_numbers.csv", header=["value"])
summary
World AI adoption Q2 2026 (%) 18.80 Global South (%) 16.20 Ghana adoption Q2 2026 (%) 10.40 Nigeria adoption Q2 2026 (%) 10.40 Kenya adoption Q2 2026 (%) 8.90 Egypt adoption Q2 2026 (%) 15.50 South Africa adoption Q2 2026 (%) 23.90 Ghana Claude usage index 0.39 Nigeria Claude usage index 0.23 Kenya Claude usage index 0.34 Egypt Claude usage index 0.34 South Africa Claude usage index 0.45 African countries below world Claude usage 24.00 African countries published 26.00 Coursework share: world (%) 16.20 Coursework share: Africa median (%) 32.10 Directive share: world (%) 31.60 Directive share: Africa median (%) 39.00 Learning share: world (%) 16.70 Learning share: Africa median (%) 14.70 Education & Learning requests: world (%) 12.90 Education & Learning requests: Ghana (%) 28.90 Education & Learning requests: Africa median (%) 23.30 Content creation requests: Nigeria (%) 38.40 Content creation requests: world (%) 22.20 Microsoft vs Claude rank correlation 0.86 Countries in both 109.00 dtype: float64
4. Limitations¶
- One product for "what for". The Economic Index covers Claude only, which is a small share of AI use in most African countries. Microsoft's figures cover more products but do not say which.
- Regional estimates. Many African values in Microsoft's data are shared across neighbouring countries, so country differences there should not be over-read.
- Country-level patterns. The coursework, directive and learning shares are separate country-level measures; the data do not show how coursework conversations themselves go.
- Two months. The Anthropic data cover April and May 2026, so seasonal patterns (exam periods, for example) may matter.
- Published cells only. Countries with few conversations are not published, so the African picture covers 26 countries, mostly the larger and more connected ones.