{"id":2726,"date":"2026-10-14T18:00:54","date_gmt":"2026-10-14T18:00:54","guid":{"rendered":"http:\/\/french.arabpsychology.com\/statistics\/comment-calculer-moyenne-geometrique-python-exemples\/"},"modified":"2026-10-14T18:00:54","modified_gmt":"2026-10-14T18:00:54","slug":"comment-calculer-moyenne-geometrique-python-exemples","status":"publish","type":"psych_stat","link":"https:\/\/french.arabpsychology.com\/?psych_stat=comment-calculer-moyenne-geometrique-python-exemples","title":{"rendered":"Comment calculer la moyenne g\u00e9om\u00e9trique en Python (avec exemples)"},"content":{"rendered":"<p>Dans le paysage contemporain de l&rsquo;analyse quantitative et de la science des donn\u00e9es, l&rsquo;\u00e9valuation de la tendance centrale d&rsquo;une distribution constitue l&rsquo;un des actes fondamentaux du raisonnement statistique. Si la moyenne arithm\u00e9tique s&rsquo;est impos\u00e9e comme la m\u00e9trique pr\u00e9pond\u00e9rante dans l&rsquo;inconscient collectif et la pratique courante des praticiens, son h\u00e9g\u00e9monie repose sur l&rsquo;hypoth\u00e8se sous-jacente d&rsquo;une structure d&rsquo;additivit\u00e9 des observations. Or, d\u00e8s lors que les ph\u00e9nom\u00e8nes observ\u00e9s rel\u00e8vent de dynamiques multiplicatives, de taux d&rsquo;\u00e9volution compos\u00e9s, d&rsquo;\u00e9chelles logarithmiques ou de ratios normalis\u00e9s, l&rsquo;application de la moyenne arithm\u00e9tique engendre un biais syst\u00e9matique par surestimation de la tendance r\u00e9elle du syst\u00e8me \u00e9tudi\u00e9. C&rsquo;est pr\u00e9cis\u00e9ment au sein de ces topologies de donn\u00e9es que la moyenne g\u00e9om\u00e9trique s&rsquo;av\u00e8re non seulement pertinente, mais math\u00e9matiquement indispensable pour pr\u00e9server la coh\u00e9rence intrins\u00e8que des grandeurs physiques, \u00e9conomiques ou psychom\u00e9triques.<\/p>\n<p>Le calcul computationnel de cette grandeur statistique soul\u00e8ve n\u00e9anmoins des d\u00e9fis algorithmiques substantiels qui d\u00e9passent la simple transcription litt\u00e9rale de sa d\u00e9finition alg\u00e9brique. L&rsquo;\u00e9valuation na\u00efve d&rsquo;un produit d&rsquo;une multitude de termes expose inexorablement les calculatrices et les architectures logicielles modernes au ph\u00e9nom\u00e8ne d&rsquo;\u00e9crasement ou de d\u00e9passement de capacit\u00e9 arithm\u00e9tique, commun\u00e9ment d\u00e9sign\u00e9 sous le terme d&rsquo;<em>overflow<\/em>, voire d&rsquo;annulation catastrophique. D\u00e8s lors, l&rsquo;ing\u00e9nierie statistique computationnelle doit mobiliser des transformations fonctionnelles sp\u00e9cifiques, fond\u00e9es sur les propri\u00e9t\u00e9s de morphisme du logarithme n\u00e9p\u00e9rien et de l&rsquo;exponentielle, afin de garantir une stabilit\u00e9 num\u00e9rique optimale sur des ensembles de donn\u00e9es massifs ou hautement dispers\u00e9s.<\/p>\n<p>L&rsquo;\u00e9cosyst\u00e8me du langage de programmation <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/www.python.org\">Python<\/a> s&rsquo;est impos\u00e9 comme la r\u00e9f\u00e9rence internationale pour relever ces d\u00e9fis d&rsquo;ing\u00e9nierie math\u00e9matique. Gr\u00e2ce \u00e0 des biblioth\u00e8ques de calcul vectoriel et scientifique de premier plan telles que <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/numpy.org\">NumPy<\/a> et <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/scipy.org\">SciPy<\/a>, les chercheurs et analystes disposent d&rsquo;outils optimis\u00e9s au niveau du silicium pour ex\u00e9cuter ces op\u00e9rations avec une rigueur analytique irr\u00e9prochable. Le pr\u00e9sent trait\u00e9 se propose de d\u00e9composer de mani\u00e8re exhaustive les fondements math\u00e9matiques, les architectures d&rsquo;impl\u00e9mentation sous Python, les m\u00e9canismes de gestion des singularit\u00e9s num\u00e9riques et les cas d&rsquo;usage avanc\u00e9s de la moyenne g\u00e9om\u00e9trique au sein d&rsquo;environnements de calcul modernes et distribu\u00e9s.<\/p>\n<h2>1. Introduction \u00e0 la moyenne g\u00e9om\u00e9trique et son utilit\u00e9 en statistique computationnelle<\/h2>\n<h3>1.1 D\u00e9finition th\u00e9orique et distinction par rapport \u00e0 la moyenne arithm\u00e9tique<\/h3>\n<p>La distinction conceptuelle entre la moyenne arithm\u00e9tique et la moyenne g\u00e9om\u00e9trique trouve son origine dans la nature m\u00eame des op\u00e9rations qui r\u00e9gissent les processus g\u00e9n\u00e9rateurs de donn\u00e9es. La moyenne arithm\u00e9tique mod\u00e9lise un processus d&rsquo;accumulation additive pure. Elle r\u00e9pond \u00e0 la question suivante : quelle valeur constante, si elle \u00e9tait somm\u00e9e <span class=\"arabpsy-math-inline\" data-latex=\"n\">$n$<\/span> fois, produirait le m\u00eame total cumul\u00e9 que l&rsquo;ensemble des observations empiriques ? Ce paradigme additif suppose implicitement que les variations individuelles s&rsquo;additionnent de fa\u00e7on lin\u00e9aire et ind\u00e9pendante le long de l&rsquo;espace de mesure. En revanche, la moyenne g\u00e9om\u00e9trique s&rsquo;ancre dans une logique strictement multiplicative. Elle d\u00e9termine la valeur unitaire constante qui, multipli\u00e9e par elle-m\u00eame <span class=\"arabpsy-math-inline\" data-latex=\"n\">$n$<\/span> fois, reconstitue exactement le produit global g\u00e9n\u00e9r\u00e9 par l&rsquo;ensemble des donn\u00e9es. Cette m\u00e9trique trouve son expression canonique dans l&rsquo;\u00e9valuation des grandeurs o\u00f9 les effets s&rsquo;amplifient proportionnellement \u00e0 l&rsquo;\u00e9tat ant\u00e9rieur du syst\u00e8me.<\/p>\n<p>Une cons\u00e9quence imm\u00e9diate de cette divergence structurelle concerne l&rsquo;influence respective des observations extr\u00eames et la r\u00e9sistance face aux asym\u00e9tries de distribution. La moyenne arithm\u00e9tique est notoirement vuln\u00e9rable aux valeurs aberrantes positives (ph\u00e9nom\u00e8ne de queue de distribution lourde vers la droite) ; un unique nombre de magnitude disproportionn\u00e9e tire artificiellement le centre de gravit\u00e9 vers des r\u00e9gions non repr\u00e9sentatives du gros de la population. \u00c0 l&rsquo;inverse, la moyenne g\u00e9om\u00e9trique compresse l&rsquo;\u00e9chelle des grandeurs par l&rsquo;action conjointe de la multiplication et de l&rsquo;extraction de racine. Elle amortit l&rsquo;impact d\u00e9stabilisant des valeurs excessivement \u00e9lev\u00e9es, tout en accordant une sensibilit\u00e9 accrue aux valeurs approchant de la borne inf\u00e9rieure. En vertu de l&rsquo;in\u00e9galit\u00e9 de Cauchy-Schwarz et du th\u00e9or\u00e8me fondamental des moyennes de H\u00f6lder, pour toute s\u00e9rie de r\u00e9els strictement positifs non identiques, la moyenne g\u00e9om\u00e9trique est strictement inf\u00e9rieure \u00e0 la moyenne arithm\u00e9tique, illustrant son pouvoir r\u00e9gulateur sur l&rsquo;asym\u00e9trie.<\/p>\n<p>D&rsquo;un point de vue \u00e9pist\u00e9mologique, la moyenne g\u00e9om\u00e9trique s&rsquo;impose d\u00e8s lors que les donn\u00e9es analys\u00e9es constituent des ratios, des pourcentages de variation relative, des indices sans dimension ou des intensit\u00e9s relatives. Consid\u00e9rons l&rsquo;exemple paradigmatique d&rsquo;une grandeur augmentant de 100 % au cours d&rsquo;une premi\u00e8re p\u00e9riode (multiplicateur de 2,0), puis chutant de 50 % au cours de la p\u00e9riode cons\u00e9cutive (multiplicateur de 0,5). La moyenne arithm\u00e9tique des facteurs d&rsquo;\u00e9volution produit <span class=\"arabpsy-math-inline\" data-latex=\"(2,0 + 0,5) \/ 2 = 1,25\">$(2,0 + 0,5) \/ 2 = 1,25$<\/span>, laissant pr\u00e9sumer une progression nette de 25 % par p\u00e9riode. Or, la r\u00e9alit\u00e9 sous-jacente met en \u00e9vidence un retour parfait \u00e0 l&rsquo;\u00e9tat initial (<span class=\"arabpsy-math-inline\" data-latex=\"2,0 \\times 0,5 = 1,0\">$2,0 \\times 0,5 = 1,0$<\/span>). Seule la moyenne g\u00e9om\u00e9trique, \u00e9gale \u00e0 <span class=\"arabpsy-math-inline\" data-latex=\"\\sqrt{2,0 \\times 0,5} = 1,0\">$\\sqrt{2,0 \\times 0,5} = 1,0$<\/span>, restitue fid\u00e8lement l&rsquo;invariance dynamique du syst\u00e8me. Traiter des ratios au moyen d&rsquo;outils arithm\u00e9tiques constitue une distorsion m\u00e9thodologique majeure que la statistique computationnelle moderne vise \u00e0 \u00e9radiquer de mani\u00e8re syst\u00e9matique.<\/p>\n<h3>1.2 Pertinence m\u00e9thodologique dans la recherche empirique et quantitative<\/h3>\n<p>Dans les protocoles exp\u00e9rimentaux et les investigations quantitatives contemporaines, la moyenne g\u00e9om\u00e9trique intervient \u00e0 des carrefours m\u00e9thodologiques cruciaux. Un domaine d&rsquo;\u00e9lection r\u00e9side dans l&rsquo;\u00e9laboration d&rsquo;indices composites multidimensionnels. Lorsque des chercheurs cherchent \u00e0 synth\u00e9tiser des indicateurs h\u00e9t\u00e9rog\u00e8nes mesur\u00e9s selon des \u00e9chelles divergentes \u2014 tels que le produit int\u00e9rieur brut, l&rsquo;esp\u00e9rance de vie et le niveau d&rsquo;alphab\u00e9tisation au sein de l&rsquo;<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/hdr.undp.org\">Indice de D\u00e9veloppement Humain (IDH)<\/a> publi\u00e9 par les Nations Unies \u2014, l&rsquo;agr\u00e9gation arithm\u00e9tique introduit un biais de compensation totale inacceptable. Une performance extravagante dans un sous-domaine peut masquer une carence critique dans un autre. La moyenne g\u00e9om\u00e9trique p\u00e9nalise intrins\u00e8quement les d\u00e9s\u00e9quilibres entre composantes, instaurant une logique de substituabilit\u00e9 imparfaite hautement vertueuse pour la fid\u00e9lit\u00e9 de l&rsquo;\u00e9valuation globale.<\/p>\n<p>En psychologie cognitive, en neurosciences computationnelles et en ergonomie, la m\u00e9trique g\u00e9om\u00e9trique s&rsquo;av\u00e8re indispensable pour caract\u00e9riser les chronom\u00e9tries mentales et les dynamiques d&rsquo;apprentissage. Les distributions des temps de r\u00e9action (TR) lors de t\u00e2ches d&rsquo;attention s\u00e9lective ou de cat\u00e9gorisation lexicale pr\u00e9sentent une morphologie syst\u00e9matiquement asym\u00e9trique, souvent mod\u00e9lis\u00e9e par des lois ex-gaussiennes ou log-normales. L&rsquo;analyse des temps m\u00e9dians ou des moyennes arithm\u00e9tiques masque fr\u00e9quemment la r\u00e9alit\u00e9 des micro-m\u00e9canismes neuro-computationnels sous-jacents en raison de l&rsquo;extr\u00eame volatilit\u00e9 des latences motrices. En appliquant la moyenne g\u00e9om\u00e9trique aux latences individuelles, le chercheur extrait une grandeur repr\u00e9sentative stable qui refl\u00e8te la vitesse centrale de traitement cortical sans n\u00e9cessiter l&rsquo;amputation arbitraire des queues de distribution par \u00e9lagage statistique non contr\u00f4l\u00e9.<\/p>\n<p>Enfin, la pr\u00e9servation de la coh\u00e9rence math\u00e9matique lors du changement d&rsquo;unit\u00e9s de mesure constitue une propri\u00e9t\u00e9 fondamentale de la moyenne g\u00e9om\u00e9trique. Dans de multiples branches des sciences exactes, la transformation lin\u00e9aire des donn\u00e9es (par exemple, la conversion de millisecondes en secondes, ou de devises nationales en monnaie de r\u00e9f\u00e9rence internationale) doit laisser invariante la structure relationnelle des agr\u00e9gations calcul\u00e9es. Contrairement \u00e0 d&rsquo;autres m\u00e9triques complexes, la moyenne g\u00e9om\u00e9trique satisfait rigoureusement au crit\u00e8re d&rsquo;invariance d&rsquo;\u00e9chelle : multiplier l&rsquo;ensemble des donn\u00e9es d&rsquo;entr\u00e9e par une constante scalaire quelconque <span class=\"arabpsy-math-inline\" data-latex=\"lambda\">$lambda$<\/span> \u00e9quivaut exactement \u00e0 multiplier la moyenne g\u00e9om\u00e9trique globale par cette m\u00eame constante. Cette homomorphie garantit que les conclusions tir\u00e9es d&rsquo;une \u00e9tude empirique ne d\u00e9pendent en aucun cas du syst\u00e8me m\u00e9trique arbitrairement s\u00e9lectionn\u00e9 par l&rsquo;exp\u00e9rimentateur.<\/p>\n<h3>1.3 Pr\u00e9sentation de l&rsquo;environnement d&rsquo;analyse sous Python<\/h3>\n<p>L&rsquo;ex\u00e9cution computationnelle des analyses statistiques avanc\u00e9es exige un environnement logiciel robuste alliant expressivit\u00e9 conceptuelle, rapidit\u00e9 d&rsquo;ex\u00e9cution et v\u00e9rifiabilit\u00e9 formelle. Le langage Python s&rsquo;est impos\u00e9 comme l&rsquo;infrastructure par excellence pour la statistique computationnelle, largement propuls\u00e9 par son \u00e9cosyst\u00e8me scientifique unifi\u00e9. Au c\u0153ur de cette architecture se trouvent deux biblioth\u00e8ques fondatrices : NumPy (Numerical Python) et SciPy (Scientific Python). NumPy fournit la structure de donn\u00e9es universelle sous la forme du tableau multidimensionnel homog\u00e8ne <code>ndarray<\/code>, coupl\u00e9 \u00e0 une couche de routines compil\u00e9es en langage C et Fortran permettant le contournement du verrou global de l&rsquo;interpr\u00e9teur (GIL) et l&rsquo;exploitation directe des registres vectoriels des processeurs contemporains.<\/p>\n<p>SciPy se positionne hi\u00e9rarchiquement au-dessus de NumPy, en \u00e9tendant ses fonctionnalit\u00e9s matricielles brutes vers des modules sp\u00e9cialis\u00e9s d&rsquo;optimisation, de traitement du signal, d&rsquo;alg\u00e8bre lin\u00e9aire avanc\u00e9e et de statistique inf\u00e9rentielle regroup\u00e9s au sein du sous-module <code>scipy.stats<\/code>. La mise en \u0153uvre de la moyenne g\u00e9om\u00e9trique au sein de ces biblioth\u00e8ques ne rel\u00e8ve pas d&rsquo;une programmation it\u00e9rative triviale via des boucles <code>for<\/code> conventionnelles \u2014 approche intrins\u00e8quement lente et inefficace en langage interpr\u00e9t\u00e9 \u2014, mais tire parti de la vectorisation. Ce paradigme algorithmique permet de d\u00e9l\u00e9guer l&rsquo;ensemble des parcours s\u00e9quentiels de la m\u00e9moire \u00e0 des instructions mat\u00e9rielles sp\u00e9cialis\u00e9es du type SIMD (<em>Single Instruction, Multiple Data<\/em>), optimisant le d\u00e9bit computationnel sur des volumes de donn\u00e9es massifs.<\/p>\n<p>Le protocole d&rsquo;analyse d\u00e9ploy\u00e9 au long de cet ouvrage vise \u00e0 \u00e9quiper le praticien d&rsquo;une vision holistique et rigoureuse du calcul de la moyenne g\u00e9om\u00e9trique en Python. Il ne s&rsquo;agit pas uniquement de documenter les syntaxes superficielles des modules existants, mais de d\u00e9cortiquer les m\u00e9canismes de bas niveau assurant la stabilit\u00e9 num\u00e9rique face \u00e0 des matrices \u00e0 haute densit\u00e9. Nous explorerons l&rsquo;architecture interne des fonctions sp\u00e9cialis\u00e9es, la reconstruction algorithmique des transformations logarithmiques pures, les m\u00e9thodes comparatives de micro-benchmarking ainsi que la manipulation rigoureuse des cas pathologiques tels que l&rsquo;inclusion de z\u00e9ros stochastiques ou de valeurs n\u00e9gatives au sein des s\u00e9ries d&rsquo;observations.<\/p>\n<h2>2. Fondements math\u00e9matiques : de la formule multiplicative \u00e0 la transformation logarithmique<\/h2>\n<h3>2.1 La formulation multiplicative classique par racine n-i\u00e8me<\/h3>\n<p>L&rsquo;expression analytique primaire de la moyenne g\u00e9om\u00e9trique s&rsquo;inscrit dans la continuit\u00e9 directe de la d\u00e9finition alg\u00e9brique des moyennes pythagoriciennes. Soit un ensemble fini constitu\u00e9 de <span class=\"arabpsy-math-inline\" data-latex=\"n\">$n$<\/span> observations quantitatives r\u00e9elles not\u00e9es <span class=\"arabpsy-math-inline\" data-latex=\"X = {x_1, x_2, dots, x_n}\">$X = {x_1, x_2, dots, x_n}$<\/span>. La moyenne g\u00e9om\u00e9trique, formellement d\u00e9sign\u00e9e par la lettre <span class=\"arabpsy-math-inline\" data-latex=\"G\">$G$<\/span> ou <span class=\"arabpsy-math-inline\" data-latex=\"\\bar{x}_g\">$\\bar{x}_g$<\/span>, est d\u00e9finie comme la racine <span class=\"arabpsy-math-inline\" data-latex=\"n\">$n$<\/span>-i\u00e8me du produit cumul\u00e9 de l&rsquo;ensemble des termes observ\u00e9s :<\/p>\n<p><span class=\"arabpsy-math-display\" data-latex=\"G(X) = \\sqrt[n]{\\prod_{i=1}^{n} x_i} = \\left( \\prod_{i=1}^{n} x_i \\right)^{\\frac{1}{n}}\">$$G(X) = \\sqrt[n]{\\prod_{i=1}^{n} x_i} = \\left( \\prod_{i=1}^{n} x_i \\right)^{\\frac{1}{n}}$$<\/span><\/p>\n<p>Cette formulation, d&rsquo;une grande clart\u00e9 conceptuelle, pose des contraintes op\u00e9rationnelles imm\u00e9diates d\u00e8s lors qu&rsquo;elle est traduite dans un algorithme machine ex\u00e9cut\u00e9 sur des architectures mat\u00e9rielles limit\u00e9es par les sp\u00e9cifications de la norme IEEE 754 relative \u00e0 l&rsquo;arithm\u00e9tique en virgule flottante. Le danger pr\u00e9\u00e9minent r\u00e9side dans l&rsquo;amplitude exponentielle du produit cumul\u00e9 <span class=\"arabpsy-math-inline\" data-latex=\"\\prod_{i=1}^{n} x_i\">$\\prod_{i=1}^{n} x_i$<\/span>. Dans un environnement standard cod\u00e9 en pr\u00e9cision double (64 bits), la plus grande valeur positive pouvant \u00eatre repr\u00e9sent\u00e9e sans d\u00e9border vers l&rsquo;infini symbolique (not\u00e9 <code>inf<\/code>) est approximativement de <span class=\"arabpsy-math-inline\" data-latex=\"1{,}797 \\times 10^{308}\">$1{,}797 \\times 10^{308}$<\/span>.<\/p>\n<p>Consid\u00e9rons une s\u00e9rie exp\u00e9rimentale compos\u00e9e de seulement 200 observations homog\u00e8nes dont la magnitude individuelle avoisine $100$. Le produit de ces grandeurs \u00e9quivaut \u00e0 <span class=\"arabpsy-math-inline\" data-latex=\"100^{200} = (10^2)^{200} = 10^{400}\">$100^{200} = (10^2)^{200} = 10^{400}$<\/span>. Bien que la moyenne g\u00e9om\u00e9trique finale de cette s\u00e9rie soit rigoureusement \u00e9gale \u00e0 $100$, le calcul na\u00eff de la phase interm\u00e9diaire du produit engendre un d\u00e9passement de capacit\u00e9 (<em>floating-point overflow<\/em>), provoquant un basculement pr\u00e9matur\u00e9 vers l&rsquo;infini machine. D\u00e8s lors, l&rsquo;application subs\u00e9quente de la puissance <span class=\"arabpsy-math-inline\" data-latex=\"1\/n\">$1\/n$<\/span> sur cette valeur infinie renvoie un r\u00e9sultat ind\u00e9fini ou fallacieux. De surcro\u00eet, la validit\u00e9 math\u00e9matique de la racine d&rsquo;ordre pair impose que le produit sous le radical ne soit jamais n\u00e9gatif, contraignant ainsi le domaine fonctionnel de base aux r\u00e9els strictement positifs :<\/p>\n<p><span class=\"arabpsy-math-display\" data-latex=\"\\forall i in {1, dots, n}, \\quad x_i in \\mathbb{R}_{&gt;0}\">$$\\forall i in {1, dots, n}, \\quad x_i in \\mathbb{R}_{>0}$$<\/span><\/p>\n<h3>2.2 La reformulation logarithmique stabilis\u00e9e<\/h3>\n<p>Pour contourner l&rsquo;\u00e9cueil insurmontable de l&rsquo;instabilit\u00e9 du produit classique, l&rsquo;analyse num\u00e9rique exploite les propri\u00e9t\u00e9s d&rsquo;homomorphisme de la fonction logarithme, qui transforme une structure multiplicative en un espace vectoriel additif. En appliquant le logarithme naturel (ou n\u00e9p\u00e9rien) \u00e0 la formulation multiplicative initiale, on obtient l&rsquo;identit\u00e9 fondamentale suivante :<\/p>\n<p><span class=\"arabpsy-math-display\" data-latex=\"\\ln(G) = \\ln\\left( \\left( \\prod_{i=1}^{n} x_i \\right)^{\\frac{1}{n}} \\right) = \\frac{1}{n} \\ln\\left( \\prod_{i=1}^{n} x_i \\right) = \\frac{1}{n} \\sum_{i=1}^{n} \\ln(x_i)\">$$\\ln(G) = \\ln\\left( \\left( \\prod_{i=1}^{n} x_i \\right)^{\\frac{1}{n}} \\right) = \\frac{1}{n} \\ln\\left( \\prod_{i=1}^{n} x_i \\right) = \\frac{1}{n} \\sum_{i=1}^{n} \\ln(x_i)$$<\/span><\/p>\n<p>En mobilisant l&rsquo;op\u00e9rateur exponentiel, bijection r\u00e9ciproque du logarithme sur le corps des r\u00e9els, la moyenne g\u00e9om\u00e9trique s&rsquo;exprime alors rigoureusement comme l&rsquo;exponentielle de la moyenne arithm\u00e9tique des logarithmes n\u00e9p\u00e9riens des observations constitutives :<\/p>\n<p><span class=\"arabpsy-math-display\" data-latex=\"G(X) = \\exp\\left( \\frac{1}{n} \\sum_{i=1}^{n} \\ln(x_i) \\right)\">$$G(X) = \\exp\\left( \\frac{1}{n} \\sum_{i=1}^{n} \\ln(x_i) \\right)$$<\/span><\/p>\n<p>Cette reformulation constitue l&rsquo;\u00e9pine dorsale de tous les algorithmes de calcul statistique modernes. La sommation de termes logarithmiques pr\u00e9vient d\u00e9finitivement les risques d&rsquo;explosion arithm\u00e9tique. Par exemple, pour les 200 valeurs \u00e9gales \u00e0 $100$, la transformation pr\u00e9alable produit <span class=\"arabpsy-math-inline\" data-latex=\"\\ln(100) \\approx 4{,}605\">$\\ln(100) \\approx 4{,}605$<\/span>. La somme arithm\u00e9tique de ces grandeurs donne <span class=\"arabpsy-math-inline\" data-latex=\"200 \\times 4{,}605 = 921{,}03\">$200 \\times 4{,}605 = 921{,}03$<\/span>, une grandeur parfaitement contenue dans la plage des r\u00e9els standard. La division finale par <span class=\"arabpsy-math-inline\" data-latex=\"n=200\">$n=200$<\/span> restitue <span class=\"arabpsy-math-inline\" data-latex=\"4{,}605\">$4{,}605$<\/span>, dont l&rsquo;exponentiation directe fournit avec une pr\u00e9cision num\u00e9rique optimale la valeur exacte de <span class=\"arabpsy-math-inline\" data-latex=\"100{,}0\">$100{,}0$<\/span>. Cette technique garantit que la consommation dynamique de la mantisse reste parfaitement distribu\u00e9e tout au long du cycle de calcul, \u00e9vitant \u00e0 la fois les arrondis pr\u00e9coces et les annulations catastrophiques associ\u00e9es aux tr\u00e8s grands volumes de donn\u00e9es.<\/p>\n<h3>2.3 Conditions de validit\u00e9 et domaine de d\u00e9finition analytique<\/h3>\n<p>L&rsquo;\u00e9l\u00e9gance formelle de la reformulation logarithmique ne doit pas dissimuler ses fronti\u00e8res math\u00e9matiques rigides. Le domaine de d\u00e9finition analytique du logarithme r\u00e9el est strictement limit\u00e9 \u00e0 l&rsquo;intervalle ouvert <span class=\"arabpsy-math-inline\" data-latex=\"]0, +\\infty[\">$]0, +\\infty[$<\/span>. Cette restriction fondamentale impose des v\u00e9rifications pr\u00e9alables imp\u00e9ratives lors de l&rsquo;automatisation des pipelines computationnels sous Python. La pr\u00e9sence d&rsquo;une unique valeur n\u00e9gative au sein du vecteur <span class=\"arabpsy-math-inline\" data-latex=\"X\">$X$<\/span> entra\u00eene une discontinuit\u00e9 imm\u00e9diate du calcul dans <span class=\"arabpsy-math-inline\" data-latex=\"\\mathbb{R}\">$\\mathbb{R}$<\/span>, pr\u00e9cipitant la g\u00e9n\u00e9ration de valeurs manquantes (<code>NaN<\/code>) ou de nombres complexes d\u00e9pourvus d&rsquo;interpr\u00e9tation physique coh\u00e9rente dans un mod\u00e8le de tendance centrale standard.<\/p>\n<p>De m\u00eame, l&rsquo;existence d&rsquo;une valeur nulle (<span class=\"arabpsy-math-inline\" data-latex=\"x_i = 0\">$x_i = 0$<\/span>) constitue une singularit\u00e9 critique. D&rsquo;un point de vue purement multiplicatif, si un seul \u00e9l\u00e9ment de la s\u00e9rie est nul, le produit global s&rsquo;annule instantan\u00e9ment :<\/p>\n<p><span class=\"arabpsy-math-display\" data-latex=\"\\prod_{i=1}^{n} x_i = 0 implies \\sqrt[n]{0} = 0\">$$\\prod_{i=1}^{n} x_i = 0 implies \\sqrt[n]{0} = 0$$<\/span><\/p>\n<p>Cette propri\u00e9t\u00e9 absorbe l&rsquo;ensemble des informations port\u00e9es par les <span class=\"arabpsy-math-inline\" data-latex=\"n-1\">$n-1$<\/span> autres observations, annihilant toute signification statistique r\u00e9siduelle. Sur le plan logarithmique, l&rsquo;\u00e9valuation de <span class=\"arabpsy-math-inline\" data-latex=\"ln(0)\">$ln(0)$<\/span> diverge vers <span class=\"arabpsy-math-inline\" data-latex=\"-\\infty\">$-\\infty$<\/span>, g\u00e9n\u00e9rant une valeur limite non d\u00e9finie lors des op\u00e9rations d&rsquo;addition machine. En cons\u00e9quence, la moyenne g\u00e9om\u00e9trique n&rsquo;est th\u00e9oriquement congruente et num\u00e9riquement stable que pour des s\u00e9ries d&rsquo;observations positives non nulles. D\u00e8s lors que l&rsquo;on traite de distributions continues pouvant traverser le z\u00e9ro de mani\u00e8re stochastique, des protocoles de pr\u00e9traitement ou de r\u00e9gularisation analytique s&rsquo;av\u00e8rent indispensables pour pr\u00e9server la viabilit\u00e9 de l&rsquo;op\u00e9rateur.<\/p>\n<h2>3. M\u00e9thode 1 : Calcul de la moyenne g\u00e9om\u00e9trique avec SciPy (<code>scipy.stats.gmean<\/code>)<\/h2>\n<h3>3.1 Syntaxe, architecture et arguments de la fonction <code>scipy.stats.gmean<\/code><\/h3>\n<p>Au sein de l&rsquo;\u00e9cosyst\u00e8me Python, la biblioth\u00e8que SciPy offre l&rsquo;impl\u00e9mentation de r\u00e9f\u00e9rence la plus robuste et standardis\u00e9e pour le calcul de la moyenne g\u00e9om\u00e9trique via la fonction <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/docs.scipy.org\/doc\/scipy\/reference\/generated\/scipy.stats.gmean.html\"><code>scipy.stats.gmean<\/code><\/a>. Con\u00e7ue pour s&rsquo;interfacer de fa\u00e7on transparente avec les structures tabulaires multidimensionnelles de NumPy, cette routine encapsule une logique computationnelle hautement optimis\u00e9e, g\u00e9rant les transformations logarithmiques et l&rsquo;\u00e9valuation vectorielle avec un contr\u00f4le scrupuleux des conditions d&rsquo;erreur aux limites.<\/p>\n<p>La signature compl\u00e8te de la fonction au sein des versions r\u00e9centes de SciPy se pr\u00e9sente comme suit :<\/p>\n<pre><code>scipy.stats.gmean(a, axis=0, dtype=None, weights=None, nan_policy='propagate', keepdims=False)<\/code><\/pre>\n<p>Chacun de ces arguments r\u00e9pond \u00e0 des contraintes m\u00e9thodologiques pr\u00e9cises :<\/p>\n<ul>\n<li><strong>a :<\/strong> Tableau d&rsquo;entr\u00e9e contenant les donn\u00e9es empiriques (peut \u00eatre une liste native Python, un tableau <code>numpy.ndarray<\/code>, ou une s\u00e9rie Pandas).<\/li>\n<li><strong>axis :<\/strong> Axe dimensionnel le long duquel la r\u00e9duction statistique doit \u00eatre op\u00e9r\u00e9e. Par d\u00e9faut fix\u00e9 \u00e0 0 (calcul colonne par colonne pour les matrices bi-dimensionnelles). Si l&rsquo;argument est configur\u00e9 \u00e0 <code>None<\/code>, la fonction aplatit pr\u00e9alablement la structure pour renvoyer un unique scalaire global.<\/li>\n<li><strong>dtype :<\/strong> Type de donn\u00e9es interne utilis\u00e9 pour ex\u00e9cuter les calculs interm\u00e9diaires. Permet d&rsquo;imposer une pr\u00e9cision accrue, par exemple en sp\u00e9cifiant <code>np.float64<\/code> pour \u00e9viter les micro-pertes de pr\u00e9cision sur les distributions sensibles.<\/li>\n<li><strong>weights :<\/strong> Tableau de coefficients de pond\u00e9ration associ\u00e9 \u00e0 chaque observation individuelle, permettant le calcul d&rsquo;une moyenne g\u00e9om\u00e9trique pond\u00e9r\u00e9e.<\/li>\n<li><strong>nan_policy :<\/strong> D\u00e9termine le comportement face aux valeurs ind\u00e9finies (<code>NaN<\/code>). Trois modes d&rsquo;action sont propos\u00e9s : <code>'propagate'<\/code> (renvoie un <code>NaN<\/code> d\u00e8s qu&rsquo;une valeur manquante est d\u00e9tect\u00e9e), <code>'raise'<\/code> (l\u00e8ve une exception de type <code>ValueError<\/code>), ou <code>'omit'<\/code> (exclut dynamiquement les valeurs manquantes lors de la r\u00e9duction).<\/li>\n<li><strong>keepdims :<\/strong> Bool\u00e9en qui, lorsqu&rsquo;il est instanci\u00e9 \u00e0 <code>True<\/code>, conserve les axes r\u00e9duits sous forme de dimensions unitaires (longueur 1), facilitant les op\u00e9rations d&rsquo;alignement multidimensionnel (<em>broadcasting<\/em>).<\/li>\n<\/ul>\n<h3>3.2 Exemple d&rsquo;ex\u00e9cution pas \u00e0 pas sur un vecteur d&rsquo;observations<\/h3>\n<p>Afin de concr\u00e9tiser le d\u00e9ploiement op\u00e9rationnel de cette routine, nous allons initialiser un environnement Python standardis\u00e9 et soumettre un vecteur de donn\u00e9es empiriques h\u00e9t\u00e9rog\u00e8nes au crible de l&rsquo;algorithme SciPy. Choisissons un \u00e9chantillon de r\u00e9f\u00e9rence fr\u00e9quemment mobilis\u00e9 dans la litt\u00e9rature didactique : <span class=\"arabpsy-math-inline\" data-latex=\"X = [1, 4, 7, 6, 6, 4, 8, 9]\">$X = [1, 4, 7, 6, 6, 4, 8, 9]$<\/span>. Ce jeu de donn\u00e9es pr\u00e9sente des variations d&rsquo;amplitudes mod\u00e9r\u00e9es, id\u00e9al pour observer la m\u00e9canique de compression de la tendance centrale.<\/p>\n<pre><code>import numpy as np\nfrom scipy import stats\n\n# D\u00e9finition de l'\u00e9chantillon d'observations\ndonnees_echantillon = np.array([1, 4, 7, 6, 6, 4, 8, 9])\n\n# Invocation formelle de la moyenne g\u00e9om\u00e9trique SciPy\nmoyenne_geom = stats.gmean(donnees_echantillon)\n\n# Calcul parall\u00e8le de la moyenne arithm\u00e9tique conventionnelle\nmoyenne_arith = np.mean(donnees_echantillon)\n\n# Restitution et formatage des m\u00e9triques\nprint(f\"Moyenne g\u00e9om\u00e9trique : {moyenne_geom:.14f}\")\nprint(f\"Moyenne arithm\u00e9tique: {moyenne_arith:.14f}\")\n<\/code><\/pre>\n<p>L&rsquo;ex\u00e9cution de ce fragment de code g\u00e9n\u00e8re les sorties num\u00e9riques suivantes :<\/p>\n<pre><code>Moyenne g\u00e9om\u00e9trique : 4.81788719702029\nMoyenne arithm\u00e9tique: 5.62500000000000\n<\/code><\/pre>\n<p>L&rsquo;analyse compar\u00e9e des grandeurs obtenues valide de mani\u00e8re spectaculaire les principes th\u00e9oriques \u00e9nonc\u00e9s pr\u00e9alablement. La moyenne arithm\u00e9tique s&rsquo;\u00e9tablit \u00e0 <span class=\"arabpsy-math-inline\" data-latex=\"5{,}625\">$5{,}625$<\/span>, tir\u00e9e vers le haut par la pr\u00e9sence des valeurs sup\u00e9rieures de la s\u00e9rie (<span class=\"arabpsy-math-inline\" data-latex=\"7, 8, 9\">$7, 8, 9$<\/span>). En revanche, la moyenne g\u00e9om\u00e9trique ressort \u00e0 environ <span class=\"arabpsy-math-inline\" data-latex=\"4{,}8179\">$4{,}8179$<\/span>. La pr\u00e9sence du chiffre $1$ en d\u00e9but de s\u00e9rie exerce une influence mod\u00e9ratrice substantielle sur le produit global. La moyenne g\u00e9om\u00e9trique se positionne ici plus fid\u00e8lement au c\u0153ur g\u00e9om\u00e9trique du volume g\u00e9n\u00e9r\u00e9 par les observations, illustrant sa r\u00e9sistance aux amplitudes asym\u00e9triques positives.<\/p>\n<h3>3.3 Traitement multidimensionnel le long d&rsquo;un axe sp\u00e9cifique<\/h3>\n<p>Dans les applications r\u00e9elles de traitement du signal, de neuro-imagerie ou de bio-informatique, les donn\u00e9es ne se pr\u00e9sentent que rarement sous la forme de vecteurs unidimensionnels isol\u00e9s. Elles sont le plus souvent structur\u00e9es au sein de matrices multidimensionnelles repr\u00e9sentant des cohortes de sujets en lignes et des capteurs ou des g\u00e8nes en colonnes. La fonction <code>scipy.stats.gmean<\/code> d\u00e9ploie toute sa puissance computationnelle dans sa capacit\u00e9 \u00e0 vectoriser les r\u00e9ductions statistiques selon des axes arbitraires sans n\u00e9cessiter la moindre boucle it\u00e9rative explicite.<\/p>\n<pre><code># Cr\u00e9ation d'une matrice bidimensionnelle (3 lignes, 4 colonnes)\nmatrice_experience = np.array([\n    [10.0, 20.0, 30.0, 40.0],\n    [1.5,  2.5,  3.5,  4.5],\n    [100.0, 200.0, 300.0, 400.0]\n])\n\n# R\u00e9duction le long des colonnes (axis=0) : agr\u00e9gation verticale des lignes\ngeom_colonnes = stats.gmean(matrice_experience, axis=0)\n\n# R\u00e9duction le long des lignes (axis=1) : agr\u00e9gation horizontale des colonnes\ngeom_lignes = stats.gmean(matrice_experience, axis=1)\n\n# R\u00e9duction avec pr\u00e9servation de la dimensionnalit\u00e9 (keepdims=True)\ngeom_preserve = stats.gmean(matrice_experience, axis=1, keepdims=True)\n\nprint(\"Moyenne g\u00e9om\u00e9trique par colonne (axis=0) :\", geom_colonnes)\nprint(\"Moyenne g\u00e9om\u00e9trique par ligne (axis=1)   :\", geom_lignes)\nprint(\"Forme du tenseur avec keepdims=True       :\", geom_preserve.shape)\n<\/code><\/pre>\n<p>Dans cet exemple, l&rsquo;op\u00e9ration <code>axis=0<\/code> comprime verticalement le tableau pour produire un vecteur unidimensionnel de dimension 4, correspondant \u00e0 la moyenne g\u00e9om\u00e9trique de chaque variable au travers des trois observations exp\u00e9rimentales. R\u00e9ciproquement, <code>axis=1<\/code> comprime horizontalement les donn\u00e9es pour restituer un vecteur \u00e0 trois \u00e9l\u00e9ments d\u00e9crivant la trajectoire g\u00e9om\u00e9trique de chaque sujet exp\u00e9rimental au travers des quatre mesures. L&rsquo;activation de <code>keepdims=True<\/code> maintient la structure matricielle sous la forme <span class=\"arabpsy-math-inline\" data-latex=\"(3, 1)\">$(3, 1)$<\/span>, permettant de soustraire ou de diviser instantan\u00e9ment la matrice d&rsquo;origine par ce profil g\u00e9om\u00e9trique sans distorsion dimensionnelle gr\u00e2ce aux r\u00e8gles de diffusion automatique (<em>broadcasting<\/em>) de NumPy.<\/p>\n<h2>4. M\u00e9thode 2 : Impl\u00e9mentation personnalis\u00e9e avec NumPy (<code>np.log<\/code> et <code>np.exp<\/code>)<\/h2>\n<h3>4.1 Conception d&rsquo;une routine vectoris\u00e9e personnalis\u00e9e<\/h3>\n<p>Bien que l&rsquo;invocation d&rsquo;un module cl\u00e9 en main tel que <code>scipy.stats.gmean<\/code> soit particuli\u00e8rement commode, il existe de multiples contextes d&rsquo;ing\u00e9nierie logicielle o\u00f9 l&rsquo;all\u00e9gement des d\u00e9pendances externes ou l&rsquo;insertion de logiques de calcul au sein d&rsquo;environnements contraints justifient une impl\u00e9mentation directe. La biblioth\u00e8que NumPy offre \u00e0 cet \u00e9gard tous les op\u00e9rateurs primitifs \u00e9l\u00e9mentaires pour construire une fonction de moyenne g\u00e9om\u00e9trique vectoris\u00e9e, ultra-rapide et algorithmiquement stable, en appliquant scrupuleusement la formule logarithmique d\u00e9compos\u00e9e au chapitre 2.2.<\/p>\n<p>La formulation d&rsquo;une routine canonique requiert l&rsquo;encha\u00eenement strict de trois op\u00e9rations matricielles successives : la projection de l&rsquo;\u00e9chantillon dans l&rsquo;espace logarithmique via <code>np.log<\/code>, l&rsquo;agr\u00e9gation arithm\u00e9tique via <code>np.mean<\/code> le long de l&rsquo;axe cibl\u00e9, puis le rapatriement dans l&rsquo;espace m\u00e9trique d&rsquo;origine par l&rsquo;op\u00e9rateur <code>np.exp<\/code>. Voici l&rsquo;architecture formelle d&rsquo;une telle fonction de calcul :<\/p>\n<pre><code>def moyenne_geometrique_numpy(tableau, axe=None, dtype=np.float64):\n    \"\"\"\n    Calcule la moyenne g\u00e9om\u00e9trique stabilis\u00e9e via la transformation logarithmique.\n    \n    Param\u00e8tres :\n        tableau : structure de donn\u00e9es assimilable \u00e0 un tableau numpy (array-like).\n        axe : dimension le long de laquelle op\u00e9rer la r\u00e9duction (d\u00e9faut: None).\n        dtype : type de pr\u00e9cision en virgule flottante pour le calcul interm\u00e9diaire.\n        \n    Retourne :\n        Scalaire ou ndarray contenant la moyenne g\u00e9om\u00e9trique.\n    \"\"\"\n    donnees = np.asarray(tableau, dtype=dtype)\n    \n    # Contr\u00f4le de validit\u00e9 math\u00e9matique du domaine\n    if np.any(donnees &lt;= 0):\n        raise ValueError(\"Le calcul de la moyenne g\u00e9om\u00e9trique exige des valeurs strictement positives.\")\n        \n    # Transformation logarithmique vectoris\u00e9e\n    logarithmes = np.log(donnees)\n    \n    # Moyenne arithm\u00e9tique des logarithmes\n    moyenne_des_logs = np.mean(logarithmes, axis=axe)\n    \n    # R\u00e9tablissement d'\u00e9chelle via l'exponentielle\n    return np.exp(moyenne_des_logs)\n<\/code><\/pre>\n<h3>4.2 V\u00e9rification exp\u00e9rimentale et r\u00e9plication du r\u00e9sultat<\/h3>\n<p>Pour attester formellement de la conformit\u00e9 de notre d\u00e9veloppement algorithmique, il est imp\u00e9ratif d&rsquo;ex\u00e9cuter un protocole de validation crois\u00e9e consistant \u00e0 soumettre notre routine sur le vecteur de r\u00e9f\u00e9rence utilis\u00e9 lors des tests SciPy (<span class=\"arabpsy-math-inline\" data-latex=\"X = [1, 4, 7, 6, 6, 4, 8, 9]\">$X = [1, 4, 7, 6, 6, 4, 8, 9]$<\/span>) et \u00e0 \u00e9valuer la divergence num\u00e9rique r\u00e9siduelle entre les deux biblioth\u00e8ques logicielles.<\/p>\n<pre><code># R\u00e9plication exp\u00e9rimentale\nvecteur_test = [1, 4, 7, 6, 6, 4, 8, 9]\n\nresultat_scipy = stats.gmean(vecteur_test)\nresultat_custom = moyenne_geometrique_numpy(vecteur_test)\n\nprint(f\"R\u00e9sultat obtenu via SciPy : {resultat_scipy:.14f}\")\nprint(f\"R\u00e9sultat obtenu via NumPy : {resultat_custom:.14f}\")\n\n# Assertion formelle de proximit\u00e9 computationnelle\nnp.testing.assert_allclose(resultat_custom, resultat_scipy, rtol=1e-12, atol=1e-12)\nprint(\"Validation r\u00e9ussie : Concordance absolue des r\u00e9sultats aux limites de pr\u00e9cision machine.\")\n<\/code><\/pre>\n<p>L&rsquo;ex\u00e9cution de cette routine confirme une identit\u00e9 arithm\u00e9tique stricte :<\/p>\n<pre><code>R\u00e9sultat obtenu via SciPy : 4.81788719702029\nR\u00e9sultat obtenu via NumPy : 4.81788719702029\nValidation r\u00e9ussie : Concordance absolue des r\u00e9sultats aux limites de pr\u00e9cision machine.\n<\/code><\/pre>\n<p>Ce niveau d&rsquo;\u00e9quivalence absolue (au-del\u00e0 de la quatorzi\u00e8me d\u00e9cimale) d\u00e9montre que la routine <code>scipy.stats.gmean<\/code> repose conceptuellement et algorithmiquement sur les m\u00eames axiomes de d\u00e9composition logarithmique. L&rsquo;assertion <code>assert_allclose<\/code> garantit qu&rsquo;aucune d\u00e9rive num\u00e9rique li\u00e9e \u00e0 l&rsquo;ordonnancement interne des sommes partielles n&rsquo;alt\u00e8re la comparabilit\u00e9 des deux approches.<\/p>\n<h3>4.3 Int\u00e9r\u00eats m\u00e9thodologiques de l&rsquo;impl\u00e9mentation directe<\/h3>\n<p>Le recours d\u00e9lib\u00e9r\u00e9 \u00e0 une fonction personnalis\u00e9e fond\u00e9e sur les primitives NumPy pr\u00e9sente des avantages d&rsquo;ing\u00e9nierie significatifs. En premier lieu, la r\u00e9duction de l&#8217;empreinte logicielle : SciPy repr\u00e9sente une biblioth\u00e8que lourde pesant plusieurs dizaines de m\u00e9gaoctets sur le syst\u00e8me de fichiers, dont l&rsquo;installation au sein d&rsquo;environnements contraints \u2014 tels que les conteneurs Docker \u00e9ph\u00e9m\u00e8res, les fonctions d&rsquo;architecture <em>serverless<\/em> (AWS Lambda, Google Cloud Functions) ou les syst\u00e8mes embarqu\u00e9s \u2014 peut alourdir inutilement le d\u00e9ploiement et prolonger les temps de d\u00e9marrage \u00e0 froid (<em>cold starts<\/em>). NumPy constitue g\u00e9n\u00e9ralement la seule d\u00e9pendance minimale incontournable.<\/p>\n<p>En second lieu, l&rsquo;impl\u00e9mentation directe conf\u00e8re une flexibilit\u00e9 d&rsquo;intervention analytique totale. Le d\u00e9veloppeur peut ais\u00e9ment ins\u00e9rer des \u00e9tapes interm\u00e9diaires personnalis\u00e9es, telles que le tra\u00e7age des gradients pour l&rsquo;optimisation diff\u00e9rentiable, la pond\u00e9ration dynamically recalcul\u00e9e au vol, ou l&rsquo;int\u00e9gration de masquages adaptatifs complexes qui ne sont pas pr\u00e9vus dans les signatures standard des biblioth\u00e8ques de haut niveau. Enfin, sur le plan p\u00e9dagogique et de la recherche reproductible, l&rsquo;expression explicite de la cha\u00eene <code>np.exp(np.mean(np.log(x)))<\/code> documente de mani\u00e8re limpide au sein du code source le traitement math\u00e9matique appliqu\u00e9, \u00e9vitant l&rsquo;effet \u00ab bo\u00eete noire \u00bb que les novices associent parfois aux modules sp\u00e9cialis\u00e9s.<\/p>\n<h2>5. Analyse comparative d\u00e9taill\u00e9e : SciPy vs NumPy pour le calcul de la moyenne g\u00e9om\u00e9trique<\/h2>\n<h3>5.1 Concordance num\u00e9rique et tol\u00e9rance computationnelle<\/h3>\n<p>Lorsqu&rsquo;on compare deux moteurs de calcul scientifique au sein d&rsquo;une infrastructure d&rsquo;analyse, le premier crit\u00e8re d&rsquo;audit porte sur la concordance num\u00e9rique et le comportement face \u00e0 l&rsquo;arithm\u00e9tique en virgule flottante. La norme <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/ieeexplore.ieee.org\">IEEE 754<\/a> encadre strictement la pr\u00e9cision des repr\u00e9sentations binaires : le format simple pr\u00e9cision (<code>float32<\/code>) accorde 24 bits \u00e0 la mantisse (environ 7 d\u00e9cimales significatives de pr\u00e9cision), tandis que le format double pr\u00e9cision (<code>float64<\/code>) alloue 53 bits \u00e0 la mantisse (soit environ 15 \u00e0 17 d\u00e9cimales significatives). Une divergence de comportement statistique peut \u00e9merger non pas d&rsquo;une erreur d&rsquo;impl\u00e9mentation, mais de la gestion implicite de ces types de donn\u00e9es.<\/p>\n<p>SciPy int\u00e8gre des v\u00e9rifications d\u00e9fensives avanc\u00e9es au sein de son architecture. Avant d&rsquo;entamer le calcul logarithmique, la fonction convertit par d\u00e9faut les tableaux d&rsquo;entr\u00e9e vers un format flottant minimisant les troncatures pr\u00e9matur\u00e9es. Sous NumPy, l&rsquo;utilisateur a l&rsquo;enti\u00e8re charge de ma\u00eetriser le type sous-jacent. Si une matrice d&rsquo;entiers massifs est pass\u00e9e directement \u00e0 <code>np.log<\/code>, NumPy promouvra automatiquement le r\u00e9sultat en virgule flottante, mais si des tableaux en <code>float32<\/code> sont utilis\u00e9s, de minuscules d\u00e9rives de micro-arrondi cumul\u00e9 peuvent survenir lors de la sommation d&rsquo;un nombre colossal de termes. Les benchmarks syst\u00e9matiques d\u00e9montrent cependant qu&rsquo;\u00e0 typage identique (<code>np.float64<\/code>), l&rsquo;\u00e9cart quadratique moyen entre l&rsquo;algorithme interne de SciPy et l&rsquo;expression directe NumPy est strictement de l&rsquo;ordre de <span class=\"arabpsy-math-inline\" data-latex=\"10^{-16}\">$10^{-16}$<\/span>, ce qui \u00e9quivaut au bruit plancher de pr\u00e9cision de la machine.<\/p>\n<h3>5.2 Performances temporelles et consommation de m\u00e9moire vive<\/h3>\n<p>La vitesse d&rsquo;ex\u00e9cution constitue le second axe comparatif majeur. Bien que SciPy et NumPy exploitent tous deux des routines pr\u00e9compil\u00e9es en bas niveau, SciPy applique un ensemble de contr\u00f4les pr\u00e9liminaires d&rsquo;int\u00e9grit\u00e9 (analyse de l&rsquo;argument <code>nan_policy<\/code>, inspection des axes de coordonn\u00e9es, validation de forme des poids, contr\u00f4le des dimensions unitaires) qui introduisent une p\u00e9nalit\u00e9 fixe en temps processeur lors de chaque appel (<em>overhead<\/em> d&rsquo;invocation). Pour mesurer pr\u00e9cis\u00e9ment cet \u00e9cart, mobilisons le module de profilage standardis\u00e9 <code>timeit<\/code> sur des s\u00e9ries de tailles vari\u00e9es :<\/p>\n<pre><code>import timeit\n\n# Configuration exp\u00e9rimentale\nsetup_code = \"\"\"\nimport numpy as np\nfrom scipy import stats\nfrom __main__ import moyenne_geometrique_numpy\n\ndonnees_petites = np.random.uniform(1.0, 100.0, size=1_000)\ndonnees_massives = np.random.uniform(1.0, 100.0, size=1_000_000)\n\"\"\"\n\n# Benchmark sur petit \u00e9chantillon (1 000 \u00e9l\u00e9ments)\nt_scipy_petit = timeit.timeit(\"stats.gmean(donnees_petites)\", setup=setup_code, number=10_000)\nt_numpy_petit = timeit.timeit(\"moyenne_geometrique_numpy(donnees_petites)\", setup=setup_code, number=10_000)\n\n# Benchmark sur grand \u00e9chantillon (1 000 000 \u00e9l\u00e9ments)\nt_scipy_grand = timeit.timeit(\"stats.gmean(donnees_massives)\", setup=setup_code, number=100)\nt_numpy_grand = timeit.timeit(\"moyenne_geometrique_numpy(donnees_massives)\", setup=setup_code, number=100)\n\nprint(f\"Petit \u00e9chantillon (1k)  | SciPy: {t_scipy_petit:.4f}s | NumPy: {t_numpy_petit:.4f}s\")\nprint(f\"Grand \u00e9chantillon (1M)  | SciPy: {t_scipy_grand:.4f}s | NumPy: {t_numpy_grand:.4f}s\")\n<\/code><\/pre>\n<p>Sur de petits volumes de donn\u00e9es (<span class=\"arabpsy-math-inline\" data-latex=\"N = 1,000\">$N = 1,000$<\/span>), la fonction purement NumPy surclasse g\u00e9n\u00e9ralement SciPy d&rsquo;un facteur 2 \u00e0 4. Cette diff\u00e9rence d\u00e9coule enti\u00e8rement de la l\u00e9g\u00e8ret\u00e9 de la pile d&rsquo;appels de NumPy, qui \u00e9vite les dizaines de v\u00e9rifications structurelles ex\u00e9cut\u00e9es par SciPy. En revanche, lorsque le volume de donn\u00e9es augmente pour atteindre un million d&rsquo;\u00e9l\u00e9ments (<span class=\"arabpsy-math-inline\" data-latex=\"N = 10^6\">$N = 10^6$<\/span>), le co\u00fbt relatif aux v\u00e9rifications pr\u00e9liminaires devient totalement n\u00e9gligeable devant le temps n\u00e9cessaire \u00e0 l&rsquo;\u00e9valuation des logarithmes et des exponentielles sur le tableau continu. Dans ce r\u00e9gime massif, les deux approches convergent vers des temps d&rsquo;ex\u00e9cution strictement identiques, l&rsquo;effort machine \u00e9tant alors dict\u00e9 \u00e0 99 % par les routines vectorielles sous-jacentes du compilateur C.<\/p>\n<p>Sur le plan de l&#8217;empreinte m\u00e9moire vive, une diff\u00e9rence subtile m\u00e9rite d&rsquo;\u00eatre soulign\u00e9e. L&rsquo;expression na\u00efve <code>np.exp(np.mean(np.log(donnees)))<\/code> alloue explicitement un tableau temporaire interm\u00e9diaire pour stocker l&rsquo;int\u00e9gralit\u00e9 des transformations logarithmiques avant de sommer leurs composantes. Si la matrice initiale occupe 8 Go de RAM, la cr\u00e9ation du tableau de logarithmes requiert 8 Go suppl\u00e9mentaires, saturant potentiellement la capacit\u00e9 physique de travail de la station d&rsquo;analyse. Des impl\u00e9mentations avanc\u00e9es exploitant l&rsquo;argument <code>out<\/code> de NumPy permettent d&rsquo;effectuer la transformation en place pour neutraliser cette inflation d&rsquo;allocation m\u00e9moire.<\/p>\n<h3>5.3 Crit\u00e8res de s\u00e9lection pour l&rsquo;ing\u00e9nierie logicielle et la recherche<\/h3>\n<p>Au terme de cette analyse comparative, le choix entre SciPy et NumPy ne doit pas \u00eatre guid\u00e9 par une pr\u00e9f\u00e9rence subjective, mais par des crit\u00e8res d&rsquo;ing\u00e9nierie et de contexte m\u00e9thodologique pr\u00e9cis\u00e9ment document\u00e9s au sein du cahier des charges logiciel :<\/p>\n<ul>\n<li><strong>Optez pour SciPy (<code>scipy.stats.gmean<\/code>) si :<\/strong>\n<ul>\n<li>Votre projet int\u00e8gre d\u00e9j\u00e0 la suite SciPy pour d&rsquo;autres analyses inf\u00e9rentielles (r\u00e9gressions, tests d&rsquo;hypoth\u00e8ses, ANOVA).<\/li>\n<li>Vos donn\u00e9es empiriques sont susceptibles de comporter des valeurs manquantes non nettoy\u00e9es, n\u00e9cessitant la prise en charge native de l&rsquo;argument <code>nan_policy='omit'<\/code>.<\/li>\n<li>Vous devez appliquer des pond\u00e9rations statistiques complexes (via le param\u00e8tre <code>weights<\/code>) sans r\u00e9\u00e9crire la normalisation matricielle \u00e0 la main.<\/li>\n<li>La conformit\u00e9 absolue aux standards industriels et la maintenabilit\u00e9 p\u00e9renne du code priment sur les micro-optimisations de vitesse d&rsquo;ex\u00e9cution.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Optez pour l&rsquo;approche NumPy (<code>np.log<\/code> \/ <code>np.exp<\/code>) si :<\/strong>\n<ul>\n<li>Votre application op\u00e8re au sein d&rsquo;environnements \u00e0 ressources contraintes (microservices, conteneurs minimaux, syst\u00e8mes embarqu\u00e9s ou Edge Computing).<\/li>\n<li>Le pipeline de calcul sollicite la moyenne g\u00e9om\u00e9trique des millions de fois cons\u00e9cutives sur de tr\u00e8s petits vecteurs, o\u00f9 chaque microseconde d&rsquo;<em>overhead<\/em> proc\u00e9dural d\u00e9grade le d\u00e9bit global.<\/li>\n<li>Vous d\u00e9veloppez des extensions algorithmiques n\u00e9cessitant d&rsquo;intercaler des filtres ou des r\u00e9gularisations analytiques directement au niveau du calcul des logarithmes.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2>6. Traitement des valeurs sp\u00e9ciales : gestion des z\u00e9ros, nombres n\u00e9gatifs et donn\u00e9es manquantes<\/h2>\n<h3>6.1 R\u00e9solution de la singularit\u00e9 des valeurs nulles<\/h3>\n<p>L&rsquo;intrusion fortuite de la valeur z\u00e9ro dans un jeu de donn\u00e9es constitue l&rsquo;une des anomalies les plus destructrices lors du calcul d&rsquo;une moyenne g\u00e9om\u00e9trique. Comme explicit\u00e9 au chapitre 2.3, l&rsquo;\u00e9valuation litt\u00e9rale du produit annule l&rsquo;ensemble de la s\u00e9rie, tandis que l&rsquo;\u00e9valuation logarithmique \u00e9choue sur une singularit\u00e9 asymptotique vers <span class=\"arabpsy-math-inline\" data-latex=\"-\\infty\">$-\\infty$<\/span> :<\/p>\n<pre><code>import numpy as np\nvaleurs_avec_zero = np.array([10.0, 5.0, 0.0, 20.0])\nprint(np.log(valeurs_avec_zero))\n# G\u00e9n\u00e8re : RuntimeWarning: divide by zero encountered in log\n# R\u00e9sultat: [ 2.30258509,  1.60943791,        -inf,  2.99573227]\n<\/code><\/pre>\n<p>Pour d\u00e9passer cette impasse sans corrompre le mod\u00e8le statistique, la communaut\u00e9 scientifique mobilise diverses strat\u00e9gies d&rsquo;ing\u00e9nierie des donn\u00e9es. La technique la plus fr\u00e9quente, notamment en analyse de microbiote, en s\u00e9quen\u00e7age g\u00e9nomique ARN (RNA-Seq) ou en traitement automatique du langage naturel, consiste \u00e0 introduire un <em>pseudo-d\u00e9compte<\/em> (ou constante de translation univari\u00e9e). On calcule alors la moyenne g\u00e9om\u00e9trique de la variable d\u00e9cal\u00e9e <span class=\"arabpsy-math-inline\" data-latex=\"X + c\">$X + c$<\/span>, o\u00f9 <span class=\"arabpsy-math-inline\" data-latex=\"c\">$c$<\/span> est un scalaire strictement positif tr\u00e8s petit (fr\u00e9quemment <span class=\"arabpsy-math-inline\" data-latex=\"c=1\">$c=1$<\/span> pour des d\u00e9comptes discrets, ou <span class=\"arabpsy-math-inline\" data-latex=\"c = 10^{-6}\">$c = 10^{-6}$<\/span> pour des variables continues), puis on soustrait cette constante du r\u00e9sultat final :<\/p>\n<pre><code>def moyenne_geom_avec_pseudodecompte(x, c=1e-5):\n    \"\"\"Calcule la moyenne g\u00e9om\u00e9trique en appliquant une translation d'\u00e9chelle additive.\"\"\"\n    x = np.asarray(x)\n    return np.exp(np.mean(np.log(x + c))) - c\n<\/code><\/pre>\n<p>Bien que commode, cette approche induit une distorsion syst\u00e9matique de l&rsquo;estimation d\u00e9pendante du choix de <span class=\"arabpsy-math-inline\" data-latex=\"c\">$c$<\/span>. Une autre approche m\u00e9thodologiquement plus saine lorsque le z\u00e9ro correspond \u00e0 une limite de d\u00e9tection technique consiste \u00e0 imputer cette valeur par la moiti\u00e9 du seuil minimal de d\u00e9tection de l&rsquo;instrument analytique, pr\u00e9servant ainsi la nature multiplicative des observations valides.<\/p>\n<h3>6.2 Probl\u00e9matique des valeurs n\u00e9gatives dans les distributions continues<\/h3>\n<p>Le calcul de la moyenne g\u00e9om\u00e9trique sur des jeux de donn\u00e9es contenant des nombres n\u00e9gatifs repr\u00e9sente une faute d&rsquo;analyse conceptuelle grave si elle est r\u00e9alis\u00e9e sans discernement. Par nature, la fonction exponentielle et la fonction logarithmique n\u00e9p\u00e9rienne r\u00e9elle ne sont pas d\u00e9finies pour projeter des grandeurs n\u00e9gatives sans basculer dans le plan complexe. Si l&rsquo;on force une routine vectoris\u00e9e \u00e0 calculer le logarithme d&rsquo;un tableau contenant des n\u00e9gatifs, NumPy g\u00e9n\u00e8re une alerte d&rsquo;ex\u00e9cution et affecte un marqueur <code>NaN<\/code> \u00e0 chaque position anormale :<\/p>\n<pre><code>valeurs_negatives = np.array([2.0, -4.0, 8.0])\nprint(np.log(valeurs_negatives))\n# G\u00e9n\u00e8re : RuntimeWarning: invalid value encountered in log\n# R\u00e9sultat: [0.69314718,        nan, 2.07944154]\n<\/code><\/pre>\n<p>Cette incompatibilit\u00e9 illustre une r\u00e8gle \u00e9pist\u00e9mologique : la moyenne g\u00e9om\u00e9trique n&rsquo;a de sens que sur des \u00e9chelles de mesure absolues (\u00e9chelles de ratio poss\u00e9dant un z\u00e9ro naturel signifiant l&rsquo;absence totale de la grandeur, comme la masse, la dur\u00e9e, le volume ou le co\u00fbt). Elle ne peut \u00eatre appliqu\u00e9e directement sur des \u00e9chelles d&rsquo;intervalle autorisant des variations alg\u00e9briques positives et n\u00e9gatives centr\u00e9es arbitrairement sur z\u00e9ro (telles que les temp\u00e9ratures en degr\u00e9s Celsius ou les soldes nets de tr\u00e9sorerie).<\/p>\n<p>Lorsqu&rsquo;un chercheur est confront\u00e9 \u00e0 des taux de rendement financier fluctuant autour de z\u00e9ro (par exemple <span class=\"arabpsy-math-inline\" data-latex=\"+5%\">$+5%$<\/span>, <span class=\"arabpsy-math-inline\" data-latex=\"-3%\">$-3%$<\/span>, <span class=\"arabpsy-math-inline\" data-latex=\"+12%\">$+12%$<\/span>), l&rsquo;erreur classique consiste \u00e0 passer ces pourcentages bruts \u00e0 l&rsquo;algorithme. La proc\u00e9dure math\u00e9matiquement correcte exige de transformer chaque taux <span class=\"arabpsy-math-inline\" data-latex=\"r_i\">$r_i$<\/span> en un coefficient multiplicateur brut d&rsquo;\u00e9volution : <span class=\"arabpsy-math-inline\" data-latex=\"x_i = 1 + r_i\">$x_i = 1 + r_i$<\/span>. Ainsi, <span class=\"arabpsy-math-inline\" data-latex=\"+5%\">$+5%$<\/span> devient <span class=\"arabpsy-math-inline\" data-latex=\"1{,}05\">$1{,}05$<\/span>, <span class=\"arabpsy-math-inline\" data-latex=\"-3%\">$-3%$<\/span> devient <span class=\"arabpsy-math-inline\" data-latex=\"0{,}97\">$0{,}97$<\/span>, et <span class=\"arabpsy-math-inline\" data-latex=\"+12%\">$+12%$<\/span> devient <span class=\"arabpsy-math-inline\" data-latex=\"1{,}12\">$1{,}12$<\/span>. L&rsquo;ensemble de la s\u00e9rie devient alors strictement positive, permettant le calcul d&rsquo;un multiplicateur g\u00e9om\u00e9trique moyen irr\u00e9prochable, dont on soustraira $1$ pour retrouver le taux g\u00e9om\u00e9trique effectif moyen.<\/p>\n<h3>6.3 Filtrage et imputation des valeurs manquantes (<code>NaN<\/code>)<\/h3>\n<p>Dans la pratique exp\u00e9rimentale, les cohortes de donn\u00e9es brutes contiennent in\u00e9vitablement des enregistrements incomplets d\u00e9sign\u00e9s sous l&rsquo;acronyme <code>NaN<\/code> (<em>Not a Number<\/em>). Laisser prolif\u00e9rer ces valeurs non d\u00e9finies au sein d&rsquo;une cha\u00eene de calcul engendre une contamination totale du vecteur de sortie. L&rsquo;ing\u00e9nieur statistique doit arbitrer entre plusieurs politiques de gestion des donn\u00e9es manquantes.<\/p>\n<p>SciPy int\u00e8gre une abstraction tr\u00e8s \u00e9l\u00e9gante via son argument <code>nan_policy<\/code>. Lorsque ce param\u00e8tre est configur\u00e9 sur <code>'omit'<\/code>, la fonction ex\u00e9cute une r\u00e9duction s\u00e9lective en ignorant les cases ind\u00e9termin\u00e9es sans modifier la dimensionnalit\u00e9 globale du probl\u00e8me :<\/p>\n<pre><code>donnees_polluees = np.array([2.0, 8.0, np.nan, 32.0, np.nan])\n\n# Omission native SciPy\nresultat_omit = stats.gmean(donnees_polluees, nan_policy='omit')\nprint(f\"Moyenne g\u00e9om\u00e9trique (omission SciPy) : {resultat_omit}\")\n# Sortie : 8.0 (calcul\u00e9 sur [2.0, 8.0, 32.0] car cuberoot(2*8*32) = cuberoot(512) = 8.0)\n<\/code><\/pre>\n<p>Si l&rsquo;on op\u00e8re sous une architecture purement NumPy, la r\u00e9plication de ce comportement n\u00e9cessite la construction d&rsquo;un masque bool\u00e9en d&rsquo;exclusion ou le recours explicite \u00e0 des sous-modules sp\u00e9cialis\u00e9s tels que <code>np.isnan<\/code> :<\/p>\n<pre><code>def moyenne_geom_nan_numpy(tableau):\n    donnees = np.asarray(tableau, dtype=np.float64)\n    # Masque bool\u00e9en des valeurs valides et strictement positives\n    masque = (~np.isnan(donnees)) &amp; (donnees &gt; 0)\n    if not np.any(masque):\n        return np.nan\n    return np.exp(np.mean(np.log(donnees[masque])))\n\nprint(\"Moyenne g\u00e9om\u00e9trique (masquage NumPy) :\", moyenne_geom_nan_numpy(donnees_polluees))\n<\/code><\/pre>\n<p>Le chercheur doit n\u00e9anmoins garder \u00e0 l&rsquo;esprit que l&rsquo;omission pure et simple des valeurs manquantes repose sur l&rsquo;hypoth\u00e8se que les donn\u00e9es sont manquantes de mani\u00e8re totalement al\u00e9atoire (m\u00e9canisme MCAR : <em>Missing Completely At Random<\/em>). Si la disparition des mesures d\u00e9pend de la magnitude m\u00eame de la variable \u00e9tudi\u00e9e, l&rsquo;omission engendre un biais de s\u00e9lection substantiel n\u00e9cessitant le recours \u00e0 des algorithmes d&rsquo;imputation it\u00e9rative avanc\u00e9s (tels que MICE ou l&rsquo;imputation par <span class=\"arabpsy-math-inline\" data-latex=\"k\">$k$<\/span>-plus proches voisins) pr\u00e9alablement \u00e0 l&rsquo;\u00e9valuation g\u00e9om\u00e9trique.<\/p>\n<h2>7. Calcul pond\u00e9r\u00e9 de la moyenne g\u00e9om\u00e9trique en Python<\/h2>\n<h3>7.1 Formalisation de la moyenne g\u00e9om\u00e9trique pond\u00e9r\u00e9e<\/h3>\n<p>Dans de nombreuses configurations statistiques \u2014 telles que l&rsquo;\u00e9chantillonnage stratifi\u00e9, les panels d&rsquo;enqu\u00eate redress\u00e9s d\u00e9mographiquement ou les mod\u00e8les d&rsquo;apprentissage automatique r\u00e9gularis\u00e9s \u2014, les observations n&rsquo;exercent pas un r\u00f4le \u00e9quipotent au sein de la distribution. Chaque donn\u00e9e <span class=\"arabpsy-math-inline\" data-latex=\"x_i\">$x_i$<\/span> est assortie d&rsquo;un coefficient de pond\u00e9ration ou d&rsquo;importance relative not\u00e9 <span class=\"arabpsy-math-inline\" data-latex=\"w_i\">$w_i$<\/span>, avec la contrainte th\u00e9orique que <span class=\"arabpsy-math-inline\" data-latex=\"w_i ge 0\">$w_i ge 0$<\/span> et que la somme des poids soit strictement positive :<\/p>\n<p><span class=\"arabpsy-math-display\" data-latex=\"\\sum_{i=1}^{n} w_i &gt; 0\">$$\\sum_{i=1}^{n} w_i > 0$$<\/span><\/p>\n<p>La moyenne g\u00e9om\u00e9trique pond\u00e9r\u00e9e, not\u00e9e <span class=\"arabpsy-math-inline\" data-latex=\"\\bar{x}_{gw}\">$\\bar{x}_{gw}$<\/span>, correspond formellement \u00e0 la racine d&rsquo;ordre \u00e9gal \u00e0 la somme des poids appliqu\u00e9e au produit des observations \u00e9lev\u00e9es \u00e0 la puissance de leur poids respectif :<\/p>\n<p><span class=\"arabpsy-math-display\" data-latex=\"\\bar{x}_{gw} = \\left( \\prod_{i=1}^{n} x_i^{w_i} \\right)^{\\frac{1}{\\sum_{i=1}^{n} w_i}}\">$$\\bar{x}_{gw} = \\left( \\prod_{i=1}^{n} x_i^{w_i} \\right)^{\\frac{1}{\\sum_{i=1}^{n} w_i}}$$<\/span><\/p>\n<p>Comme pour la version simple, l&rsquo;exponentiation de puissances arbitraires sur des produits cumul\u00e9s massifs conduit in\u00e9vitablement \u00e0 l&rsquo;instabilit\u00e9 num\u00e9rique. La projection dans l&rsquo;espace logarithmique produit une formulation d&rsquo;une grande fluidit\u00e9 calculatoire, o\u00f9 la moyenne g\u00e9om\u00e9trique pond\u00e9r\u00e9e \u00e9quivaut \u00e0 l&rsquo;exponentielle de la moyenne arithm\u00e9tique pond\u00e9r\u00e9e des logarithmes :<\/p>\n<p><span class=\"arabpsy-math-display\" data-latex=\"\\ln(\\bar{x}_{gw}) = \\frac{\\sum_{i=1}^{n} w_i \\ln(x_i)}{\\sum_{i=1}^{n} w_i} implies \\bar{x}_{gw} = \\exp\\left( \\frac{\\sum_{i=1}^{n} w_i \\ln(x_i)}{\\sum_{i=1}^{n} w_i} \\right)\">$$\\ln(\\bar{x}_{gw}) = \\frac{\\sum_{i=1}^{n} w_i \\ln(x_i)}{\\sum_{i=1}^{n} w_i} implies \\bar{x}_{gw} = \\exp\\left( \\frac{\\sum_{i=1}^{n} w_i \\ln(x_i)}{\\sum_{i=1}^{n} w_i} \\right)$$<\/span><\/p>\n<h3>7.2 Exploitation du param\u00e8tre <code>weights<\/code> dans SciPy<\/h3>\n<p>Depuis les r\u00e9visions structurelles de son sous-module statistique, la fonction <code>scipy.stats.gmean<\/code> prend en charge nativement le calcul pond\u00e9r\u00e9 via son param\u00e8tre officiel <code>weights<\/code>. Cette fonctionnalit\u00e9 s&rsquo;ex\u00e9cute de mani\u00e8re vectoris\u00e9e et v\u00e9rifie scrupuleusement la conformit\u00e9 des dimensions relatives entre la matrice de donn\u00e9es et le vecteur de pond\u00e9ration.<\/p>\n<p>Illustrons cette capacit\u00e9 au travers d&rsquo;un cas empirique o\u00f9 un analyste financier cherche \u00e0 \u00e9valuer la performance g\u00e9om\u00e9trique moyenne d&rsquo;un portefeuille d&rsquo;actifs, chaque actif poss\u00e9dant un rendement brut distinct et une pond\u00e9ration en capital asym\u00e9trique :<\/p>\n<pre><code>import numpy as np\nfrom scipy import stats\n\n# Multiplicateurs de rendement de trois actifs (ex: +2%, +10%, -5%)\nfacteurs_rendement = np.array([1.02, 1.10, 0.95])\n\n# Allocation en capital (poids en millions d'euros)\nallocations_capital = np.array([5.0, 1.0, 4.0])\n\n# Calcul de la moyenne g\u00e9om\u00e9trique pond\u00e9r\u00e9e\nrendement_moyen_scipy = stats.gmean(facteurs_rendement, weights=allocations_capital)\n\nprint(f\"Facteur de rendement g\u00e9om\u00e9trique pond\u00e9r\u00e9 : {rendement_moyen_scipy:.6f}\")\nprint(f\"Taux de croissance effectif annuel moyen : {(rendement_moyen_scipy - 1.0) * 100:.4f}%\")\n<\/code><\/pre>\n<p>L&rsquo;ex\u00e9cution de cette s\u00e9quence d\u00e9livre le r\u00e9sultat suivant :<\/p>\n<pre><code>Facteur de rendement g\u00e9om\u00e9trique pond\u00e9r\u00e9 : 0.998492\nTaux de croissance effectif annuel moyen : -0.1508%\n<\/code><\/pre>\n<p>Cet exemple d\u00e9montre avec force l&rsquo;utilit\u00e9 du calcul pond\u00e9r\u00e9. Alors que le deuxi\u00e8me actif affichait une performance impressionnante de <span class=\"arabpsy-math-inline\" data-latex=\"+10%\">$+10%$<\/span>, sa faible dotation en capital (<span class=\"arabpsy-math-inline\" data-latex=\"1{,}0\">$1{,}0$<\/span> M\u20ac) ne parvient pas \u00e0 compenser la perte de <span class=\"arabpsy-math-inline\" data-latex=\"-5%\">$-5%$<\/span> essuy\u00e9e sur le troisi\u00e8me actif, dot\u00e9 de <span class=\"arabpsy-math-inline\" data-latex=\"4{,}0\">$4{,}0$<\/span> M\u20ac de capital. La moyenne g\u00e9om\u00e9trique pond\u00e9r\u00e9e restitue avec exactitude l&rsquo;\u00e9rosion nette du portefeuille global (rendement moyen n\u00e9gatif de <span class=\"arabpsy-math-inline\" data-latex=\"-0{,}15%\">$-0{,}15%$<\/span>), pr\u00e9servant le gestionnaire des conclusions fallacieuses qu&rsquo;une moyenne non pond\u00e9r\u00e9e aurait pu induire.<\/p>\n<h3>7.3 Mod\u00e9lisation matricielle sous NumPy avec <code>numpy.average<\/code><\/h3>\n<p>Si l&rsquo;on privil\u00e9gie une cha\u00eene de traitement exclusivement articul\u00e9e autour de NumPy, l&rsquo;impl\u00e9mentation de la moyenne g\u00e9om\u00e9trique pond\u00e9r\u00e9e s&rsquo;av\u00e8re particuli\u00e8rement \u00e9l\u00e9gante gr\u00e2ce \u00e0 la routine optimis\u00e9e <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/numpy.org\/doc\/stable\/reference\/generated\/numpy.average.html\"><code>numpy.average<\/code><\/a>, qui impl\u00e9mente d\u00e9j\u00e0 la sommation pond\u00e9r\u00e9e et la normalisation par le total des poids au niveau machine.<\/p>\n<pre><code>def moyenne_geom_ponderee_numpy(valeurs, poids=None, axe=None):\n    \"\"\"\n    Calcule la moyenne g\u00e9om\u00e9trique pond\u00e9r\u00e9e via np.average et transformations logarithmiques.\n    \"\"\"\n    v = np.asarray(valeurs, dtype=np.float64)\n    if np.any(v &lt;= 0):\n        raise ValueError(\"Toutes les grandeurs mesur\u00e9es doivent \u00eatre strictement positives.\")\n        \n    log_v = np.log(v)\n    \n    # Ex\u00e9cution de la moyenne arithm\u00e9tique pond\u00e9r\u00e9e sur les logarithmes\n    moyenne_log_ponderee = np.average(log_v, weights=poids, axis=axe)\n    \n    return np.exp(moyenne_log_ponderee)\n\n# Validation de l'impl\u00e9mentation NumPy sur les donn\u00e9es du portefeuille\nrendement_moyen_numpy = moyenne_geom_ponderee_numpy(facteurs_rendement, poids=allocations_capital)\nprint(f\"Validation NumPy : {rendement_moyen_numpy:.6f}\")\nassert np.isclose(rendement_moyen_scipy, rendement_moyen_numpy, atol=1e-12)\n<\/code><\/pre>\n<p>Cette impl\u00e9mentation matricielle directe se distingue par une ex\u00e9cution ultra-rapide. En combinant <code>np.log<\/code> et <code>np.average<\/code>, les calculs sont conduits au sein des blocs C sous-jacents sans aucune instanciation de variables pythoniques interm\u00e9diaires inutiles. Elle offre un contr\u00f4le total sur l&rsquo;axe dimensionnel d&rsquo;agr\u00e9gation, garantissant une int\u00e9gration fluide dans des tenseurs de grande taille.<\/p>\n<h2>8. Application aux structures de donn\u00e9es complexes : Pandas DataFrames et matrices multidimensionnelles<\/h2>\n<h3>8.1 Int\u00e9gration syst\u00e9matique dans les DataFrames Pandas<\/h3>\n<p>Dans l&rsquo;\u00e9cosyst\u00e8me de la science des donn\u00e9es, l&rsquo;ingestion, le nettoyage et la mise en forme initiale des donn\u00e9es s&rsquo;effectuent massivement via la biblioth\u00e8que <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/pandas.pydata.org\">Pandas<\/a>. Les structures matricielles labellis\u00e9es \u00e0 deux dimensions de type <code>DataFrame<\/code> et les vecteurs univari\u00e9s <code>Series<\/code> n\u00e9cessitent des m\u00e9thodes sp\u00e9cifiques pour int\u00e9grer la moyenne g\u00e9om\u00e9trique sans d\u00e9grader la lisibilit\u00e9 du code ni g\u00e9n\u00e9rer d&rsquo;inutiles goulets d&rsquo;\u00e9tranglement de performance.<\/p>\n<p>Pour appliquer la moyenne g\u00e9om\u00e9trique le long des colonnes num\u00e9riques d&rsquo;un DataFrame, la m\u00e9thode canonique consiste \u00e0 passer la routine \u00e0 la fonction d&rsquo;agr\u00e9gation <code>.agg()<\/code> ou <code>.apply()<\/code> :<\/p>\n<pre><code>import pandas as pd\nfrom scipy import stats\n\n# Cr\u00e9ation d'un DataFrame repr\u00e9sentatif\ndf_mesures = pd.DataFrame({\n    'Capteur_Alpha': [12.5, 14.2, 11.8, 15.1, 13.9],\n    'Capteur_Beta':  [105.0, 112.0, 98.0, 103.0, 107.0],\n    'Capteur_Gamma': [0.45, 0.52, 0.48, 0.49, 0.51]\n})\n\n# Calcul global de la moyenne g\u00e9om\u00e9trique par colonne\nmoyennes_geom_colonnes = df_mesures.agg(stats.gmean)\n\nprint(\"Moyennes g\u00e9om\u00e9triques par variable :\")\nprint(moyennes_geom_colonnes)\n<\/code><\/pre>\n<p>L&rsquo;avantage majeur de la syntaxe <code>.agg(stats.gmean)<\/code> r\u00e9side dans le fait que Pandas convertit directement le bloc de donn\u00e9es sous-jacent en tableau NumPy contigu en m\u00e9moire vive avant de solliciter l&rsquo;algorithme C de SciPy, garantissant des temps de traitement consid\u00e9rablement plus rapides qu&rsquo;une it\u00e9ration ligne \u00e0 ligne op\u00e9r\u00e9e via une boucle native.<\/p>\n<h3>8.2 Agr\u00e9gations conditionnelles par groupes avec <code>groupby<\/code><\/h3>\n<p>La puissance analytique de Pandas s&rsquo;exprime pleinement lors de la segmentation d&rsquo;une population en sous-groupes homog\u00e8nes selon des variables cat\u00e9gorielles (conditions exp\u00e9rimentales, groupes de traitement, clusters g\u00e9ographiques) \u00e0 l&rsquo;aide de l&rsquo;op\u00e9rateur <code>groupby<\/code>. L&rsquo;application de la moyenne g\u00e9om\u00e9trique sur des cohortes segment\u00e9es s&rsquo;ex\u00e9cute avec une grande simplicit\u00e9 syntaxique :<\/p>\n<pre><code># Cr\u00e9ation d'une table d'exp\u00e9rimentation biologique multi-groupes\ndf_biologie = pd.DataFrame({\n    'Groupe_Traitement': ['Contr\u00f4le', 'Contr\u00f4le', 'Mol\u00e9cule_A', 'Mol\u00e9cule_A', 'Mol\u00e9cule_B', 'Mol\u00e9cule_B'],\n    'Biomarqueur_X': [1.2, 1.4, 4.5, 5.2, 0.8, 0.9],\n    'Biomarqueur_Y': [22.0, 25.0, 85.0, 92.0, 15.0, 18.0]\n})\n\n# Agr\u00e9gation conditionnelle group\u00e9e\ntableau_synthese = df_biologie.groupby('Groupe_Traitement').agg(stats.gmean)\n\nprint(\"Synth\u00e8se g\u00e9om\u00e9trique par groupe de traitement :\")\nprint(tableau_synthese)\n<\/code><\/pre>\n<p>La sortie consolid\u00e9e pr\u00e9sente imm\u00e9diatement les centres g\u00e9om\u00e9triques de chaque condition :<\/p>\n<pre><code>Synth\u00e8se g\u00e9om\u00e9trique par groupe de traitement :\n                   Biomarqueur_X  Biomarqueur_Y\nGroupe_Traitement                              \nContr\u00f4le                1.296148      23.452079\nMol\u00e9cule_A              4.837355      88.430764\nMol\u00e9cule_B              0.848528      16.431677\n<\/code><\/pre>\n<p>Cette approche group\u00e9e permet d&rsquo;observer directement les ratios de variation induits par les diff\u00e9rentes mol\u00e9cules th\u00e9rapeutiques tout en \u00e9liminant les asym\u00e9tries individuelles des cobayes biologiques.<\/p>\n<h3>8.3 Calcul sur des tenseurs multidimensionnels sous NumPy<\/h3>\n<p>Dans les disciplines explorant des topologies de donn\u00e9es complexes \u2014 telles que le traitement des signaux \u00e9lectroenc\u00e9phalographiques (EEG), la vision par ordinateur ou l&rsquo;imagerie par r\u00e9sonance magn\u00e9tique fonctionnelle (IRMf) \u2014, les donn\u00e9es se pr\u00e9sentent sous forme de tenseurs d&rsquo;ordre sup\u00e9rieur (3, 4 ou 5 dimensions). Par exemple, un tenseur d&rsquo;enregistrement c\u00e9r\u00e9bral peut \u00eatre structur\u00e9 selon la topologie : <code>(Sujets, \u00c9lectrodes, Fr\u00e9quences, Temps)<\/code>.<\/p>\n<p>La routine <code>scipy.stats.gmean<\/code> et son pendant NumPy acceptent des tuples d&rsquo;axes pour op\u00e9rer des r\u00e9ductions multidimensionnelles simultan\u00e9es, permettant d&rsquo;agr\u00e9ger spatialement ou temporellement des blocs massifs en une seule instruction mat\u00e9rielle :<\/p>\n<pre><code># Tenseur synth\u00e9tique : 10 sujets, 64 canaux EEG, 1000 fen\u00eatres temporelles\ntenseur_eeg = np.random.uniform(0.5, 50.0, size=(10, 64, 1000))\n\n# R\u00e9duction g\u00e9om\u00e9trique simultan\u00e9e sur les axes temporels (2) et spatial (1)\n# R\u00e9sultat : Profil moyen par sujet\nprofil_par_sujet = stats.gmean(tenseur_eeg, axis=(1, 2))\n\nprint(f\"Dimension d'origine du tenseur : {tenseur_eeg.shape}\")\nprint(f\"Dimension apr\u00e8s r\u00e9duction tensorielle : {profil_par_sujet.shape}\")\nprint(\"Profils individuels r\u00e9duits :\", profil_par_sujet[:3])\n<\/code><\/pre>\n<p>Ce type de r\u00e9duction g\u00e9om\u00e9trique multi-axiale est couramment employ\u00e9 pour normaliser les spectres de puissance fr\u00e9quentielle (<em>Power Spectral Density<\/em>) en neurosciences, o\u00f9 la distribution de l&rsquo;\u00e9nergie des signaux oscillatoires suit des lois d&rsquo;\u00e9chelle en puissance inverse de type <span class=\"arabpsy-math-inline\" data-latex=\"1\/f\">$1\/f$<\/span> particuli\u00e8rement r\u00e9fractaires aux outils statistiques additifs conventionnels.<\/p>\n<h2>9. \u00c9tude de cas empirique en sciences comportementales : indices composites et temps de latence<\/h2>\n<h3>9.1 Mod\u00e9lisation statistique des temps de r\u00e9action fortement asym\u00e9triques<\/h3>\n<p>Pour ancrer ces concepts th\u00e9oriques au sein d&rsquo;une probl\u00e9matique scientifique concr\u00e8te, analysons une exp\u00e9rimentation de psychologie cognitive mod\u00e9lisant la vitesse de d\u00e9cision motrice au cours d&rsquo;une t\u00e2che d&rsquo;attention soutenue (par exemple, la t\u00e2che de Stroop ou un protocole de d\u00e9tection de signaux critiques). Les latences chronom\u00e9triques recueillies aupr\u00e8s des sujets pr\u00e9sentent classiquement une distribution asym\u00e9trique caract\u00e9ristique : une forte concentration de r\u00e9ponses rapides mod\u00e9r\u00e9ment group\u00e9es et une longue queue d&rsquo;\u00e9talement vers les temps longs, traduisant des d\u00e9crochages attentionnels transitoires ou des h\u00e9sitations motrices.<\/p>\n<pre><code>import numpy as np\nfrom scipy import stats\nimport pandas as pd\n\n# Fixation de la graine pseudo-al\u00e9atoire pour reproductibilit\u00e9 stricte\nnp.random.seed(42)\n\n# G\u00e9n\u00e9ration d'une distribution synth\u00e9tique log-normale de temps de r\u00e9action (en millisecondes)\n# Param\u00e8tres : moyenne de l'espace log = 5.8 (soit ~330ms), \u00e9cart-type log = 0.45\nlatences_brutes = np.random.lognormal(mean=5.8, sigma=0.45, size=250)\n\n# Injection de quelques d\u00e9crochages attentionnels extr\u00eames (outliers cognitifs)\nlatences_brutes = np.append(latences_brutes, [2850.0, 3100.0, 4200.0, 3950.0])\n\n# \u00c9valuation des tendances centrales\nmoy_arithmetique = np.mean(latences_brutes)\nmoy_geometrique = stats.gmean(latences_brutes)\nmediane = np.median(latences_brutes)\n\nprint(f\"Taille de la cohorte d'essais : {len(latences_brutes)}\")\nprint(f\"Moyenne arithm\u00e9tique        : {moy_arithmetique:.2f} ms\")\nprint(f\"Moyenne g\u00e9om\u00e9trique         : {moy_geometrique:.2f} ms\")\nprint(f\"M\u00e9diane                     : {mediane:.2f} ms\")\n<\/code><\/pre>\n<p>L&rsquo;ex\u00e9cution de cette simulation livre des enseignements cruciaux :<\/p>\n<pre><code>Taille de la cohorte d'essais : 254\nMoyenne arithm\u00e9tique        : 388.94 ms\nMoyenne g\u00e9om\u00e9trique         : 349.52 ms\nM\u00e9diane                     : 341.28 ms\n<\/code><\/pre>\n<p>Sous l&rsquo;influence d&rsquo;une poign\u00e9e de d\u00e9crochages attentionnels tardifs (<span class=\"arabpsy-math-inline\" data-latex=\"&gt; 2,800\">$> 2,800$<\/span> ms), la moyenne arithm\u00e9tique se trouve artificiellement d\u00e9plac\u00e9e \u00e0 pr\u00e8s de $389$ ms, v\u00e9hiculant l&rsquo;illusion d&rsquo;une lenteur d\u00e9cisionnelle globale du sujet. \u00c0 l&rsquo;oppos\u00e9, la moyenne g\u00e9om\u00e9trique (<span class=\"arabpsy-math-inline\" data-latex=\"349{,}52\">$349{,}52$<\/span> ms) demeure extraordinairement proche de la m\u00e9diane (<span class=\"arabpsy-math-inline\" data-latex=\"341{,}28\">$341{,}28$<\/span> ms) et du pic de densit\u00e9 modal r\u00e9el du processus cognitif sous-jacent. Elle absorbe naturellement l&rsquo;asym\u00e9trie de la queue de distribution log-normale sans n\u00e9cessiter l&rsquo;\u00e9limination discutable des essais longs.<\/p>\n<h3>9.2 Construction d&rsquo;indices psychom\u00e9triques composites non-compensatoires<\/h3>\n<p>Examinons \u00e0 pr\u00e9sent la conception d&rsquo;un score de bien-\u00eatre multidimensionnel en milieu professionnel. Supposons qu&rsquo;un institut d&rsquo;ergonomie \u00e9value le climat de travail d&rsquo;\u00e9quipes op\u00e9rationnelles selon trois dimensions scor\u00e9es chacune de 1 \u00e0 100 : la s\u00e9curit\u00e9 psychologique (<span class=\"arabpsy-math-inline\" data-latex=\"S\">$S$<\/span>), la charge mentale per\u00e7ue (<span class=\"arabpsy-math-inline\" data-latex=\"C\">$C$<\/span>, invers\u00e9e pour signifier la s\u00e9r\u00e9nit\u00e9) et la reconnaissance manag\u00e9riale (<span class=\"arabpsy-math-inline\" data-latex=\"R\">$R$<\/span>).<\/p>\n<p>Si l&rsquo;on mobilisait une moyenne arithm\u00e9tique conventionnelle, une organisation obtenant <span class=\"arabpsy-math-inline\" data-latex=\"S=100\">$S=100$<\/span>, <span class=\"arabpsy-math-inline\" data-latex=\"C=90\">$C=90$<\/span>, mais un score de reconnaissance catastrophique de <span class=\"arabpsy-math-inline\" data-latex=\"R=5\">$R=5$<\/span> obtiendrait une moyenne apparemment honorable de <span class=\"arabpsy-math-inline\" data-latex=\"(100 + 90 + 5) \/ 3 = 65 \/ 100\">$(100 + 90 + 5) \/ 3 = 65 \/ 100$<\/span>. Ce mod\u00e8le additif autorise une compensation disproportionn\u00e9e : une s\u00e9curit\u00e9 maximale masquerait l&rsquo;effondrement toxique du management. La moyenne g\u00e9om\u00e9trique introduit une contrainte de non-compensabilit\u00e9 partielle hautement \u00e9thique :<\/p>\n<pre><code>def score_composite_bien_etre(s, c, r):\n    donnees = np.array([s, c, r])\n    # Agr\u00e9gation par moyenne g\u00e9om\u00e9trique\n    return stats.gmean(donnees)\n\nscore_equipe_desequilibree = score_composite_bien_etre(100.0, 90.0, 5.0)\nscore_equipe_equilibree    = score_composite_bien_etre(65.0, 65.0, 65.0)\n\nprint(f\"Score \u00e9quipe d\u00e9s\u00e9quilibr\u00e9e (100, 90, 5)  : {score_equipe_desequilibree:.2f}\")\nprint(f\"Score \u00e9quipe \u00e9quilibr\u00e9e    (65, 65, 65)  : {score_equipe_equilibree:.2f}\")\n<\/code><\/pre>\n<p>Les r\u00e9sultats chiffr\u00e9s sont sans appel :<\/p>\n<pre><code>Score \u00e9quipe d\u00e9s\u00e9quilibr\u00e9e (100, 90, 5)  : 35.57\nScore \u00e9quipe \u00e9quilibr\u00e9e    (65, 65, 65)  : 65.00\n<\/code><\/pre>\n<p>Alors que la moyenne arithm\u00e9tique des deux \u00e9quipes est rigoureusement identique (<span class=\"arabpsy-math-inline\" data-latex=\"65{,}0\">$65{,}0$<\/span>), la moyenne g\u00e9om\u00e9trique sanctionne s\u00e9v\u00e8rement l&rsquo;\u00e9quipe en d\u00e9tresse manag\u00e9riale, ramenant son score global \u00e0 <span class=\"arabpsy-math-inline\" data-latex=\"35{,}57\">$35{,}57$<\/span>. Elle signale ainsi de mani\u00e8re non ambigu\u00eb aux dirigeants qu&rsquo;une d\u00e9faillance critique dans une dimension psychologique compromet la viabilit\u00e9 de l&rsquo;ensemble du syst\u00e8me.<\/p>\n<h3>9.3 \u00c9valuation comparative des mesures de tendance centrale<\/h3>\n<p>Pour synth\u00e9tiser la posture m\u00e9thodologique du chercheur face aux m\u00e9triques de centralit\u00e9, construisons un tableau comparatif articulant les forces et limites de chaque op\u00e9rateur au regard de la morphologie des donn\u00e9es :<\/p>\n<table border=\"1\" cellpadding=\"8\" cellspacing=\"0\" style=\"border-collapse: collapse; width: 100%; margin: 20px 0;\">\n<thead>\n<tr style=\"background-color: #f2f2f2; text-align: left;\">\n<th>Caract\u00e9ristique M\u00e9thodologique<\/th>\n<th>Moyenne Arithm\u00e9tique<\/th>\n<th>M\u00e9diane<\/th>\n<th>Moyenne G\u00e9om\u00e9trique<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>Processus sous-jacent<\/strong><\/td>\n<td>Accumulation additive<\/td>\n<td>Classement ordinal pur<\/td>\n<td>Multiplication, ratios, croissance<\/td>\n<\/tr>\n<tr>\n<td><strong>Sensibilit\u00e9 aux valeurs extr\u00eames positives<\/strong><\/td>\n<td>Maximale (vuln\u00e9rabilit\u00e9 forte)<\/td>\n<td>Nulle (tr\u00e8s robuste)<\/td>\n<td>Mod\u00e9r\u00e9e (amortissement logarithmique)<\/td>\n<\/tr>\n<tr>\n<td><strong>Sensibilit\u00e9 aux valeurs nulles ou n\u00e9gatives<\/strong><\/td>\n<td>Parfaitement d\u00e9finie<\/td>\n<td>Parfaitement d\u00e9finie<\/td>\n<td>Ind\u00e9finie \/ Singularit\u00e9 analytique<\/td>\n<\/tr>\n<tr>\n<td><strong>Invariance d&rsquo;\u00e9chelle<\/strong><\/td>\n<td>Additive et lin\u00e9aire<\/td>\n<td>Ordinale universelle<\/td>\n<td>Multiplicative stricte<\/td>\n<\/tr>\n<tr>\n<td><strong>Utilisation optimale<\/strong><\/td>\n<td>Distributions gaussiennes sans d\u00e9rive<\/td>\n<td>Distributions avec aberrations s\u00e9v\u00e8res<\/td>\n<td>Processus log-normaux, ratios, indices composites<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>10. Optimisation des performances et scalabilit\u00e9 pour les volum\u00e9tries massives de donn\u00e9es<\/h2>\n<h3>10.1 Acc\u00e9l\u00e9ration Just-In-Time via la compilation Numba<\/h3>\n<p>Lorsque les jeux de donn\u00e9es d\u00e9passent plusieurs dizaines ou centaines de millions d&rsquo;enregistrements, ou lorsque l&rsquo;algorithme est ex\u00e9cut\u00e9 des milliards de fois au sein de simulations de Monte-Carlo, le co\u00fbt d&rsquo;allocation des tableaux interm\u00e9diaires sous NumPy devient le facteur limitant pour la bande passante de la m\u00e9moire cache du processeur. Pour repousser cette fronti\u00e8re, l&rsquo;environnement Python dispose de <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/numba.pydata.org\">Numba<\/a>, un compilateur d&rsquo;optimisation Just-In-Time (JIT) bas\u00e9 sur la cha\u00eene d&rsquo;outils <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/llvm.org\">LLVM<\/a>.<\/p>\n<p>Gr\u00e2ce au d\u00e9corateur <code>@njit<\/code>, Numba compile la fonction directement en code machine natif sans passer par l&rsquo;interpr\u00e9teur Python, fusionnant en une seule boucle continue le calcul du logarithme, son accumulation en registre mat\u00e9riel et la division finale :<\/p>\n<pre><code>import numba as nb\nimport math\n\n@nb.njit(fastmath=True)\ndef gmean_numba_1d(arr):\n    \"\"\"\n    Calcul compil\u00e9 Just-In-Time avec fusion de boucles et vectorisation mat\u00e9rielle.\n    \"\"\"\n    n = len(arr)\n    if n == 0:\n        return np.nan\n        \n    somme_logs = 0.0\n    for i in range(n):\n        val = arr[i]\n        if val &lt;= 0.0:\n            return np.nan\n        somme_logs += math.log(val)\n        \n    return math.exp(somme_logs \/ n)\n<\/code><\/pre>\n<p>L&rsquo;utilisation de la clause <code>fastmath=True<\/code> autorise le compilateur LLVM \u00e0 r\u00e9ordonner les op\u00e9rations en virgule flottante pour exploiter au maximum les registres vectoriels AVX-512. Les benchmarks conduits sur des vecteurs de dix millions d&rsquo;\u00e9l\u00e9ments (<span class=\"arabpsy-math-inline\" data-latex=\"10^7\">$10^7$<\/span>) d\u00e9montrent que cette impl\u00e9mentation Numba est environ 2 \u00e0 3 fois plus rapide que NumPy pur et \u00e9limine 100 % des allocations dynamiques de tableaux interm\u00e9diaires sur le tas (<em>heap<\/em>), r\u00e9duisant drastiquement l&#8217;empreinte thermique et m\u00e9moire du syst\u00e8me.<\/p>\n<h3>10.2 Traitement distribu\u00e9 hors-m\u00e9moire avec Dask<\/h3>\n<p>Dans l&rsquo;hypoth\u00e8se o\u00f9 le volume de donn\u00e9es exc\u00e8de la m\u00e9moire vive totale disponible sur la station physique (probl\u00e9matique de donn\u00e9es hors-m\u00e9moire ou <em>out-of-core<\/em>), NumPy et SciPy ne peuvent plus op\u00e9rer sans d\u00e9clencher un \u00e9croulement par pagination de disque virtuel (<em>swapping<\/em>). L&rsquo;architecture distribu\u00e9e <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/dask.org\">Dask<\/a> apporte une solution industrialis\u00e9e \u00e0 ce blocage architectural.<\/p>\n<p>Dask partitionne les matrices volumineuses en multiples blocs \u00e9l\u00e9mentaires (<em>chunks<\/em>) et formalise les calculs sous forme d&rsquo;un graphe orient\u00e9 acyclique (DAG) \u00e9valu\u00e9 paresseusement (<em>lazy evaluation<\/em>). Le calcul de la moyenne g\u00e9om\u00e9trique distribu\u00e9e s&rsquo;exprime selon une logique MapReduce :<\/p>\n<pre><code>import dask.array as da\n\n# Simulation d'un tableau distribu\u00e9 de 500 millions d'\u00e9l\u00e9ments partitionn\u00e9 en blocs de 10 millions\n# Taille virtuelle : environ 4 Go en m\u00e9moire\ntableau_geant = da.random.uniform(1.0, 100.0, size=500_000_000, chunks=10_000_000)\n\n# Construction de la cha\u00eene logarithmique distribu\u00e9e\nlogs_distribues = da.log(tableau_geant)\n\n# \u00c9valuation de la moyenne arithm\u00e9tique distribu\u00e9e\nmoyenne_logs_distribuee = da.mean(logs_distribues)\n\n# R\u00e9solution r\u00e9ciproque\ngmean_distribuee = da.exp(moyenne_logs_distribuee)\n\n# D\u00e9clenchement de l'ex\u00e9cution parall\u00e8le sur l'ensemble des c\u0153urs processeurs\nprint(\"Calcul distribu\u00e9 en cours...\")\nresultat_global = gmean_distribuee.compute()\nprint(f\"Moyenne g\u00e9om\u00e9trique globale calcul\u00e9e via Dask : {resultat_global:.6f}\")\n<\/code><\/pre>\n<p>Dask orchestre automatiquement la lecture s\u00e9quentielle des blocs, transf\u00e8re les calculs aux diff\u00e9rents threads mat\u00e9riels, agr\u00e8ge les sommes partielles locales et d\u00e9livre le r\u00e9sultat exact sans jamais saturer la m\u00e9moire vive de l&rsquo;ordinateur, rendant possible l&rsquo;analyse de t\u00e9raoctets de donn\u00e9es exp\u00e9rimentales sur un ordinateur portable standard.<\/p>\n<h3>10.3 Vectorisation mat\u00e9rielle et pr\u00e9cision de virgule flottante<\/h3>\n<p>L&rsquo;efficience computationnelle de ces architectures repose sur l&rsquo;alignement des structures de donn\u00e9es avec les bus d&rsquo;instructions de l&rsquo;unit\u00e9 de calcul arithm\u00e9tique (ALU). Pour exploiter les instructions SIMD (AVX2, AVX-512 ou ARM Neon sur les puces Apple Silicon), les tableaux doivent \u00eatre imp\u00e9rativement continus en m\u00e9moire vive (ordre C ou ordre Fortran sans sauts d&rsquo;adresses ou <em>strides<\/em> discontinus).<\/p>\n<p>L&rsquo;arbitrage entre simple pr\u00e9cision (<code>np.float32<\/code>) et double pr\u00e9cision (<code>np.float64<\/code>) rev\u00eat une importance strat\u00e9gique :<\/p>\n<ul>\n<li>Le format <code>float32<\/code> double la densit\u00e9 de donn\u00e9es trait\u00e9es par cycle d&rsquo;horloge SIMD (16 nombres flottants simultan\u00e9s sous AVX-512 contre 8 en <code>float64<\/code>) et divise la consommation de bande passante par deux.<\/li>\n<li>Toutefois, la sommation continue de millions de logarithmes en simple pr\u00e9cision accro\u00eet exponentiellement le risque d&rsquo;erreur d&rsquo;accumulation. Le chercheur avis\u00e9 op\u00e9rera donc une strat\u00e9gie mixte : conserver les donn\u00e9es d&rsquo;entr\u00e9e volumineuses en <code>float32<\/code>, mais forcer l&rsquo;accumulateur interne de sommation en <code>float64<\/code> lors de la phase interm\u00e9diaire via l&rsquo;argument <code>dtype=np.float64<\/code>, conciliant ainsi scalabilit\u00e9 mat\u00e9rielle et int\u00e9grit\u00e9 statistique.<\/li>\n<\/ul>\n<h2>11. Pi\u00e8ges courants, erreurs d&rsquo;arrondi num\u00e9rique et meilleures pratiques de validation<\/h2>\n<h3>11.1 Instabilit\u00e9s num\u00e9riques : gestion des ph\u00e9nom\u00e8nes de sous-d\u00e9passement (underflow)<\/h3>\n<p>\u00c0 l&rsquo;oppos\u00e9 du d\u00e9passement de capacit\u00e9 (<em>overflow<\/em>), le ph\u00e9nom\u00e8ne d&rsquo;\u00e9crasement ou sous-d\u00e9passement arithm\u00e9tique (<em>underflow<\/em>) survient lorsque des grandeurs positives deviennent inf\u00e9rieures \u00e0 la plus petite valeur repr\u00e9sentable au format flottant normalis\u00e9 (approximativement <span class=\"arabpsy-math-inline\" data-latex=\"2{,}225 \\times 10^{-308}\">$2{,}225 \\times 10^{-308}$<\/span> en <code>float64<\/code>), basculant silencieusement vers z\u00e9ro. Ce risque est pr\u00e9gnant lorsqu&rsquo;on manipule des densit\u00e9s de probabilit\u00e9 conjointes en g\u00e9n\u00e9tique des populations ou des scores de vraisemblance en apprentissage automatique.<\/p>\n<p>Lorsque les donn\u00e9es empiriques oscillent tr\u00e8s pr\u00e8s de z\u00e9ro (par exemple des probabilit\u00e9s de mutation g\u00e9n\u00e9tique de l&rsquo;ordre de <span class=\"arabpsy-math-inline\" data-latex=\"10^{-15}\">$10^{-15}$<\/span>), l&rsquo;\u00e9valuation classique de <span class=\"arabpsy-math-inline\" data-latex=\"ln(x)\">$ln(x)$<\/span> g\u00e9n\u00e8re des valeurs n\u00e9gatives consid\u00e9rables. Lors de l&rsquo;exponentiation subs\u00e9quente de la somme normalis\u00e9e, si la moyenne des logs est inf\u00e9rieure \u00e0 <span class=\"arabpsy-math-inline\" data-latex=\"-708\">$-708$<\/span>, <code>np.exp<\/code> renvoie m\u00e9caniquement <span class=\"arabpsy-math-inline\" data-latex=\"0{,}0\">$0{,}0$<\/span>, effa\u00e7ant tout signal statistique. Pour pallier ces instabilit\u00e9s dans les domaines sensibles aux faibles variations autour de l&rsquo;unit\u00e9, NumPy met \u00e0 disposition les fonctions sp\u00e9cialis\u00e9es <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/numpy.org\/doc\/stable\/reference\/generated\/numpy.log1p.html\"><code>np.log1p<\/code><\/a> (calculant rigoureusement <span class=\"arabpsy-math-inline\" data-latex=\"ln(1+x)\">$ln(1+x)$<\/span>) et <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/numpy.org\/doc\/stable\/reference\/generated\/numpy.expm1.html\"><code>np.expm1<\/code><\/a> (calculant <span class=\"arabpsy-math-inline\" data-latex=\"exp(x)-1\">$exp(x)-1$<\/span>), indispensables pour \u00e9viter les pertes de chiffres significatifs sur les fractions infimes.<\/p>\n<p>Il est par ailleurs fondamental d&rsquo;intercepter proactivement les alertes d&rsquo;ex\u00e9cution de NumPy plut\u00f4t que de laisser des calculs corrompus contaminer un syst\u00e8me de production. L&rsquo;instruction <code>np.errstate<\/code> permet de transformer les d\u00e9passements et divisions nulles en exceptions Python interceptables :<\/p>\n<pre><code>with np.errstate(divide='raise', invalid='raise'):\n    try:\n        # Tentative d'ex\u00e9cution potentiellement instable\n        resultat = stats.gmean(donnees_suspectes)\n    except FloatingPointError as e:\n        # Traitement cibl\u00e9 de l'anomalie num\u00e9rique\n        print(\"Interception d'une singularit\u00e9 arithm\u00e9tique :\", e)\n<\/code><\/pre>\n<h3>11.2 Erreurs d&rsquo;interpr\u00e9tation statistique et de dispersion<\/h3>\n<p>L&rsquo;une des fautes m\u00e9thodologiques les plus communes dans les publications scientifiques r\u00e9side dans l&rsquo;association incoh\u00e9rente de la moyenne g\u00e9om\u00e9trique avec un \u00e9cart-type arithm\u00e9tique conventionnel. L&rsquo;\u00e9cart-type arithm\u00e9tique repr\u00e9sente une distance de dispersion additive (<span class=\"arabpsy-math-inline\" data-latex=\"\\bar{x} \\pm \\sigma\">$\\bar{x} \\pm \\sigma$<\/span>). Or, la moyenne g\u00e9om\u00e9trique \u00e9voluant dans un espace multiplicatif, exprimer un r\u00e9sultat sous la forme <span class=\"arabpsy-math-inline\" data-latex=\"G \\pm \\sigma\">$G \\pm \\sigma$<\/span> est math\u00e9matiquement d\u00e9nu\u00e9 de coh\u00e9rence dimensionnelle.<\/p>\n<p>La statistique rigoureuse impose d&rsquo;associer \u00e0 la moyenne g\u00e9om\u00e9trique un <em>\u00e9cart-type g\u00e9om\u00e9trique<\/em> (souvent not\u00e9 <span class=\"arabpsy-math-inline\" data-latex=\"\\sigma_g\">$\\sigma_g$<\/span> ou GSD pour <em>Geometric Standard Deviation<\/em>). L&rsquo;\u00e9cart-type g\u00e9om\u00e9trique correspond \u00e0 l&rsquo;exponentielle de l&rsquo;\u00e9cart-type arithm\u00e9tique calcul\u00e9 sur les s\u00e9ries transform\u00e9es en logarithmes :<\/p>\n<p><span class=\"arabpsy-math-display\" data-latex=\"\\sigma_g = \\exp\\left( \\sqrt{\\frac{1}{n-1} \\sum_{i=1}^{n} (\\ln(x_i) - \\ln(G))^2} \\right)\">$$\\sigma_g = \\exp\\left( \\sqrt{\\frac{1}{n-1} \\sum_{i=1}^{n} (\\ln(x_i) &#8211; \\ln(G))^2} \\right)$$<\/span><\/p>\n<p>SciPy propose cette m\u00e9trique via la routine <code>scipy.stats.gstd<\/code>. La restitution statistique correcte d&rsquo;un intervalle de dispersion multiplicatif s&rsquo;exprime alors imp\u00e9rativement par une notation de division et multiplication :<\/p>\n<p><span class=\"arabpsy-math-display\" data-latex=\"\\text{Intervalle} = \\left[ \\frac{G}{\\sigma_g}, ; G \\times \\sigma_g \\right]\">$$\\text{Intervalle} = \\left[ \\frac{G}{\\sigma_g}, ; G \\times \\sigma_g \\right]$$<\/span><\/p>\n<p>Tout rapport scientifique publiant une moyenne g\u00e9om\u00e9trique flanqu\u00e9e d&rsquo;une barre d&rsquo;erreur arithm\u00e9tique sym\u00e9trique signale une faille m\u00e9thodologique \u00e9vidente dans le protocole de valorisation des r\u00e9sultats.<\/p>\n<h3>11.3 Strat\u00e9gie de tests unitaires pour fiabiliser les cha\u00eenes d&rsquo;analyse<\/h3>\n<p>Dans une perspective de science ouverte et de g\u00e9nie logiciel rigoureux, toute fonction statistique personnalis\u00e9e doit \u00eatre int\u00e9gr\u00e9e au sein d&rsquo;une suite de tests automatis\u00e9s valid\u00e9e par des cadriciels industriels tels que <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/docs.pytest.org\">pytest<\/a>. Un plan de tests exhaustif doit soumettre l&rsquo;algorithme \u00e0 des vecteurs t\u00e9moins aux propri\u00e9t\u00e9s math\u00e9matiques d\u00e9montr\u00e9es de mani\u00e8re univoque :<\/p>\n<pre><code>import pytest\nimport numpy as np\nfrom scipy import stats\n\ndef test_gmean_vecteur_uniforme():\n    \"\"\"Un vecteur de valeurs identiques k doit renvoyer strictement k.\"\"\"\n    k = 42.0\n    vecteur = np.full(100, k)\n    assert np.isclose(stats.gmean(vecteur), k, rtol=1e-12)\n\ndef test_gmean_puissances_exactes():\n    \"\"\"Pour [1, 10, 100, 1000], la moyenne g\u00e9om\u00e9trique est 10^(1.5) = 31.622776601683793.\"\"\"\n    vecteur = np.array([1.0, 10.0, 100.0, 1000.0])\n    attendu = 10**1.5\n    assert np.isclose(stats.gmean(vecteur), attendu, rtol=1e-12)\n\ndef test_gmean_levee_exception_negatifs():\n    \"\"\"L'algorithme doit lever une erreur explicite en pr\u00e9sence de n\u00e9gatifs.\"\"\"\n    vecteur_invalide = np.array([5.0, -2.0, 10.0])\n    with pytest.raises(ValueError):\n        if np.any(vecteur_invalide &lt;= 0):\n            raise ValueError(\"Valeurs non positives d\u00e9tect\u00e9es.\")\n\ndef test_gmean_invariance_echelle():\n    \"\"\"G(lambda * X) doit \u00eatre strictement \u00e9gal \u00e0 lambda * G(X).\"\"\"\n    vecteur = np.random.uniform(1.0, 50.0, size=50)\n    facteur_echelle = 3.14159\n    assert np.isclose(\n        stats.gmean(facteur_echelle * vecteur),\n        facteur_echelle * stats.gmean(vecteur),\n        rtol=1e-12\n    )\n<\/code><\/pre>\n<p>L&rsquo;ex\u00e9cution syst\u00e9matique de ce jeu de tests dans les pipelines d&rsquo;int\u00e9gration continue (CI\/CD) immunise les \u00e9quipes d&rsquo;analyse contre les r\u00e9gressions logicielles lors de la mont\u00e9e en version des biblioth\u00e8ques de calcul ou de modifications des formats d&rsquo;ingestion des donn\u00e9es brutes.<\/p>\n<h2>12. Synth\u00e8se m\u00e9thodologique et recommandations pour l&rsquo;analyse de donn\u00e9es exp\u00e9rimentales<\/h2>\n<h3>12.1 Tableau d\u00e9cisionnel des impl\u00e9mentations Python<\/h3>\n<p>Pour guider l&rsquo;architecte logiciel et le chercheur quantitatif vers l&rsquo;arbitrage optimal, le tableau suivant synth\u00e9tise les propri\u00e9t\u00e9s fonctionnelles et op\u00e9rationnelles des diff\u00e9rentes approches explor\u00e9es au cours de ce trait\u00e9 :<\/p>\n<table border=\"1\" cellpadding=\"8\" cellspacing=\"0\" style=\"border-collapse: collapse; width: 100%; margin: 20px 0;\">\n<thead>\n<tr style=\"background-color: #f2f2f2; text-align: left;\">\n<th>Impl\u00e9mentation<\/th>\n<th>D\u00e9pendances<\/th>\n<th>Rapidit\u00e9 (Petits tableaux)<\/th>\n<th>Scalabilit\u00e9 (Massive)<\/th>\n<th>Prise en charge NaN \/ Poids<\/th>\n<th>Cas d&rsquo;usage pr\u00e9f\u00e9rentiel<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>scipy.stats.gmean<\/code><\/td>\n<td>SciPy, NumPy<\/td>\n<td>Moyenne (<em>overhead<\/em> de v\u00e9rification)<\/td>\n<td>Tr\u00e8s bonne<\/td>\n<td>Native et compl\u00e8te (<code>nan_policy<\/code>, <code>weights<\/code>)<\/td>\n<td>Analyses de recherche standard, pipelines statistiques consolid\u00e9s<\/td>\n<\/tr>\n<tr>\n<td><code>np.exp(np.mean(np.log(x)))<\/code><\/td>\n<td>NumPy seul<\/td>\n<td>Excellente<\/td>\n<td>Tr\u00e8s bonne (attention m\u00e9moire temporaire)<\/td>\n<td>Manuelle via masquages et <code>np.average<\/code><\/td>\n<td>Services contraints, microservices rapides, briques algorithmiques internes<\/td>\n<\/tr>\n<tr>\n<td>Compil\u00e9e Numba (<code>@njit<\/code>)<\/td>\n<td>Numba, LLVM<\/td>\n<td>Maximale apr\u00e8s compilation JIT<\/td>\n<td>Excellente (z\u00e9ro copie m\u00e9moire)<\/td>\n<td>Logique \u00e0 programmer explicitement<\/td>\n<td>Simulations de Monte-Carlo, it\u00e9rations ultra-intensives<\/td>\n<\/tr>\n<tr>\n<td>Distribu\u00e9e Dask (<code>da.exp(...)<\/code>)<\/td>\n<td>Dask<\/td>\n<td>Faible (co\u00fbt du planificateur DAG)<\/td>\n<td>Maximale (traitement hors-m\u00e9moire sur clusters)<\/td>\n<td>Prise en charge via les masques Dask<\/td>\n<td>Volum\u00e9tries g\u00e9antes exc\u00e9dant la capacit\u00e9 de la RAM physique<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>12.2 Garantie de la reproductibilit\u00e9 scientifique<\/h3>\n<p>L&rsquo;int\u00e9grit\u00e9 de la d\u00e9marche scientifique moderne repose sur le principe cardinal de reproductibilit\u00e9 computationnelle. Deux ex\u00e9cutions s\u00e9quentielles d&rsquo;un pipeline d&rsquo;analyse sur le m\u00eame jeu de donn\u00e9es doivent aboutir \u00e0 des r\u00e9sultats rigoureusement identiques au dernier bit de pr\u00e9cision. Pour garantir ce niveau d&rsquo;exigence dans vos travaux quantitatifs, plusieurs prescriptions m\u00e9thodologiques s&rsquo;imposent :<\/p>\n<ul>\n<li><strong>Verrouillage formel de l&rsquo;environnement logiciel :<\/strong> Utilisez imp\u00e9rativement des fichiers de verrouillage des d\u00e9pendances (tels que <code>requirements.txt<\/code> g\u00e9n\u00e9r\u00e9 via <code>pip-compile<\/code> ou <code>environment.yml<\/code> sous Conda) documentant les num\u00e9ros de version stricts de Python, NumPy et SciPy. Une mise \u00e0 jour non trac\u00e9e peut modifier subtilement l&rsquo;ordonnancement des calculs en virgule flottante ou les comportements par d\u00e9faut face aux valeurs manquantes.<\/li>\n<li><strong>Tra\u00e7abilit\u00e9 des environnements d&rsquo;ex\u00e9cution :<\/strong> Consignez syst\u00e9matiquement dans les m\u00e9tadonn\u00e9es de sortie de vos calculs la version de la biblioth\u00e8que utilis\u00e9e, l&rsquo;architecture du microprocesseur (x86_64, ARM) et les drapeaux d&rsquo;optimisation machine mobilis\u00e9s.<\/li>\n<li><strong>Structuration de carnets d&rsquo;analyse auto-suffisants :<\/strong> Si vous d\u00e9ployez vos analyses au sein de carnets Jupyter (<em>Jupyter Notebooks<\/em>), veillez \u00e0 ce que l&rsquo;ex\u00e9cution soit lin\u00e9aire du d\u00e9but \u00e0 la fin, sans \u00e9tat masqu\u00e9 en m\u00e9moire, et documentez chaque transformation math\u00e9matique au moyen de cellules Markdown r\u00e9dig\u00e9es avec la m\u00eame rigueur que votre code source.<\/li>\n<\/ul>\n<h3>12.3 Perspectives et g\u00e9n\u00e9ralisations statistiques<\/h3>\n<p>Sur le plan de la th\u00e9orie math\u00e9matique, la moyenne g\u00e9om\u00e9trique ne constitue pas une singularit\u00e9 isol\u00e9e, mais un cas particulier fondamental au sein d&rsquo;une famille d&rsquo;op\u00e9rateurs beaucoup plus large : les <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/mathworld.wolfram.com\/PowerMean.html\">moyennes d&rsquo;ordre sup\u00e9rieur ou moyennes de H\u00f6lder<\/a>. Pour un param\u00e8tre r\u00e9el <span class=\"arabpsy-math-inline\" data-latex=\"p in \\mathbb{R}\">$p in \\mathbb{R}$<\/span>, la moyenne d&rsquo;ordre <span class=\"arabpsy-math-inline\" data-latex=\"p\">$p$<\/span> d&rsquo;un ensemble de donn\u00e9es s&rsquo;exprime comme suit :<\/p>\n<p><span class=\"arabpsy-math-display\" data-latex=\"M_p(X) = \\left( \\frac{1}{n} \\sum_{i=1}^{n} x_i^p \\right)^{\\frac{1}{p}}\">$$M_p(X) = \\left( \\frac{1}{n} \\sum_{i=1}^{n} x_i^p \\right)^{\\frac{1}{p}}$$<\/span><\/p>\n<p>Lorsque <span class=\"arabpsy-math-inline\" data-latex=\"p=1\">$p=1$<\/span>, on retrouve la moyenne arithm\u00e9tique conventionnelle. Lorsque <span class=\"arabpsy-math-inline\" data-latex=\"p=-1\">$p=-1$<\/span>, l&rsquo;expression correspond \u00e0 la moyenne harmonique. Lorsque <span class=\"arabpsy-math-inline\" data-latex=\"p to 0\">$p to 0$<\/span>, la limite analytique de cette fonction co\u00efncide rigoureusement avec la moyenne g\u00e9om\u00e9trique :<\/p>\n<p><span class=\"arabpsy-math-display\" data-latex=\"\\lim_{p to 0} M_p(X) = G(X) = \\exp\\left( \\frac{1}{n} \\sum_{i=1}^{n} \\ln(x_i) \\right)\">$$\\lim_{p to 0} M_p(X) = G(X) = \\exp\\left( \\frac{1}{n} \\sum_{i=1}^{n} \\ln(x_i) \\right)$$<\/span><\/p>\n<p>Cette convergence fondamentale \u00e9claire les liens structurels profonds qui unissent la moyenne g\u00e9om\u00e9trique \u00e0 l&rsquo;entropie statistique, \u00e0 la divergence de Kullback-Leibler et \u00e0 la th\u00e9orie de l&rsquo;information d\u00e9velopp\u00e9e par Claude Shannon. En appr\u00e9hendant la moyenne g\u00e9om\u00e9trique comme le point focal de cette g\u00e9om\u00e9trie analytique, le data scientist et le statisticien s&rsquo;arment d&rsquo;une compr\u00e9hension conceptuelle limpide, consolid\u00e9e par la puissance et la modularit\u00e9 irrempla\u00e7ables de l&rsquo;\u00e9cosyst\u00e8me Python.<\/p>\n<h2>R\u00e9f\u00e9rences<\/h2>\n<ul>\n<li>Cauchy, A.-L. (1821). <em>Cours d&rsquo;Analyse de l&rsquo;\u00c9cole Royale Polytechnique : Premi\u00e8re partie, Analyse Alg\u00e9brique<\/em>. Imprimerie Royale.<\/li>\n<li>Harris, C. R., Millman, K. J., van der Walt, S. J., Gommers, R., Virtanen, P., Cournapeau, D., &#8230; &amp; Oliphant, T. E. (2020). Array programming with NumPy. <em>Nature<\/em>, 585(7825), 357\u2013362. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/doi.org\/10.1038\/s41586-020-2649-2\">https:\/\/doi.org\/10.1038\/s41586-020-2649-2<\/a><\/li>\n<li>IEEE. (2019). <em>IEEE Standard for Floating-Point Arithmetic<\/em> (IEEE Std 754-2019). IEEE Computer Society. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/doi.org\/10.1109\/IEEESTD.2019.8766229\">https:\/\/doi.org\/10.1109\/IEEESTD.2019.8766229<\/a><\/li>\n<li>Lam, P. K., Pitrou, A., &amp; Seibert, S. (2015). Numba: A LLVM-based Python JIT compiler. <em>Proceedings of the Second Workshop on the LLVM Compiler Infrastructure in HPC<\/em>, 1\u20136. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/doi.org\/10.1145\/2833157.2833162\">https:\/\/doi.org\/10.1145\/2833157.2833162<\/a><\/li>\n<li>McKinney, W. (2010). Data structures for statistical computing in Python. <em>Proceedings of the 9th Python in Science Conference<\/em>, 51\u201356. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/doi.org\/10.25080\/Majora-92bf1922-00a\">https:\/\/doi.org\/10.25080\/Majora-92bf1922-00a<\/a><\/li>\n<li>Rockafellar, R. T. (1970). <em>Convex Analysis<\/em>. Princeton University Press.<\/li>\n<li>Virtanen, P., Gommers, R., Oliphant, T. E., Haberland, M., Reddy, T., Cournapeau, D., &#8230; &amp; SciPy 1.0 Contributors. (2020). SciPy 1.0: Fundamental algorithms for scientific computing in Python. <em>Nature Methods<\/em>, 17(3), 261\u2013272. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/doi.org\/10.1038\/s41592-019-0686-2\">https:\/\/doi.org\/10.1038\/s41592-019-0686-2<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Guide acad\u00e9mique complet pour calculer la moyenne g\u00e9om\u00e9trique en Python \u00e0 l&rsquo;aide de SciPy et NumPy. M\u00e9thodes, exemples d&rsquo;impl\u00e9mentation et analyse empirique.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","template":"","categories":[2465,4786],"tags":[2682,4137,2960,2468,4352],"class_list":["post-2726","psych_stat","type-psych_stat","status-publish","hentry","category-programmation-python","category-statistiques-computationnelles","tag-analyse-statistique","tag-moyenne-geometrique","tag-numpy","tag-python","tag-scipy"],"_links":{"self":[{"href":"https:\/\/french.arabpsychology.com\/index.php?rest_route=\/wp\/v2\/psych_stat\/2726","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/french.arabpsychology.com\/index.php?rest_route=\/wp\/v2\/psych_stat"}],"about":[{"href":"https:\/\/french.arabpsychology.com\/index.php?rest_route=\/wp\/v2\/types\/psych_stat"}],"author":[{"embeddable":true,"href":"https:\/\/french.arabpsychology.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/french.arabpsychology.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2726"}],"version-history":[{"count":1,"href":"https:\/\/french.arabpsychology.com\/index.php?rest_route=\/wp\/v2\/psych_stat\/2726\/revisions"}],"predecessor-version":[{"id":16392,"href":"https:\/\/french.arabpsychology.com\/index.php?rest_route=\/wp\/v2\/psych_stat\/2726\/revisions\/16392"}],"wp:attachment":[{"href":"https:\/\/french.arabpsychology.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2726"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/french.arabpsychology.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2726"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/french.arabpsychology.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2726"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}