Normaliser chaque ligne d'un tableau en pourcentages avec numpy, également connu sous le nom de normalisation par ligne, peut être réalisé en divisant chaque élément du tableau par la somme de tous les éléments de cette ligne particulière :
Considérons l'exemple suivant.
import numpy as np
np.random.seed(42)
data = np.random.random_sample((6, 2)) * 10
donne
array([[3.74540119, 9.50714306],
[7.31993942, 5.98658484],
[1.5601864 , 1.5599452 ],
[0.58083612, 8.66176146],
[6.01115012, 7.08072578],
[0.20584494, 9.69909852]])
Notre objectif est de normaliser chaque ligne et de calculer le pourcentage.
"broadcasting method"
row_sums = data.sum(axis=1)
data_new = data / row_sums[:, np.newaxis
donne
array([[0.28261752, 0.71738248],
[0.55010153, 0.44989847],
[0.50003865, 0.49996135],
[0.06284339, 0.93715661],
[0.45915117, 0.54084883],
[0.02078204, 0.97921796]])
Pour obtenir un pourcentage, il suffit de multiplier chaque ligne par 100 :
row_sums = data.sum(axis=1)
data_new = data / row_sums[:, np.newaxis] * 100
donne
array([[28.26175199, 71.73824801],
[55.01015348, 44.98984652],
[50.00386524, 49.99613476],
[ 6.28433854, 93.71566146],
[45.91511687, 54.08488313],
[ 2.07820412, 97.92179588]])
Utiliser sklearn avec la normalisation
Une autre solution
from sklearn.preprocessing import normalize
data_new = normalize(data, axis=1, norm='l1') * 100
donne
array([[28.26175199, 71.73824801],
[55.01015348, 44.98984652],
[50.00386524, 49.99613476],
[ 6.28433854, 93.71566146],
[45.91511687, 54.08488313],
[ 2.07820412, 97.92179588]])
En utilisant pandas
Une autre solution
import pandas as pd
df = pd.DataFrame(data)
Calculer la somme pour chaque ligne.
df.sum(axis=1)
donne
0 13.252544
1 13.306524
2 3.120132
3 9.242598
4 13.091876
5 9.904943
dtype: float64
Créez un dataframe avec des lignes normalisées à 100.
df[[0,1]].div(df.sum(axis=1), axis=0) * 100
retourne le dataframe suivant
0 1
0 28.582162 71.417838
1 55.399630 44.600370
2 50.397602 49.602398
3 6.377737 93.622263
4 46.306478 53.693522
5 2.110498 97.889502
Convertir un dataframe en numpy.
df[[0,1]].div(df.sum(axis=1), axis=0).to_numpy() * 100
donne
array([[28.26175199, 71.73824801],
[55.01015348, 44.98984652],
[50.00386524, 49.99613476],
[ 6.28433854, 93.71566146],
[45.91511687, 54.08488313],
[ 2.07820412, 97.92179588]])
Notes supplémentaires
Créez une carte thermique à l'aide de matplotlib.
import matplotlib.pyplot as plt
import seaborn as sns; sns.set()
fig = plt.figure(num=None, figsize=(12, 8), dpi=80, facecolor='w', edgecolor='k')
plt.clf()
ax = fig.add_subplot(111)
ax.set_aspect(0.5)
annot_m = np.empty(data_new.shape,dtype='<U16')
for i in range(data_new.shape[0]):
for j in range(data_new.shape[1]):
annot_m[i,j] = 'Score: {:.2f}'.format(data_new[i,j])
res = sns.heatmap(data_new, annot=annot_m, fmt="", cmap="YlGnBu", vmin=0.0, vmax=100.0, cbar=False)
plt.title('How to normalize rows of an array with numpy ?',fontsize=12)
plt.xticks([i+0.5 for i in range(data_new.shape[1])], ['C1', 'C2'])
plt.xticks(rotation=0)
plt.yticks([i+0.5 for i in range(data_new.shape[0])], ['A', 'B', 'C','D', 'E', 'F'])
plt.yticks(rotation=0)
plt.yticks(rotation=0)
plt.savefig("how_to_normalize_rows_of_an_array_with_numpy_02.png", bbox_inches='tight', dpi=200)
plt.show()
Arrondir les valeurs du tableau
np.around(data_new,2)
donne
array([[28.26, 71.74],
[55.01, 44.99],
[50. , 50. ],
[ 6.28, 93.72],
[45.92, 54.08],
[ 2.08, 97.92]])
Références
Liens | Site |
---|---|
numpy.sum | numpy.org |
broadcasting | numpy.org |
sklearn.preprocessing.normaliz | scikit-learn.org |
pandas.DataFrame.divide | pandas.pydata.org |
around() | numpy.org |