IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MATLAB Discussion :

Matrice importante: boucle impossible


Sujet :

MATLAB

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 62
    Points : 57
    Points
    57
    Par défaut Matrice importante: boucle impossible
    Bonjour,

    Voici mon problème:
    J'ai une matrice initiale (C) de la forme n lignes, 2 colonnes:
    1	0.1
    1	0.09
    1	0.2
    2	0.09
    2	0.08
    3	0.1
    3	0.08
    4	0.09
    4	0.09
    Je veux une matrice finale de la forme m lignes (autant que de valeurs discrètes dans la première colonne de la matrice initiale), 3 colonnes:

    	Mean	Std	
    1	0.13	0.0608276
    2	0.085	0.00707107
    3	0.09	0.0141421
    4	0.09	0

    En faisant des boucles, j'arrive à créer ma matrice mais ça prend un temps fou parce que ma matrice initiale est énorme (>10e6 valeurs)!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    Result=zeros(length(A),2);
    Result(:,1)=A(:);
    Result(:,2)=B(:);
    C=sortrows(Result,1); %Matrice initiale dans mon post
     
    i=0;j=0;k=0;l=0;
     
    for(j=1:max(B(:,1)))
        for(i=1:length(B))
            if(B(i,1)==j)
                k=k+B(i,2);
                l=l+1;
                Std_k(l)=B(i,2);
            end
        end%for
        Result2(j,1)=j;
        %Result2(j,1) contient les différentes valeurs discretes
        Result2(j,2)=k/l;
        %Result2(j,2) contient la valeur moyenne
        Result2(isnan(Result2))=0;
        %Result2(j,3) contient l'écart-type
        Result2(j,3)=std(Std_k);
        k=0;
        l=0;
        Std_k=0;
    end%for
    Il doit bien y avoir une méthode moins bourrine et plus subtile pour faire ça en Matlab, mais je ne vois pas...

    Merci d'avance!

    Sébastien

  2. #2
    Membre éprouvé
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Points : 1 277
    Points
    1 277
    Par défaut
    Bonjour,

    Tu peux vectoriser un peu ton code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    data=[];
    u= unique(B(:,1));
    for v= (u(:)')
        idx= B(:,1)== v;
        data(end+1)= [v, mean(B(idx,2)),std(B(idx,2))];
    end

  3. #3
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 52 882
    Points
    52 882
    Par défaut
    Une solution en utilisant ACCUMARRAY :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    C = [1	0.1
        1	0.09
        1	0.2
        2	0.09
        2	0.08
        3	0.1
        3	0.08
        4	0.09
        4	0.09];
     
    uC1 = unique(C(:,1));
    nuC1 = numel(uC1);
     
    M = accumarray(C(:,1),C(:,2),[nuC1 1],@mean);
    S = accumarray(C(:,1),C(:,2),[nuC1 1],@std);
     
    [M S]
    Si les valeurs de la première colonne sont dans l'intervalle [1 N] sans valeurs manquantes, le code ci-dessus se simplifie en :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    C = [1	0.1
        1	0.09
        1	0.2
        2	0.09
        2	0.08
        3	0.1
        3	0.08
        4	0.09
        4	0.09];
     
    nuC1 = max(C(:,1));
     
    M = accumarray(C(:,1),C(:,2),[nuC1 1],@mean);
    S = accumarray(C(:,1),C(:,2),[nuC1 1],@std);
     
    [M S]
    ou encore :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    C = [1	0.1
        1	0.09
        1	0.2
        2	0.09
        2	0.08
        3	0.1
        3	0.08
        4	0.09
        4	0.09];
     
    M = accumarray(C(:,1),C(:,2),[],@mean);
    S = accumarray(C(:,1),C(:,2),[],@std);
     
    [M S]
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 62
    Points : 57
    Points
    57
    Par défaut
    Merci bcp.
    Cette solution est fort élégante.

    Comme tu l'as indiqué, mes matrices ne contiennent pas forcément des valeurs contigues, typ:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    C = [1	0.1
        1	0.09
        1	0.2
        3	0.09
        3	0.08
        3	0.1
        7	0.08
        12	0.09
        12	0.09];

    Dans ce cas, j'ai essayé tes différentes méthodes mais ça marche sur un exemple simple mais pas sur mes datas.
    J'ai essayé de joindre mes datas dans un fichier mais c'est trop lourd...

  5. #5
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 52 882
    Points
    52 882
    Par défaut
    Pourtant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    C = [1 0.1
    1 0.09
    1 0.2
    3 0.09
    3 0.08
    3 0.1
    7 0.08
    12 0.09
    12 0.09]
     
    M = accumarray(C(:,1),C(:,2),[],@mean,NaN);
    S = accumarray(C(:,1),C(:,2),[],@std,NaN);
     
    idx = ~isnan(M);
     
    X = [M(idx) S(idx)]
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 62
    Points : 57
    Points
    57
    Par défaut
    Effectivement, ça fonctionne mais quand je teste les deux méthodes que j'avais codées, j'tombe sur des matrices de 20317 alors que là, M et S ont une taille de 20083...

    J'vais voir ce que ça donne en représentant les data.
    Il me reste encore à remplir la première colonne (les indices 1,2,3,7,9,11, etc.).

  7. #7
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 52 882
    Points
    52 882
    Par défaut
    Citation Envoyé par Mailf Voir le message
    Il me reste encore à remplir la première colonne (les indices 1,2,3,7,9,11, etc.).
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 62
    Points : 57
    Points
    57
    Par défaut
    Bonjour,

    Merci pour la résolution parfaite de ma question.
    J'avoue que je n'aurais pas du tout pensé à cette solution avec accumarray.
    C'est là un bel exemple de la puissance de Matlab, quand on connaît les bonnes fonctions, c'est très efficace!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    %Result continent deux colonnes
    % de type Result_Init= [1 0.1
    1 0.09
    1 0.2
    3 0.09
    3 0.08
    3 0.1
    7 0.08
    12 0.09
    12 0.09];
     
     
    B=sortrows(Result_Init,1);
     
    M = accumarray(B(:,1),B(:,2),[],@mean,NaN);
    S = accumarray(B(:,1),B(:,2),[],@std,NaN);
    I = unique(B(:,1));
    Result_Final=zeros(size(I,1),3);
    idx = ~isnan(M);
     
    Result_Final= [I M(idx) S(idx)];
    J'espère que ça pourra aider d'autres personnes à l'avenir.
    Bien cordialement.

  9. #9
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 52 882
    Points
    52 882
    Par défaut
    Il n'est pas nécessaire de trier le tableau avec SORTROWS dans ton code.

    Sinon essaie aussi cette version :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    Result_Init= [1 0.1
    1 0.09
    1 0.2
    3 0.09
    3 0.08
    3 0.1
    7 0.08
    12 0.09
    12 0.09];
     
    [I,a,b] = unique(Result_Init(:,1));
    nI = numel(I);
     
    M = accumarray(b,Result_Init(:,2),[nI 1],@mean);
    S = accumarray(b,Result_Init(:,2),[nI 1],@std);
     
    Result_Final = [I M S];
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Débutant] indexation de matrice et boucle for
    Par mygwel dans le forum MATLAB
    Réponses: 2
    Dernier message: 15/03/2009, 18h09
  2. [FPDF] boucle impossible
    Par schwarzy2 dans le forum Bibliothèques et frameworks
    Réponses: 3
    Dernier message: 09/06/2008, 21h11
  3. Probleme Vista : CHKDSK en boucle + Impossible charger profil
    Par Bateau_Ivre dans le forum Windows Vista
    Réponses: 0
    Dernier message: 14/01/2008, 14h25
  4. Matrice et boucle: problème de dimension
    Par lilyla dans le forum MATLAB
    Réponses: 6
    Dernier message: 21/12/2007, 11h30
  5. Comparaison de deux matrices sans boucle for
    Par zicos dans le forum MATLAB
    Réponses: 8
    Dernier message: 04/05/2007, 18h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo