0

Je veux donc mettre en œuvre une méthode de normalisation matricielle. Pour ce faire, je nous a dit denumpy - faire l'opération le long de l'axe spécifié

Soustraire la moyenne et diviser par l'écart-type pour chaque dimension

Et pour vérifier:

après ce traitement, chaque dimension a zéro variance moyenne et unité.

Cela semble assez simple ...

import numpy as np 
def standardize(X : np.ndarray,inplace=True,verbose=False,check=False): 

    ret = X 
    if not inplace: 
     ret = X.copy() 

    ndim = np.ndim(X) 

    for d in range(ndim): 
     m = np.mean(ret,axis=d) 
     s = np.std(ret,axis=d) 

     if verbose: 
      print(f"m{d} =",m) 
      print(f"s{d} =",s) 

     # TODO: handle zero s 
     # TODO: subtract m along the correct axis 
     # TODO: divide by s along the correct axis 

    if check:  
     means = [np.mean(X,axis=d) for d in range(ndim)] 
     stds = [np.std(X,axis=d) for d in range(ndim)] 
     if verbose: 
      print("means=\n",means) 
      print("stds=\n",stds) 

     assert all(all(m < 1e-15 for m in mm) for mm in means) 
     assert all(all(s == 1.0 for s in ss) for ss in stds) 

    return ret 

par exemple pour ndim == 2, nous pourrions obtenir quelque chose comme

A= 
[[ 0.40923704 0.91397416 0.62257397] 
    [ 0.15614258 0.56720836 0.80624135]] 
m0 = [ 0.28268981 0.74059126 0.71440766] # can broadcast with ret -= m0 
s0 = [ 0.12654723 0.1733829 0.09183369] # can broadcast with ret /= s0 
m1 = [ 0.33333333 -0.33333333] # ??? 
s1 = [ 0.94280904 0.94280904] # ??? 

Comment puis-je faire cela?

A en juger par Broadcast an operation along specific axis in python, je pensais que je cherche peut-être un moyen de créer

m[None, None, None, .., None, : , None, None, .., None] 

Là où il y a exactement un : à l'index d.

Mais même si savait comment faire cela, je ne suis pas sûr que cela fonctionnerait.

+0

Mettez cette 'np.append' doucement vers le bas, et reculez. C'est dangereux. http://stackoverflow.com/questions/42563335/how-to-append-a-selection-of-a-numpy-array-to-an-empty-numpy-array – hpaulj

+0

@hpaulj ne fonctionnait pas, de toute façon. =) J'ai aussi essayé de "bidouiller" le 2D-case et j'ai trouvé que l'index du '': '' ne répondait pas à mes attentes. – User1291

+1

Utilisez 'keepdims' et évitez ainsi tout travail explicite de dilatation progressive? – Divakar

Répondre

1

Vous pouvez échanger vos axes de telle sorte que les premiers axes soient ceux que vous souhaitez normaliser. Cela devrait aussi fonctionner inplace, car swapaxes ne fait que renvoyer une vue sur vos données.

En utilisant la commande numpy swapaxes:

for d in range(ndim): 

    m = np.mean(ret,axis=d) 
    s = np.std(ret,axis=d) 

    ret = np.swapaxes(ret, 0, d) 

    # Perform Normalisation of Axis 
    ret -= m 
    ret /= s 

    ret = np.swapaxes(ret, 0, d) 
+0

Donc, il réattribue juste des étiquettes d'axe sans déplacer de données? Parce que bien que cette méthode obtienne les moyens suffisamment bas, je ne reçois pas exactement les variances unitaires. – User1291

+0

Oui, cela ne change pas les données. Mais vous avez raison, cette approche échoue également avec plus de 2 dimensions en quelque sorte. –

+0

Eh bien, il se trouve la raison * pourquoi * cela ne fonctionne pas parce que je fais la mauvaise chose. Ils ont écrit "pour chaque dimension", mais ce qu'ils signifiaient réellement était "pour chaque colonne" donc selon eux, une matrice "m par n" à deux dimensions a des dimensions "n". -.- Une simple diffusion aurait suffi. – User1291