Légèrement modifié de: Python Pandas Dataframe: Normaliser les données entre 0,01 et 0,99? mais à partir de certains commentaires, il a pensé que c'était pertinent (désolé si considéré comme un republication cependant ...)
Je voulais une normalisation personnalisée dans ce percentile régulier de la donnée ou du score z n'était pas adéquate. Parfois, je savais quels étaient les max et min possibles de la population, et je voulais donc le définir autrement que mon échantillon, ou un point médian différent, ou autre! Cela peut souvent être utile pour redimensionner et normaliser les données pour les réseaux neuronaux où vous voudrez peut-être toutes les entrées entre 0 et 1, mais certaines de vos données devront peut-être être mises à l'échelle de manière plus personnalisée ... car les percentiles et stdevs supposent que votre échantillon couvre la population, mais parfois nous savons que ce n'est pas vrai. Cela m'a également été très utile lors de la visualisation de données dans des cartes thermiques. J'ai donc créé une fonction personnalisée (j'ai utilisé des étapes supplémentaires dans le code pour le rendre aussi lisible que possible):
def NormData(s,low='min',center='mid',hi='max',insideout=False,shrinkfactor=0.):
if low=='min':
low=min(s)
elif low=='abs':
low=max(abs(min(s)),abs(max(s)))*-1.#sign(min(s))
if hi=='max':
hi=max(s)
elif hi=='abs':
hi=max(abs(min(s)),abs(max(s)))*1.#sign(max(s))
if center=='mid':
center=(max(s)+min(s))/2
elif center=='avg':
center=mean(s)
elif center=='median':
center=median(s)
s2=[x-center for x in s]
hi=hi-center
low=low-center
center=0.
r=[]
for x in s2:
if x<low:
r.append(0.)
elif x>hi:
r.append(1.)
else:
if x>=center:
r.append((x-center)/(hi-center)*0.5+0.5)
else:
r.append((x-low)/(center-low)*0.5+0.)
if insideout==True:
ir=[(1.-abs(z-0.5)*2.) for z in r]
r=ir
rr =[x-(x-0.5)*shrinkfactor for x in r]
return rr
Cela prendra dans une série de pandas, ou même juste une liste et la normalisera à vos points bas, centre et hauts spécifiés. il y a aussi un facteur de rétrécissement! pour vous permettre de réduire les données des points de terminaison 0 et 1 (j'ai dû le faire lors de la combinaison de cartes de couleurs dans matplotlib: Single pcolormesh avec plus d'une palette de couleurs en utilisant Matplotlib ) Vous pouvez donc probablement voir comment le code fonctionne, mais vous dites essentiellement ont des valeurs [-5,1,10] dans un échantillon, mais veulent normaliser sur la base d'une plage de -7 à 7 (donc tout ce qui est au-dessus de 7, notre "10" est traité comme un 7 effectivement) avec un point médian de 2, mais réduisez-le pour l'adapter à une palette de couleurs 256 RVB:
#In[1]
NormData([-5,2,10],low=-7,center=1,hi=7,shrinkfactor=2./256)
#Out[1]
[0.1279296875, 0.5826822916666667, 0.99609375]
Cela peut aussi transformer vos données à l'envers ... cela peut sembler étrange, mais je l'ai trouvé utile pour la cartographie thermique. Supposons que vous souhaitiez une couleur plus foncée pour des valeurs plus proches de 0 que de hi / low. Vous pouvez utiliser une carte thermique basée sur des données normalisées où insideout = True:
#In[2]
NormData([-5,2,10],low=-7,center=1,hi=7,insideout=True,shrinkfactor=2./256)
#Out[2]
[0.251953125, 0.8307291666666666, 0.00390625]
Alors maintenant "2" qui est le plus proche du centre, défini comme "1" est la valeur la plus élevée.
Quoi qu'il en soit, je pensais que mon application était pertinente si vous cherchez à redimensionner les données d'une autre manière qui pourrait avoir des applications utiles pour vous.
A
etB
font partie d'un facteur de regroupement plus large que vous souhaitez normaliser séparément deC
etD
.