Skip to content

Commit af74654

Browse files
authored
Merge pull request #14 from com-480-data-visualization/jo
Added data scripts and removed test script
2 parents 3154411 + d562fb9 commit af74654

3 files changed

Lines changed: 129 additions & 39 deletions

File tree

data/data_date_nat.py

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import pandas as pd
2+
import re
3+
4+
international_bestsellers = pd.read_csv("datasets/international_bestsellers.csv")
5+
international_bestsellers = international_bestsellers.drop_duplicates(subset=["title"])
6+
7+
all_countries = pd.read_csv("datasets/all.csv")
8+
population = pd.read_csv("datasets/population.csv")
9+
all_countries = all_countries.merge(population, left_on="alpha-3", right_on="Country Code")
10+
11+
year_cols = [str(y) for y in range(1960, 2025)]
12+
all_countries = all_countries[["name", "country-code", "alpha-2"] + year_cols]
13+
14+
# Melt population into long format: one row per (country, year)
15+
pop_long = all_countries.melt(
16+
id_vars=["name", "country-code", "alpha-2"],
17+
value_vars=year_cols,
18+
var_name="year",
19+
value_name="population"
20+
)
21+
pop_long["year"] = pop_long["year"].astype(int)
22+
pop_long["population"] = pd.to_numeric(pop_long["population"], errors="coerce")
23+
24+
aliases = {
25+
"Vietnam": "Viet Nam",
26+
"Turkey": "Türkiye",
27+
"South Korea": "Korea, Republic of",
28+
"Morroco": "Morocco",
29+
"Ivory Coast": "Côte d'Ivoire",
30+
"Czech Republic": "Czechia",
31+
"Scotland": "United Kingdom of Great Britain and Northern Ireland",
32+
"Algiers": "Algeria",
33+
"Taiwan": "Taiwan, Province of China"
34+
}
35+
36+
def find_match(nationality, country_names):
37+
nationality_lower = nationality.lower().strip()
38+
for name in country_names:
39+
if nationality_lower in name.lower() or name.lower() in nationality_lower:
40+
return name
41+
if nationality.strip() in aliases:
42+
return aliases[nationality.strip()]
43+
return None
44+
45+
nationalities = international_bestsellers[["author", "nationality", "date"]].copy()
46+
nationalities["nationality"] = (
47+
nationalities["nationality"]
48+
.apply(lambda n: re.findall(r"[\w'\s]+", str(n)))
49+
)
50+
nationalities = nationalities.explode("nationality")
51+
nationalities["nationality"] = nationalities["nationality"].str.strip()
52+
nationalities = nationalities[nationalities["nationality"].str.len() > 0]
53+
nationalities["year"] = pd.to_datetime(nationalities["date"], errors="coerce").dt.year
54+
55+
grouped = (
56+
nationalities
57+
.groupby(["nationality", "year"])
58+
.size()
59+
.reset_index(name="counts")
60+
)
61+
62+
all_names = all_countries["name"].tolist()
63+
grouped["matched_name"] = grouped["nationality"].apply(
64+
lambda n: find_match(n, all_names)
65+
)
66+
67+
# Merge country metadata (without population columns — those are in pop_long)
68+
country_meta = all_countries[["name", "country-code", "alpha-2"]].copy()
69+
merged = pd.merge(
70+
grouped,
71+
country_meta,
72+
left_on="matched_name",
73+
right_on="name",
74+
how="left"
75+
)
76+
merged = merged.rename(columns={"country-code": "ID", "alpha-2":"alpha2"})
77+
78+
merged_agg = (
79+
merged
80+
.groupby(["ID", "alpha2", "year"], dropna=False)
81+
.agg(
82+
nationality=("nationality", "first"),
83+
counts=("counts", "sum"),
84+
)
85+
.reset_index()
86+
)
87+
88+
merged_agg = merged_agg[merged_agg["ID"].notna()]
89+
merged_agg["ID"] = merged_agg["ID"].astype(int)
90+
91+
# Join population for the matching (country, year)
92+
merged_agg = pd.merge(
93+
merged_agg,
94+
pop_long[["country-code", "year", "population"]],
95+
left_on=["ID", "year"],
96+
right_on=["country-code", "year"],
97+
how="left"
98+
)
99+
100+
# Scale: books per million inhabitants
101+
merged_agg["counts_raw"] = merged_agg["counts"]
102+
merged_agg["counts"] = (
103+
merged_agg["counts"] / merged_agg["population"] * 1_000_000
104+
).round(4)
105+
106+
# Warn about missing population data
107+
missing_pop = merged_agg[merged_agg["population"].isna()]
108+
if not missing_pop.empty:
109+
print("Missing population data for:")
110+
print(missing_pop[["nationality", "year"]].drop_duplicates().to_string())
111+
112+
merged_agg = merged_agg.drop(columns=["country-code", "population"])
113+
merged_agg.to_csv("datasets/nat_date.csv", index=False)
114+
115+
print("Unmatched nationalities:")
116+
print(grouped[grouped["matched_name"].isna()]["nationality"].unique())

data/data_nationality.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,17 @@
66
all_countries = pd.read_csv("datasets/all.csv")
77
all_countries = all_countries[["name", "country-code"]]
88

9-
nationalities = international_bestsellers[["author", "nationality"]]
10-
aliases = {"Vietnam": "Viet Nam", "Turkey": "Türkiye", "South Korea":"Korea, Republic of", "Morroco": "Morocco", "Ivory Coast": "Côte d'Ivoire", "Czech Republic":"Czechia", "Scotland": "United Kingdom of Great Britain and Northern Ireland"}
9+
nationalities = international_bestsellers[["author", "nationality"]]
10+
aliases = {
11+
"Vietnam": "Viet Nam",
12+
"Turkey": "Türkiye",
13+
"South Korea": "Korea, Republic of",
14+
"Morroco": "Morocco",
15+
"Ivory Coast": "Côte d'Ivoire",
16+
"Czech Republic": "Czechia",
17+
"Scotland": "United Kingdom of Great Britain and Northern Ireland",
18+
"Algiers": "Algeria"
19+
}
1120

1221

1322
def find_match(nationality, country_names):
@@ -36,9 +45,9 @@ def find_match(nationality, country_names):
3645

3746
def exceptions(series):
3847
if series.iloc[0] == "Scotland":
39-
print("found")
4048
return "United Kingdom"
4149
return series.iloc[0]
50+
4251
merged_agg = (merged
4352
.groupby("ID", dropna=False)
4453
.agg(
@@ -50,4 +59,4 @@ def exceptions(series):
5059
merged_agg["ID"] = merged_agg["ID"].dropna()
5160
merged_agg = merged_agg[merged_agg["ID"].notna()]
5261
merged_agg["ID"] = merged_agg["ID"].astype(int)
53-
merged_agg.to_csv("datasets/nationalities.csv", index=False)
62+
merged_agg.to_csv("datasets/nationalities.csv", index=False)

data/test_genres.py

Lines changed: 0 additions & 35 deletions
This file was deleted.

0 commit comments

Comments
 (0)