Calcul d'une moyenne de plusieurs matrices

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

Quynh-Mai Chu
Messages : 37
Enregistré le : 03 Oct 2013, 20:53

Calcul d'une moyenne de plusieurs matrices

Messagepar Quynh-Mai Chu » 27 Fév 2014, 22:54

Bonsoir,

Je voudrais calculer la moyenne de plusieurs matrices. La fonction mean renvoie la valeur de la moyenne de tous les éléments des matrices. Or, je voudrais une matrice (et pas un nombre) qui vaut la moyenne des matrices. Y a-t-il une fonction en R qui fait cela? Ça a l'air bête comme question mais je ne trouve pas la réponse sur internet. Parce que faire des boucles pour calculer une "moyenne matricielle" ralentit énormément la compilation de R (et prend aussi beaucoup de lignes de codes).

Merci d'avance,

Mai,

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Messagepar Logez Maxime » 28 Fév 2014, 08:06

Bonjour,

ta question n'est pas bête mais il faudrait savoir sous quelle forme sont tes matrices. Est-ce que tu as n matrices indépendantes, est-ce qu'elles sont regroupées dans une liste, dans un array ? etc.

Cordialement,
Maxime

matthieu faron
Messages : 586
Enregistré le : 16 Fév 2011, 11:23

Messagepar matthieu faron » 28 Fév 2014, 08:09

Bonjour,

Je ne comprends pas bien votre question, vous voulez :

- une matrice de la même taille que les autres qui contient pour chaque élément de la ligne x, colonne y la moyenne des valeurs aux mêmes emplacement dans les autres matrices ?
==> Les empiler dans un array et utiliser apply


- la moyenne de tous les éléments de chaque matrice
==> les mettre dans une liste et utiliser sapply


Un mini jeu de données même factie pourrait être profitable.
Matthieu FARON

Alexandre Dangléant
Messages : 270
Enregistré le : 30 Mar 2010, 14:38

Messagepar Alexandre Dangléant » 28 Fév 2014, 08:39

Bonjour,

J'ai découvert récemment mapply, qui peut potentiellement t'intéresser, pour peu que j'ai bien compris ce que tu veux faire :)
Ca fait la moyenne de chaque cellule au travers des matrices (pas facile à dire autrement). Bien sûr, celles-ci doivent avoir les mêmes dimensions... Tu trouvera un exemple ici : http://nsaunders.wordpress.com/2010/08/ ... pply-in-r/ (lien trouvé sur ce forum)

Cordialement.

Quynh-Mai Chu
Messages : 37
Enregistré le : 03 Oct 2013, 20:53

Messagepar Quynh-Mai Chu » 28 Fév 2014, 10:27

Oui je n'ai pas été très claire. Voici un exemple qui provient de mon jeu de donnée suivant: https://dl.dropboxusercontent.com/u/529 ... -200911.nc

J'extrais les variables suivants:

Code : Tout sélectionner

 library(ncdf)
DATA <- open.ncdf("G:/Drop/Dropbox/Master1/ComplModClim/Travail/Data/tas_Amon_EC-EARTH_historical_r1i1p1_194001-200911.nc")

t <- get.var.ncdf(DATA, "time")
lon <- get.var.ncdf(DATA, "lon")
lat <- get.var.ncdf(DATA, "lat")
tas <- get.var.ncdf(DATA, "tas")

Nt <- length(t)
nlon <- length(lon)
nlat <- length(lat)


La variable "tas" (température de l'air en surface) est de type array et ses dimensions sont nlon x nlat x Nt. Je voudrais calculer la température moyenne de l'air en surface (appelons la tas_mean) pour la période t[10] et t[30]. La variable tas_mean est de dimension nlon x nlat. La façon dont je procédais qui n'est vraiment pas "beau" et pratique (j'ai l'impression que l'utilisation des boucles ralentit la compilation de R) est la suivante:

Code : Tout sélectionner

 for(i in seq(nlon)){
    for(j in seq(nlat)){
     
      tas_mean[i,j] <- mean(tas[i,j,seq(t[10],t[30])])
     
    }
  }


Voilà, je voulais savoir si il y avait une fonction qui permet d'avoir le même résultat sans devoir passer par des boucles. J'ai regardé pour la fonction mapply mais je n'ai pas trop compris comment ça fonctionne. J'ai l'impression qu'elle ne renvoie qu'un vecteur. Or c'est une matrice que je voudrais. Je ne sais pas si je suis plus claire :-)

Merci encore pour votre aide,

Mai,

Vincent Guillemot
Messages : 451
Enregistré le : 05 Mai 2010, 15:11

Messagepar Vincent Guillemot » 28 Fév 2014, 10:49

Bonjour,

je viens de découvrir ce mode de fonctionnement pour "apply", qui ne finira pas de m'épater :

Code : Tout sélectionner

system.time( tas_mean1 <- apply(tas,1:2,mean) )

system.time( {
tas_mean2 <- matrix(NA,nlon,nlat)
for(i in seq(nlon))
     for(j in seq(nlat))
       tas_mean2[i,j] <- mean(tas[i,j,])
} )

identical(tas_mean1, tas_mean2)


J'ai rajouté un system.time pour bien vérifier que la première commande est un peu plus rapide que la deuxième.

Cdlt,
V.

PS : je n'ai pas pas vraiment compris à quoi servait le "seq(t[10],t[30])", donc je l'ai enlevé.

Alexandre Dangléant
Messages : 270
Enregistré le : 30 Mar 2010, 14:38

Messagepar Alexandre Dangléant » 28 Fév 2014, 10:55

Pour revenir sur mapply :

Code : Tout sélectionner

> bob <- list()
bob[[1]] <- matrix(c(10,15,5,2), byrow=T, ncol=2)
bob[[2]] <- matrix(c(10,15,5,2), byrow=T, ncol=2)
mapply(sum, bob[[1]], bob[[2]])
[1] 20 10 30  4
Effectivement, ça fonctionne sur des vecteurs, mais les matrices sont des vecteurs, fondamentalement... Attention, le vecteur d'une matrice correspond à la mise bout à bout des colonnes. Tu peux retransformer la sortie en mettant devant : matrix(ton vecteur de sortie , ncol=ncol(matrice source))

Code : Tout sélectionner

> matrix(mapply(sum, bob[[1]], bob[[2]]), ncol=2)
     [,1] [,2]
[1,]   20   30
[2,]   10    4
A toi de voir si ça t'aide!

A+

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Messagepar Logez Maxime » 28 Fév 2014, 13:00

re,

dans le même ordre d'idée la fonction rowMeans est étonnante et dans ce cas 25x plus rapide :

Code : Tout sélectionner

tas_mean1 <- apply(tas,1:2,mean)
tas_mean2 <- rowMeans(tas, dims=2)
all.equal(tas_mean1, tas_mean2)
[1] TRUE

microbenchmark(tas_mean1 <- apply(tas,1:2,mean), tas_mean2 <- rowMeans(tas, dims=2))
Unit: milliseconds
                                 expr       min       lq   median        uq       max neval
   tas_mean1 <- apply(tas, 1:2, mean) 2750.5279 2775.128 2898.791 2915.7816 3008.3859   100
 tas_mean2 <- rowMeans(tas, dims = 2)  112.1209  112.718  113.066  113.4606  115.1138   100
Cordialement,
Maxime

Quynh-Mai Chu
Messages : 37
Enregistré le : 03 Oct 2013, 20:53

Messagepar Quynh-Mai Chu » 28 Fév 2014, 20:23

Bonsoir,

Alors là, j'en apprend des choses sur R :D. Ces fonctions sont bien plus rapides que d'utiliser des boucles. Merci encore pour toutes ces réponses.

Mai,

Pierre Bady
Messages : 405
Enregistré le : 02 Mai 2006, 07:46

Messagepar Pierre Bady » 05 Mar 2014, 13:35

bien le bonjour,

la function Reduce peut également rendre quelques services lorsque l'on travaille sur des listes :)

Code : Tout sélectionner

xx <- NULL
for(i in 1:10) xx[[i]] <- matrix(c(1,2,3,4),nc=2)
Reduce("+",xx)
Reduce("+",xx)/length(xx)



HTH


pierre
=@===--------¬-------¬------¬-----¬
liens utiles :
http://www.gnurou.org/Writing/SmartQuestionsFr
http://neogrifter.free.fr/welcomeOnInternet.jpg
]<((((*< -------------------------------


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité