apt install ghostscript
pip install camelot-py[cv]
pip install pandas
pip install requests
pip install beautifulsoup4
pip install japanmap
pip install tqdm
BAD Open Data Memorial Process
tables = camelot.read_pdf(
link, pages="all", split_text=True, strip_text=" ,%%\n", line_scale=40
)
Supprimez les caractères inutiles avec "strip_text =", %% \ n "" lors de l'extraction d'un tableau à partir d'un PDF
import csv
import datetime
import pathlib
import re
from urllib.parse import urljoin
import camelot
import pandas as pd
import requests
from bs4 import BeautifulSoup
from japanmap import pref_code
from tqdm.notebook import tqdm
#Passer du calendrier japonais au calendrier occidental
def wareki2date(s):
m = re.search("(H|R|Heisei|Reiwa)([0-9 yuans]{1,2})[.Année]([0-9]{1,2})[.Mois]([0-9]{1,2})journée?",s)
year, month, day = [1 if i == "Ancien" else int(i) for i in m.group(2, 3, 4)]
if m.group(1) in ["Heisei", "H"]:
year += 1988
elif m.group(1) in ["Reiwa", "R"]:
year += 2018
return datetime.date(year, month, day)
def df_conv(df, col_name, population_date, delivery_date, criteria_date):
df.set_axis(col_name, axis=1, inplace=True)
df["Date de base du calcul de la population"] = population_date
df["Date de base pour le calcul du nombre de livraisons"] = delivery_date
df.insert(0, "Date de base du calcul", criteria_date)
return df
url = "https://www.soumu.go.jp/kojinbango_card/"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
}
cjk = str.maketrans("Long noir 戶 long noir long", "Kamecho Kuroto Ryu Nishi Aoki")
df_code = pd.read_csv(
"https://docs.google.com/spreadsheets/d/e/2PACX-1vSseDxB5f3nS-YQ1NOkuFKZ7rTNfPLHqTKaSag-qaK25EWLcSL0klbFBZm1b6JDKGtHTk6iMUxsXpxt/pub?gid=0&single=true&output=csv",
dtype={"Code de groupe": int, "Nom des préfectures": str, "Nom du comté": str, "Nom de Ville": str},
)
df_code["Nom de Ville"] = df_code["Nom du comté"].fillna("") + df_code["Nom de Ville"]
df_code.drop("Nom du comté", axis=1, inplace=True)
r = requests.get(url, headers=headers)
r.raise_for_status()
soup = BeautifulSoup(r.content, "html.parser")
links = soup.select("ul.normal > li a[href$=pdf]")
for i in tqdm(links):
creation_date = wareki2date(i.find_parent("li").get_text(strip=True))
link = urljoin(url, i.get("href"))
#Créer le dossier
path_dir = pathlib.Path(creation_date.strftime("%Y%m%d"))
path_dir.mkdir(parents=True, exist_ok=True)
#Extraire le tableau du PDF
tables = camelot.read_pdf(
link, pages="all", split_text=True, strip_text=" ,%%\n", line_scale=40
)
#Par classification de groupe
df_tmp = tables[0].df
df_tmp.iat[0, 1] = "Classification"
df_tmp.iat[1, 1] = "À l'échelle nationale"
population_date = wareki2date(df_tmp.iat[0, 2]).strftime("%Y/%m/%d")
delivery_date = wareki2date(df_tmp.iat[0, 3]).strftime("%Y/%m/%d")
df0 = df_conv(
df_tmp.iloc[1:, 1:].reset_index(drop=True),
["Classification", "population", "Nombre de livraisons", "populationに対するNombre de livraisons率"],
population_date,
delivery_date,
creation_date.strftime("%Y/%m/%d"),
)
df0 = df0.astype({"population": int, "Nombre de livraisons": int, "populationに対するNombre de livraisons率": float})
df0.to_csv(
pathlib.Path(path_dir, "summary_by_types.csv"),
index=False,
quoting=csv.QUOTE_NONNUMERIC,
encoding="utf_8_sig",
)
#Liste des préfectures
dfs = []
for table in tables[3:5]:
df_tmp = table.df
population_date = wareki2date(df_tmp.iat[0, 1]).strftime("%Y/%m/%d")
#Ajustement de la date du statut d'émission de ma carte numérique (au 1er avril 2019)
if creation_date == datetime.date(2019, 4, 1):
delivery_date = wareki2date(
df_tmp.iat[0, 2].replace("H31.41", "H31.4.1")
).strftime("%Y/%m/%d")
else:
delivery_date = wareki2date(df_tmp.iat[0, 2]).strftime("%Y/%m/%d")
df = df_conv(
df_tmp.iloc[1:].reset_index(drop=True),
["Nom des préfectures", "Nombre total (population)", "Nombre de livraisons", "人口に対するNombre de livraisons率"],
population_date,
delivery_date,
creation_date.strftime("%Y/%m/%d"),
)
dfs.append(df)
df3 = pd.concat(dfs)
df3["Nom des préfectures"] = df3["Nom des préfectures"].str.normalize("NFKC")
df3["Nom des préfectures"] = df3["Nom des préfectures"].apply(lambda s: s.translate(cjk))
#Trier par numéro de préfecture
df3.index = df3["Nom des préfectures"].apply(lambda s: pref_code(s))
df3.sort_index(inplace=True)
df3 = df3.astype({"Nombre total (population)": int, "Nombre de livraisons": int, "人口に対するNombre de livraisons率": float})
df3.to_csv(
pathlib.Path(path_dir, "all_prefectures.csv"),
index=False,
quoting=csv.QUOTE_NONNUMERIC,
encoding="utf_8_sig",
)
df3
#Par sexe et âge
n = 5
if creation_date > datetime.date(2017, 3, 8):
n = 6
df_tmp = tables[5].df
population_date = wareki2date(df_tmp.iat[0, 1]).strftime("%Y/%m/%d")
delivery_date = wareki2date(df_tmp.iat[0, 4]).strftime("%Y/%m/%d")
df5 = df_conv(
df_tmp.iloc[2:].reset_index(drop=True),
[
"âge",
"population(Homme)",
"population(femme)",
"population(Total)",
"Nombre de livraisons(Homme)",
"Nombre de livraisons(femme)",
"Nombre de livraisons(Total)",
"Taux de subvention(Homme)",
"Taux de subvention(femme)",
"Taux de subvention(Total)",
"Ratio du nombre de subventions à l'ensemble(Homme)",
"Ratio du nombre de subventions à l'ensemble(femme)",
"Ratio du nombre de subventions à l'ensemble(Total)",
],
population_date,
delivery_date,
creation_date.strftime("%Y/%m/%d"),
)
df5 = df5.astype(
{
"population(Homme)": int,
"population(femme)": int,
"population(Total)": int,
"Nombre de livraisons(Homme)": int,
"Nombre de livraisons(femme)": int,
"Nombre de livraisons(Total)": int,
"Taux de subvention(Homme)": float,
"Taux de subvention(femme)": float,
"Taux de subvention(Total)": float,
"Ratio du nombre de subventions à l'ensemble(Homme)": float,
"Ratio du nombre de subventions à l'ensemble(femme)": float,
"Ratio du nombre de subventions à l'ensemble(Total)": float,
}
)
df5.to_csv(
pathlib.Path(path_dir, "demographics.csv"),
index=False,
quoting=csv.QUOTE_NONNUMERIC,
encoding="utf_8_sig",
)
df5
#Liste par ville
dfs = []
for table in tables[n:]:
df_tmp = table.df
population_date = wareki2date(df_tmp.iat[0, 2]).strftime("%Y/%m/%d")
delivery_date = wareki2date(df_tmp.iat[0, 3]).strftime("%Y/%m/%d")
df = df_conv(
df_tmp.iloc[1:].reset_index(drop=True),
["Nom des préfectures", "Nom de Ville", "Nombre total (population)", "Nombre de livraisons", "人口に対するNombre de livraisons率"],
population_date,
delivery_date,
creation_date.strftime("%Y/%m/%d"),
)
dfs.append(df)
df6 = pd.concat(dfs)
df6["Nom des préfectures"] = df6["Nom des préfectures"].str.normalize("NFKC")
df6["Nom des préfectures"] = df6["Nom des préfectures"].apply(lambda s: s.translate(cjk))
#Exclure à l'échelle nationale
df6 = df6[df6["Nom des préfectures"] != "À l'échelle nationale"].copy()
df6["Nom de Ville"] = df6["Nom de Ville"].str.normalize("NFKC")
df6["Nom de Ville"] = df6["Nom de Ville"].apply(lambda s: s.translate(cjk))
df6["Nom de Ville"] = df6["Nom de Ville"].mask(df6["Nom des préfectures"] + df6["Nom de Ville"] == "Ville de Shinoyama, préfecture de Hyogo", "Ville de Tamba Shinoyama")
df6["Nom de Ville"] = df6["Nom de Ville"].mask(
df6["Nom des préfectures"] + df6["Nom de Ville"] == "Ville de Kajiwara, comté de Takaoka, préfecture de Kochi", "Hibara-cho, Takaoka-gun"
)
df6["Nom de Ville"] = df6["Nom de Ville"].mask(
df6["Nom des préfectures"] + df6["Nom de Ville"] == "Ville de Sue, comté de Kasuya, préfecture de Fukuoka", "Sue-cho, Kasuya-gun"
)
if creation_date < datetime.date(2018, 10, 1):
df6["Nom de Ville"] = df6["Nom de Ville"].mask(
df6["Nom des préfectures"] + df6["Nom de Ville"] == "Ville de Nakagawa, préfecture de Fukuoka", "Nakagawa-cho, Chikushi-gun"
)
else:
df6["Nom de Ville"] = df6["Nom de Ville"].mask(
df6["Nom des préfectures"] + df6["Nom de Ville"] == "Ville de Nakagawa, comté de Chikushi, préfecture de Fukuoka", "Ville de Nakagawa"
)
df6 = pd.merge(df6, df_code, on=["Nom des préfectures", "Nom de Ville"], how="left")
df6 = df6.astype(
{"Nombre total (population)": int, "Nombre de livraisons": int, "人口に対するNombre de livraisons率": float, "Code de groupe": "Int64"}
)
df6.to_csv(
pathlib.Path(path_dir, "all_localgovs.csv"),
index=False,
quoting=csv.QUOTE_NONNUMERIC,
encoding="utf_8_sig",
)
Recommended Posts