Annexe H — Semaines 6–8 — Préparer les données des grès

Cette page documente la chaîne qui transforme les fichiers publiés par Qin et al. (2022) en une table de 38 échantillons utilisée pour les corrélations, la régression linéaire et le diagnostic du modèle pendant les semaines 6–8.

H.1 Sources originales

Qin et Han publient leurs mesures sous licence CC BY 4.0 dans Mendeley Data, version 1, DOI 10.17632/7yhdmmpf6h.1. Les fichiers téléchargés le 28 septembre 2026 sont archivés sans modification dans appendices/data/sandstones/:

  • Grain_bulk_modulus_38_sandstone.csv rassemble les propriétés utilisées en classe;
  • Strain_stress_unjacketed_38_sandstone_samples.csv contient les mesures contrainte–déformation à l’origine du module des grains;
  • XRD_9_sandstone_samples.csv décrit la minéralogie de neuf échantillons seulement.

Les semaines 6–8 utilisent le premier fichier. Les deux autres sont conservés pour assurer la traçabilité de la publication, mais ne sont ni joints ni agrégés dans le fichier pédagogique.

H.2 Lire et renommer les variables

pd.read_csv() charge les 38 lignes sans filtre. rename() remplace ensuite les en-têtes longs par des noms qui conservent explicitement les unités.

Listing H.1: Lire la table originale et stabiliser les noms de colonnes
import pandas as pd

source = pd.read_csv(
    "appendices/data/sandstones/Grain_bulk_modulus_38_sandstone.csv"
)

renommage = {
    "SAMPLE": "sample_id",
    "POROSITY (V/V)": "porosity_fraction",
    "BULK DENSITY (g/cm^3)": "bulk_density_g_cm3",
    "GRAIN DENSITY (g/cm^3)": "grain_density_g_cm3",
    "PERMEABILITY ( 10^(-15) m^2)": "permeability_source_1e15_m2",
    "Formation Temperature (Celcius)": "formation_temperature_c",
    "Grain bulk modulus (GPa)": "grain_bulk_modulus_gpa",
    "standard deviation (GPa)": "grain_bulk_modulus_sd_gpa",
}

gres = source.rename(columns=renommage)
1
Lit le fichier compilé original sans supprimer de ligne.
2
Renomme les huit variables originales sans modifier leurs valeurs. Le suffixe source_1e15_m2 conserve temporairement l’unité utilisée dans le fichier publié.

H.3 Ajouter les variables nécessaires au cours

Le nom de chaque échantillon commence par son champ pétrolier. str.extract() récupère ce préfixe. La porosité est aussi exprimée en pourcentage pour faciliter sa lecture.

La source exprime la perméabilité en \(10^{-15}\) m², une unité peu intuitive à lire. Nous la convertissons en millidarcys (mD), une unité courante pour les roches réservoirs:

\[ k_{\mathrm{mD}} = \frac{k_{\mathrm{source}}\times10^{-15}}{9.869233\times10^{-16}}. \tag{H.1}\]

Dans Équation H.1, \(k_{\mathrm{source}}\) est la valeur numérique fournie dans l’unité \(10^{-15}\) m², \(9.869233\times10^{-16}\) m² est la valeur d’un millidarcy et \(k_{\mathrm{mD}}\) est la perméabilité convertie. Cette conversion change l’unité, pas la propriété physique mesurée. La variable booléenne permeability_detected signale ensuite les valeurs strictement positives compatibles avec une transformation logarithmique. insert() place les nouvelles variables à proximité de la colonne dont elles dérivent, rename() remplace le nom temporaire après la conversion et round() limite le résultat à trois décimales, une précision suffisante au regard des valeurs publiées.

Listing H.2: Dériver le champ, la porosité en pourcentage et la perméabilité en mD
gres.insert(
    1,
    "field",
    gres["sample_id"].str.extract(r"^([A-Za-z]+)", expand=False),
)

gres.insert(
    3,
    "porosity_pct",
    100 * gres["porosity_fraction"],
)

M2_PER_MD = 9.869233e-16
gres["permeability_source_1e15_m2"] = (
    gres["permeability_source_1e15_m2"] * 1e-15 / M2_PER_MD
).round(3)
gres = gres.rename(columns={
    "permeability_source_1e15_m2": "permeability_md"
})

gres.insert(
    7,
    "permeability_detected",
    gres["permeability_md"] > 0,
)
1
Extrait Grane, Kristin ou Statfjord depuis l’identifiant.
2
Ajoute une unité plus directement interprétable sans supprimer la fraction originale.
3
Convertit la perméabilité de \(10^{-15}\) m² en mD et retire la colonne temporaire exprimée dans l’unité source.
4
Identifie les 34 perméabilités strictement positives.

Le logarithme de la perméabilité n’est volontairement pas pré-calculé: les étudiants le construisent après avoir établi pourquoi une valeur nulle ou négative n’appartient pas au domaine de cette transformation.

H.4 Écrire et contrôler le fichier pédagogique

Listing H.3: Écrire et vérifier le fichier utilisé en semaines 6 à 8
gres.to_csv(
    "course/data/sandstones_norway.csv",
    index=False,
)

assert gres.shape == (38, 11)
assert gres["sample_id"].is_unique
assert gres["field"].value_counts().to_dict() == {
    "Kristin": 17,
    "Statfjord": 14,
    "Grane": 7,
}
assert gres["permeability_detected"].sum() == 34
1
Écrit le CSV final sans index technique.
2
Contrôle l’effectif total, l’unicité des échantillons, leur provenance et le nombre de perméabilités positives.

H.5 Structure finale

Table H.1: Colonnes du fichier pédagogique.
Colonne Signification
sample_id identifiant original de l’échantillon
field Grane, Kristin ou Statfjord
porosity_fraction fraction volumique de pores
porosity_pct porosité en pourcentage
bulk_density_g_cm3 masse volumique apparente en g cm⁻³
grain_density_g_cm3 masse volumique des grains en g cm⁻³
permeability_md perméabilité en millidarcys (mD)
permeability_detected True lorsque la perméabilité est strictement positive
formation_temperature_c température de formation en °C
grain_bulk_modulus_gpa module d’incompressibilité des grains en GPa
grain_bulk_modulus_sd_gpa écart-type rapporté du module en GPa

Aucune observation n’est supprimée et aucune moyenne n’est calculée pendant cette préparation. Les 38 lignes restent donc les 38 échantillons de la source; les exclusions nécessaires à une analyse particulière doivent être motivées dans le cours.