Skip to content

Commit 60518fd

Browse files
committed
clean process
1 parent 73043ee commit 60518fd

File tree

1 file changed

+47
-10
lines changed

1 file changed

+47
-10
lines changed

content/manipulation/05_parquet_s3.qmd

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,29 +1279,30 @@ with fs.open(FILE_PATH_OUT_S3, 'wb') as file_out:
12791279

12801280
Dans la partie précédente, on était dans le cas "simple" d'un dataframe, ce qui nous permettait d'utiliser directement les fonctions d'export de `Pandas`. Maintenant, imaginons qu'on ait plusieurs fichiers d'entrée, pouvant chacun avoir des formats différents. Un cas typique de tels fichiers sont les fichiers `ShapeFile`, qui sont des fichiers de données géographiques, et se présentent sous forme d'une combinaison de fichiers (cf. [chapitre sur GeoPandas](/content/manipulation/03_geopandas_intro.qmd#le-format-shapefile-.shp-et-le-geopackage-.gpkg)). Commençons par récupérer un fichier `.shp` pour voir sa structure.
12811281

1282-
On récupère ci-dessous les [contours des départements français](https://www.data.gouv.fr/fr/datasets/contours-des-departements-francais-issus-d-openstreetmap/), sous la forme d'une archive `.zip` qu'on va décompresser en local dans un dossier `departements_fr`.
1282+
On récupère ci-dessous les contours du département de la Réunion [produits par l'IGN](https://geoservices.ign.fr/telechargement-api/ADMIN-EXPRESS-COG-CARTO), sous la forme d'une archive `.7z` qu'on va décompresser en local dans un dossier `departements_fr`.
12831283
::::
12841284

12851285
:::: {.content-visible when-profile="en"}
12861286
#### File-based use case {-}
12871287

12881288
In the previous section, we dealt with the "simple" case of a DataFrame, which allowed us to use `Pandas`' built-in export functions. Now, let's imagine we have multiple input files, each potentially in a different format. A typical example of such files are `ShapeFile`s, which are geographic data files and are composed of several related files (see [GeoPandas chapter](/content/manipulation/03_geopandas_intro.qmd#le-format-shapefile-.shp-et-le-geopackage-.gpkg)). Let’s start by downloading a `.shp` file to inspect its structure.
12891289

1290-
Below, we retrieve the [boundaries of French departments](https://www.data.gouv.fr/fr/datasets/contours-des-departements-francais-issus-d-openstreetmap/) in the form of a `.zip` archive, which we will unzip locally into a `departements_fr` folder.
1290+
Below are the outlines of the department of Réunion [produced by the IGN](https://geoservices.ign.fr/telechargement-api/ADMIN-EXPRESS-COG-CARTO), in the form of a `..7z` archive that we will unzip locally into a folder called `departements_fr`.
12911291
::::
12921292

12931293

12941294
```{python}
12951295
import io
12961296
import os
12971297
import requests
1298-
import zipfile
1298+
import py7zr
12991299
13001300
# Import et décompression
1301-
contours_url = "https://www.data.gouv.fr/fr/datasets/r/eb36371a-761d-44a8-93ec-3d728bec17ce"
1301+
contours_url = "https://data.geopf.fr/telechargement/download/ADMIN-EXPRESS-COG-CARTO/ADMIN-EXPRESS-COG-CARTO_3-2__SHP_RGR92UTM40S_REU_2023-05-03/ADMIN-EXPRESS-COG-CARTO_3-2__SHP_RGR92UTM40S_REU_2023-05-03.7z"
13021302
response = requests.get(contours_url, stream=True)
1303-
zipfile = zipfile.ZipFile(io.BytesIO(response.content))
1304-
zipfile.extractall("departements_fr")
1303+
1304+
with py7zr.SevenZipFile(io.BytesIO(response.content), mode='r') as archive:
1305+
archive.extractall(path="departements_fr")
13051306
13061307
# Vérification du dossier (local, pas sur S3)
13071308
os.listdir("departements_fr")
@@ -1329,7 +1330,14 @@ Vérifions que le dossier a bien été copié :
13291330
fs.ls(f"{MY_BUCKET}/diffusion/departements_fr")
13301331
```
13311332

1332-
Si tout a bien fonctionné, la commande ci-dessus devrait renvoyer une liste contenant les chemins sur `MinIO` des différents fichiers (`.shp`, `.shx`, `.prj`, etc.) constitutifs du `ShapeFile` des départements.
1333+
Si le dossier, comme ici, contient des fichiers à plusieurs niveaux, il faudra parcourir la liste de manière récursive pour accéder aux fichiers. Si par exemple, on s'intéresse exclusivement aux découpages des communes, on pourra par exemple utiliser un [`glob`](https://docs.python.org/fr/3/library/glob.html):
1334+
1335+
```{python}
1336+
#| eval: false
1337+
fs.glob(f'{MY_BUCKET}/diffusion/departements_fr/**/COMMUNE.*')
1338+
```
1339+
1340+
Si tout a bien fonctionné, la commande ci-dessus devrait renvoyer une liste contenant les chemins sur `MinIO` des différents fichiers (`.shp`, `.shx`, `.prj`, etc.) constitutifs du `ShapeFile` des communes de la Réunion.
13331341
::::
13341342

13351343
:::: {.content-visible when-profile="en"}
@@ -1340,7 +1348,15 @@ Let’s check that the folder was successfully copied:
13401348
fs.ls(f"{MY_BUCKET}/diffusion/departements_fr")
13411349
```
13421350

1343-
If everything worked correctly, the command above should return a list of file paths on `MinIO` for the various components of the department `ShapeFile` (`.shp`, `.shx`, `.prj`, etc.).
1351+
If the folder, as in this case, contains files at multiple levels, you will need to browse the list recursively to access the files. If, for example, you are only interested in municipal divisions, you can use a [`glob`](https://docs.python.org/fr/3/library/glob.html):
1352+
1353+
1354+
```{python}
1355+
#| eval: false
1356+
fs.glob(f'{MY_BUCKET}/diffusion/departements_fr/**/COMMUNE.*')
1357+
```
1358+
1359+
If everything worked correctly, the command above should return a list of file paths on `MinIO` for the various components of the Réunion cities `ShapeFile` (`.shp`, `.shx`, `.prj`, etc.).
13441360
::::
13451361

13461362
:::: {.content-visible when-profile="fr"}
@@ -1395,11 +1411,21 @@ Puis on les importe classiquement depuis `Python` avec le *package* approprié.
13951411

13961412
```{python}
13971413
#| eval: false
1414+
from pathlib import Path
13981415
import geopandas as gpd
13991416
1400-
df_dep = gpd.read_file("departements_fr")
1417+
localpath = Path("departements_fr") #<1>
1418+
1419+
1420+
df_dep = gpd.read_file(
1421+
list(
1422+
localpath.glob("**/COMMUNE.shp")
1423+
)[0] #<2>
1424+
)
14011425
df_dep.head(2)
14021426
```
1427+
1. Comme notre dossier contient beaucoup de fichiers, on va devoir faire une recherche dedans via, à nouveau, un [`glob`](https://docs.python.org/fr/3/library/glob.html)
1428+
2. `Pathlib` nous donnant une liste, on se restreint au premier écho et on importe avec `GeoPandas`
14031429

14041430
## Pour aller plus loin
14051431

@@ -1458,11 +1484,22 @@ Then, you can import them in the usual way using the appropriate `Python` packag
14581484

14591485
```{python}
14601486
#| eval: false
1487+
from pathlib import Path
14611488
import geopandas as gpd
14621489
1463-
df_dep = gpd.read_file("departements_fr")
1490+
localpath = Path("departements_fr") #<1>
1491+
1492+
1493+
df_dep = gpd.read_file(
1494+
list(
1495+
localpath.glob("**/COMMUNE.shp")
1496+
)[0] #<2>
1497+
)
14641498
df_dep.head(2)
14651499
```
1500+
1. As our file contains many files, we will need to search through it using, once again, a [`glob`](https://docs.python.org/fr/3/library/glob.html)
1501+
2. `Pathlib` gives us a list, so we restrict ourselves to the first echo and import it with `GeoPandas`
1502+
14661503

14671504
## To go further
14681505

0 commit comments

Comments
 (0)