#import des modules
import matplotlib.pyplot as plt
import numpy as np
import random
%matplotlib inline
##Fonctions statistiques pour une série brute
def moyenne(tab):
return sum(tab)/len(tab)
def variance(tab):
return sum(map(lambda x : x**2, tab))/len(tab) - moyenne(tab)**2
def ecart_type(tab):
return np.sqrt(variance(tab))
#Attention comme les tableaux sont indexés à partir de 0
#il faut translater tous les indices de -1 dans les formules
def mediane(tab):
tab2 = tab[:]
tab2.sort()
n = len(tab2)
if n%2 == 0:
return (tab2[n//2-1] + tab2[n//2])/2, 'hors-série'
return tab2[(n+1)//2-1], (n+1)//2
def decile(tab, q):
tab2 = tab[:]
tab2.sort()
n = len(tab2)
position = n*q
if position == int(position):
return tab[int(position)-1], int(position)
return tab[int(position)], int(position) + 1
def cumul(tab):
cumultab = [tab[0]]
for e in tab[1:]:
cumultab.append(e + cumultab[-1])
return cumultab
#Fonctions statistiques pour une série donnée sous la forme tableau de valeurs, tableau d'effectifs
#En fait on a juste besoin de la fonction serie_brute pour réutiliser les fonctions précédentes
def moyenne_effectif(valeur, effectif):
return sum([x*n for (x, n) in zip(valeur, effectif)])/sum(effectif)
def variance_effectif(valeur, effectif):
return sum([x**2*n for (x, n) in zip(valeur, effectif)])/sum(effectif) - moyenne_effectif(valeur, effectif)**2
def ecart_type_effectif(valeur, effectif):
return np.sqrt(variance_effectif(valeur, effectif))
#Attention comme les tableaux sont indexés à partir de 0
#il faut translater tous les indices de -1 dans les formules
def serie_brute(valeur, effectif):
"""Reconstitution d'une série brute à partir des tableaux de valeurs et d'effectifs"""
return [x for i, x in enumerate(valeur) for k in range(effectif[i])]
def valeur_effectif(brute, cum = False):
"""Retourne un tableau de valeurs et un tableau d'effectifs
à partir d'une série brute.
Si ecc à True, retourne aussi le tableau des effectifs cumulés croissants"""
tab2 = brute[:]
tab2.sort() #tri
valeur, effectif = [brute[0]], [1]
ecc = None
for e in brute[1:]:
if e != valeur[-1]:
valeur.append(e)
effectif.append(1)
else:
effectif[-1] += 1
if cum:
ecc = cumul(effectif)
return valeur, effectif, ecc
return valeur, effectif
def affiche_tableau(brute=None, valeur=None, effectif=None, croissant=False):
"""Affiche un tableau Valeurs/ Effectifs"""
if brute != None:
if effectif == None and valeur == None:
valeur, effectif = tab_effectif(brute)
if effectif != None and valeur != None and len(valeur) == len(effectif):
if croissant:
effectifcumul = cumul(effectif)
print('|{:^30s}|{:^30s}|{:^30s}|'.format('Valeur', 'Effectif', 'Effectif cumulé croissant'))
for val, eff, effcumul in zip(valeur, effectif, effectifcumul):
print('|{:^30g}|{:^30g}|{:^30g}|'.format(val, eff, effcumul))
else:
print('|{:^40s}|{:^40s}|'.format('Valeur', 'Effectif'))
for val, eff in zip(valeur, effectif):
print('|{:^40g}|{:^40g}|'.format(val, eff))
def diagramme_circulaire(labels, effectif,formatfunction=None):
# The slices will be ordered and plotted counter-clockwise.
#plt.clf()
sizes = effectif
colors = ['#ECE9E9', '#ACAAAA', '#857E7E', '#848484']
if not formatfunction:
plt.pie(sizes, labels=labels,
autopct='%1.1f°', shadow=True, colors=colors,startangle=90)
else:
plt.pie(sizes, labels=labels,
autopct=formatfunction, shadow=True, colors=colors,startangle=90)
# Set aspect ratio to be equal so that pie is drawn as a circle.
plt.axis('equal')
#plt.show()
def diagramme_baton(valeur, effectif, largeur=1):
#plt.clf()
plt.bar(valeur, effectif,align='center', width=largeur,color='red', edgecolor = 'black')
plt.xlabel('Valeurs')
plt.ylabel('Effectifs')
plt.ylim(min(effectif) - 0.1*(max(effectif) - min(effectif)),
max(effectif) + 0.1*(max(effectif) - min(effectif)))
for p, e in zip(valeur, effectif):
plt.annotate(str(e),xy=(p,e), xycoords='data', fontsize=16)
# Tweak spacing to prevent clipping of ylabel
plt.subplots_adjust(left=0.15)
#plt.show()
def nuage_points(valeur, effectif):
#plt.clf()
plt.xlabel('Valeurs')
plt.ylabel('Effectifs')
plt.ylim(min(effectif) - 0.1*(max(effectif) - min(effectif)),
max(effectif) + 0.1*(max(effectif) - min(effectif)))
plt.xlim(min(valeur) - 0.1*(max(valeur) - min(valeur)),
max(valeur) + 0.1*(max(valeur) - min(valeur)))
plt.grid()
plt.plot(valeur, effectif, 'ko')
# Tweak spacing to prevent clipping of ylabel
plt.subplots_adjust(left=0.15)
#plt.show()
def polygone_cumule(brute=None, valeur=None, effectif=None, yticks = None):
def polygone_cumule_brute(tab):
valeur, effectif, ecc = valeur_effectif(tab, cum = True)
plt.xlabel('Valeurs')
plt.ylabel('Effectifs Cumulés')
plt.ylim(min(ecc) - 0.1*(max(ecc) - min(ecc)),
max(ecc) + 0.1*(max(ecc) - min(ecc)))
plt.xlim(min(valeur) - 0.1*(max(valeur) - min(valeur)),
max(valeur) + 0.1*(max(valeur) - min(valeur)))
if yticks != None:
ax = plt.gca()
ax.set_yticks(yticks, minor = True)
plt.grid(which='both')
plt.plot(valeur, ecc,'-ko')
if brute == None:
if effectif != None and valeur != None and len(valeur) == len(effectif):
polygone_cumule_brute(serie_brute(valeur, effectif))
elif effectif == None and valeur == None:
polygone_cumule_brutee(brute)
def diagramme_boite(brute=None, valeur=None, effectif=None, xmin=None, xmax=None):
def diagramme_boite_brute(tab):
#plt.clf()
if xmin != None and xmax != None:
plt.xlim(xmin, xmax)
else:
plt.xlim(min(tab) - 0.1*(max(tab) - min(tab)), max(tab) + 0.1*(max(tab) - min(tab)))
plt.boxplot(tab,vert=False,whis=10,medianprops=dict(linestyle='-',color='red'),boxprops=dict(linewidth=3))
#plt.show()
if brute == None:
if effectif != None and valeur != None and len(valeur) == len(effectif):
diagramme_boite_brute(sorted(serie_brute(valeur, effectif)))
elif effectif == None and valeur == None:
diagramme_boite_brute(sorted(brute))
def indicateurs(brute=None,effectif=None,valeur=None):
def indicateurs_brute(tab):
tab2 = tab[:]
tab2.sort()
print('Série triée :')
valeur, effectif = valeur_effectif(tab2, cum = False)
affiche_tableau(valeur=valeur, effectif=effectif, croissant=True)
print('Moyenne = %.3f'%moyenne_effectif(valeur, effectif))
print('Variance = %.3f'%variance_effectif(valeur, effectif))
print('Ecart-type = %.3f'%ecart_type_effectif(valeur, effectif))
print('-'*80)
print('Min = %s'%min(tab))
print('D1 = %s en position %s'%decile(tab2, 0.1))
print('Q1 = %s en position %s'%decile(tab2, 0.25))
print('Mediane = %s en position %s'%mediane(tab2))
print('Q2 = %s en position %s'% decile(tab2, 0.5))
print('Q3 = %s en position %s'%decile(tab2, 0.75))
print('D9 = %s en position %s'%decile(tab2, 0.9))
print('Max = %s '%max(tab2))
if brute == None:
if effectif != None and valeur != None and len(valeur) == len(effectif):
indicateurs_brute(serie_brute(valeur, effectif))
elif effectif == None and valeur == None:
indicateurs_brute(brute)
#test de la fonction serie_brute
serie_brute([1,2,3],[4,1,5])
#test des fonctions
tabalea1 = [random.randint(1, 100) for i in range(11)]
tabalea2 = [random.randint(1, 100) for i in range(10)]
effectif3, valeur3 = [random.randint(1, 100) for i in range(10)], [random.randint(1, 100) for i in range(10)]
for t in [tabalea1, tabalea2]:
print('Série = ', t)
indicateurs(brute=t)
print()
print('Valeurs = ', valeur3, 'Effectifs = ', effectif3)
indicateurs(valeur=valeur3, effectif = effectif3)
Dans l'entreprise A, il y a 100 ouvriers et 100 cadres, dans l'entreprise B, il y a 180 ouvriers et 20 cadres.
Dans l'entreprise A, le total des salaires mensuels des ouvriers est égal à 110 000 € et celui des cadres de 200 000 €.
Dans l'entreprise B, le total des salaires mensuels des ouvriers est égal à 207 000 € et celui des cadres est égal à 44 000 €.
Vérifier que le salaire mensuel moyen des ouvriers est plus élevé dans l'entreprise B que dans l'entreprise A, et qu'il en est de même pour les cadres.
Comparer les salaires mensuels moyens de l'ensemble des employés dans l'entreprise A et dans l'entreprise B.
Salaire moyen dans l'entreprise A :
Salaire moyen dans l'entreprise B :
prix = [900+i for i in range(0,700,100)]
prix.remove(1100)
effectif = [150,180,240,120,150,150]
affiche_tableau(valeur=prix, effectif=effectif)
diagramme_baton(prix, effectif,largeur=50)
diagramme_boite(valeur=prix,effectif=effectif)
#indicateurs de la série
indicateurs(valeur=prix,effectif=effectif)
On change le prix maximum de 1500 par 2000
prix[-1] = 2000
#indicateurs de la nouvelle série
indicateurs(valeur=prix,effectif=effectif)
On remet le prix maximum de 1500 et on change le prix minimum de 900 par 500
prix[-1], prix[0] = 1500, 500
#indicateurs de la nouvelle série
indicateurs(valeur=prix,effectif=effectif)
On peut remarquer que la médiane et les quartiles sont insensibles au changement des valeurs extremes mais que ce n'est pas le cas de la moyenne et de l'écart-type
diagramme_circulaire(['0,98 L', '0,99 L', '1 L', '1,1 L'], [45, 22, 27, 6])
valeur = [float(chaine.rstrip(' L').replace(',','.')) for chaine in ['0,98 L', '0,99 L', '1 L', '1,1 L']]
effectif = [45, 22, 27, 6]
indicateurs(valeur=valeur,effectif=effectif)
Groupe A
#GroupeA
noteA = [5,8,9,11,14,15]
effectifA = [2,2,1,1,4,2]
indicateurs(valeur=noteA, effectif=effectifA)
diagramme_baton(valeur=noteA, effectif=effectifA,largeur=1)
Groupe B
#serie brute de notes
serieB = [9,9,10,10,11,11,11,11,12,12,13,13]
noteB, effectifB = valeur_effectif(serieB, cum = False)
diagramme_baton(valeur=noteB, effectif = effectifB)
indicateurs(brute=serieB)
plt.subplot(2,1,1)
diagramme_boite(valeur=noteA, effectif=effectifA,xmin=0,xmax=20)
plt.subplot(2,1,2)
noteB,effectifB = valeur_effectif(serieB)
diagramme_boite(valeur=noteB, effectif=effectifB,xmin=0,xmax=20)
serieA = [21, 19, 17, 11, 9, 16, 8, 6, 12]
indicateurs(brute=serieA)
diagramme_boite(brute=serieA)
serieB = [2,9,7,2,9,8,8,6,2,8,6,8]
indicateurs(brute=serieB)
diagramme_boite(brute=serieB)
note5 = [3,5,6,7,8,9,10,11,12,13,14,17,18]
effectif5 = [1,2,1,4,3,5,5,4,2,1,2,2,1]
indicateurs(valeur=note5, effectif=effectif5)
diagramme_baton(valeur=note5, effectif=effectif5)
diagramme_boite(valeur=note5, effectif=effectif5)
On change les valeurs extremes
note5bis = note5[:]
note5bis[0], note5bis[-1] = 0, 20
indicateurs(valeur=note5bis, effectif=effectif5)
La moyenne et la variance ont été modifiées contrairement à la médiane et à l'écart-interquartile qui sont moins sensibles aux valeurs extremes
serie52 = [2, 4] + [1000]*6 + [50000]*2
indicateurs(brute=serie52)
valeur52, effectif52 = valeur_effectif(serie52, cum = False)
diagramme_baton(valeur=valeur52, effectif=effectif52)
Le couple (moyenne, ecart-type) est mieux adapté pour représenter la série car le couple (médiane, écart-interquartile) est (1000, 0) puisqu'il y a beaucoup de valeurs identiques.
Ceci dit, on peut aussi remarquer que l'écart-type caractérise mieux la dispersion de la série que l'écart-interquartile et que la médiane représente mieux la tendance centrale que la moyenne car aucune valeur de la série n'est proche de la moyenne. On pourrait donc choisir le couple (médiane, écart-type) pour caractériser la série.
serie6 = [49, 55, 57, 57, 57, 58, 58, 59, 60, 60 ,60, 62, 63, 63, 63, 63 ,64 ,64 ,64 ,64 ,64,
65 , 65 ,65 ,66 ,67, 69, 69, 70, 70, 72, 74, 74, 75 ,75 ,76, 77, 78, 79, 80, 80, 82]
indicateurs(brute=serie6)
valeur6, effectif6 = valeur_effectif(serie6)
diagramme_boite(valeur=valeur6, effectif=effectif6)
valeur8 = [i for i in range(0, 14)]
effectif8 = [1,2,3,6,8,10,15,24,16,13,12,11,9,3]
indicateurs(valeur = valeur8, effectif = effectif8)
diagramme_baton(valeur=valeur8, effectif=effectif8)
diagramme_boite(serie_brute(valeur=valeur8, effectif=effectif8))
valeur9 = [1.7, 1.71,1.72, 1.73, 1.74, 1.75, 1.76, 1.77, 1.8, 1.82, 1.83]
effectif9 = [4, 4, 2, 3, 3, 3, 6, 3, 3, 1, 1]
indicateurs(valeur = valeur9, effectif = effectif9)
diagramme_baton(valeur=valeur9, effectif=effectif9, largeur = 0.005)
diagramme_boite(serie_brute(valeur=valeur9, effectif=effectif9))