Aller au contenu

Fusion

On voudrait créer une carte des communes de plus de 50000 habitants. Mais manque de bol : la localisation des communes se trouve dans la table localisation, alors que la population se trouve dans la table population. Et on ne sait pas faire de recherche dans deux tables en même temps.

Dans ce chapitre, on va voir construire une table contenant à la fois la population et la localisation des communes à partir des tables localisation et population.

Principe

Les tables localisation et population contiennent des colonnes qui représentent les mêmes informations dans les deux tables : code_insee , nom, et code_postal.

Chaque code insée est propre à une commune : il n'y a pas deux communes qui ont le même code insée. On dit que le code insée identifie une ligne dans les tables localisation et population.

L'idée est de créer une table communes, dans laquelle chaque ligne est une ligne de localisation mixée avec la ligne de population ayant le même code insée.

localisation:
code_insee,nom,code_postal,latitude,longitude

+

population:
code_insee,nom,code_postal,population

=

communes:
code_insee,nom,code_postal,population,latitude,longitude

Commençons par implémenter cette opération sur deux lignes.

Exercice 12

Implémentez la fonction suivante :

def fusion_ligne(ligne1, ligne2):
    """ligne1 et ligne2 des dictionnaires.
    retourne une copie de ligne1 où les paires clé:valeurs de ligne2 ne correspondant pas à une clé de ligne1 ont étés ajoutées.

    >>> fusion_ligne({"a":1, "b":2}, {"a":2, "c":3})
    {"a":1, "b":2, "c":3}
    """

N'oubliez pas de copier ligne1 !

Parcourez les clés de ligne2 et vérifiez si elles sont dans ligne 1 !

def fusion_ligne(ligne1, ligne2):
    """ligne1 et ligne2 des dictionnaires.
    retourne une copie de ligne1 où les paires clé:valeurs de ligne2 ne correspondant pas à une clé de ligne1 ont étés ajoutées.

    >>> fusion_ligne({"a":1, "b":2}, {"a":2, "c":3})
    {"a":1, "b":2, "c":3}
    """
    fusion = ligne1.copy()
    for c in ligne2:
        if not c in fusion:
            fusion[c] = ligne2[c]
    return fusion

Algorithme

On commence par trier les tables sur le code insee.

Ensuite, on va parcourir simultanément les deux tables. Dans notre cas, on sait que chaque code insée dans localisation correspond à un code insée dans population. A chaque code insée, on va constituer la ligne et l'ajouter à la table communes.

Voici l'algorithme :

soit localisation une table
soit population une table

soit communes une table vide

trier localisation sur code_insee
trier population sur code_insee

pour i allant de 0 à len(localisation) -1:
    ou ajoute fusion_ligne(localisation[i], population[i]) à communes

on retourne communes

Exercice 13

Implémentez la fonction fusion_insee, qui prends en paramètre les tables localisation et population et retourne la table commune en applicant l'algorithme décrit ci-dessus.

En executant le programme correspondant à l'exercice, vous devriez obtenir la sortie suivante :

| code_insee | nom                      | code_postal | latitude     | longitude   | population |
| ---------- | ------------------------ | ----------- | ------------ | ----------- | ---------- |
| 01001      | L' Abergement-Clémenciat | 01400       | 46.153721024 | 4.925850148 | 776        |
| 01002      | L' Abergement-de-Varey   | 01640       | 46.009605679 | 5.428087796 | 248        |
| 01004      | Ambérieu-en-Bugey        | 01500       | 45.961048852 | 5.372275427 | 14035      |
| 01005      | Ambérieux-en-Dombes      | 01330       | 45.99616357  | 4.911967138 | 1689       |
| 01006      | Ambléon                  | 01300       | 45.749886304 | 5.594584599 | 111        |
| 01007      | Ambronay                 | 01500       | 46.005690539 | 5.357748739 | 2726       |
| 01008      | Ambutrix                 | 01500       | 45.936683389 | 5.332446671 | 752        |
| 01009      | Andert-et-Condon         | 01300       | 45.787194157 | 5.657799976 | 330        |
| 01010      | Anglefort                | 01350       | 45.909091467 | 5.795056945 | 1115       |
| 01011      | Apremont                 | 01100       | 46.205877513 | 5.657980818 | 376        |

Traduisez en Python l'algorithme présenté ci-dessus

def fusion_insee(localisation, population):
    localisation.sort(key=lambda l:l["code_insee"])
    population.sort(key=lambda l:l["code_insee"])

    communes = []

    i = 0
    while i < len(localisation):
        ligne = fusion_ligne(localisation[i], population[i])
        communes.append(ligne)
        i = i + 1

    return communes

Exercice 14

Utilisez les fonction définies dans ce chapitre pour implémenter la fonction plus_de_50000, qui prends en paramètres les tables localisation et population et retourne une nouvelle table renseignant pour toutes les communes de 50000 habitants ou plus leurs noms, latitudes et longitudes.

def plus_de_50000(localisation, population):
    communes = fusion_insee(localisation, population)

    return [l for l in communes if int(l["population"]) >= 50000]