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 :

Detection d'un max sur un groupe de données dans un vecteur.


Sujet :

MATLAB

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2012
    Messages : 15
    Points : 11
    Points
    11
    Par défaut Detection d'un max sur un groupe de données dans un vecteur.
    Bonjours,

    j'ai un vecteur V de taille 50 de se type:

    [0 0 0 3 6 4 0 0 0 0 0 0 0 0 0 0 0 3 2 6 7 6 0 0 0 0 0 0 0 0 0 0 7 8 2 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0]

    j'aimerais trouver le maximum de chaques groupes de donnée.

    Par groupe de donnée j'entend par la (dans cet exemple) :
    (3 6 4), (3 2 6 7 6) et (7 8 2 0 6).

    Je n'ai trouvé pour l'instant comme méthode que celle de "fenêtrage" càd:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    taille_fenetre=10;
    fenetrage = reshape(V,taille_fenetre,[]);
    [~,indice] = max(fenetrage);
    indice = indice + (0:length(indice)-1)*taille_fenetre;
    resultat=zeros(1,length(V));
    resultat(indice)=V(indice);
    fenetrage.':
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    [0 0 0 3 6 4 0 0 0 0;
    0 0 0 0 0 0 0 3 2 6 ;
    7 6 0 0 0 0 0 0 0 0 ;
    0 0 7 8 2 0 6 0 0 0 ;
    0 0 0 0 0 0 0 0 0 0 ]
    le problème est qu'il me renvoi les indices de 5 maximum (5 20 21 34 41) alors que je n'est que 3 groupes de donnée, du a la coupure du 2e groupe de donnée et aussi du a l'absence de groupe de donnée dans la 5ème fenêtre.

    J'aimerais donc comparer les maximums de ce genre de tableau (transposé biensurs):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    [0 0 0 3 6 4 0 0 0 0  0 0 0 0 0 0 0 3 2 6 ;
     0 0 0 0 0 0 0 3 2 6  7 6 0 0 0 0 0 0 0 0 ;
     7 6 0 0 0 0 0 0 0 0  0 0 7 8 2 0 6 0 0 0 ;
     0 0 7 8 2 0 6 0 0 0  0 0 0 0 0 0 0 0 0 0 ]
    Mais là je bloque sans boucle for, déjà rien que pour crée se tableau.
    Mon algorithme s'appliquerait sur des grands jeu de donnée et for serait trop long...

    Donc voila si vous avez des idées a me suggérer pour se problème ou même une autre méthode de détection de maximum je suis preneur

  2. #2
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2012
    Messages : 15
    Points : 11
    Points
    11
    Par défaut
    ok je suis bidon...

    pour le tableau(transposé):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    [0 0 0 3 6 4 0 0 0 0  0 0 0 0 0 0 0 3 2 6 ;
     0 0 0 0 0 0 0 3 2 6  7 6 0 0 0 0 0 0 0 0 ;
     7 6 0 0 0 0 0 0 0 0  0 0 7 8 2 0 6 0 0 0 ;
     0 0 7 8 2 0 6 0 0 0  0 0 0 0 0 0 0 0 0 0 ]
    c'est aussi simple que ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fenetrage2=[fenetrage(:,1:end-1);fenetrage(:,2:end)];
    maintenant il faut que je trouve comment avoir resultat.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2012
    Messages : 15
    Points : 11
    Points
    11
    Par défaut
    ok le fait de parlé de mon problème me permet de mieu le posé dans mon esprit.

    voila le code que je pense être juste:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    taille_fenetre=10;
    fenetrage = reshape(V,taille_fenetre,[]);
    fenetrage2=[fenetrage(:,1:end-1);fenetrage(:,2:end)];
    [~,indice] = max(fenetrage2);
    indice = indice + (0:length(indice)-1)*taille_fenetre;
    indice = union(indice,indice); %supprime les doublets
    indice(cellarray(@isnan, indice)) = []; %supprime les nan
    resultat=zeros(1,length(V));
    resultat(indice)=V(indice);
    il me reste un petit problème...

    pour un groupe de donnée 4 8 6 5 7 coupé de cet façon 4 8 6 | 5 7 par reshape, j'ai peur qu'il me trouve par la suite 2 max pour un groupe de donnée...

  4. #4
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2012
    Messages
    291
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 291
    Points : 434
    Points
    434
    Par défaut
    Bonjour,

    Je ne sais pas si j'ai bien compris ton problème mais une autre idée serait de faire une labelisation en composante connexe:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    l = [0 0 0 3 6 4 0 0 0 0 0 0 0 0 0 0 0 3 2 6 7 6 0 0 0 0 0 0 0 0 0 0 7 8 2 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0];
    bw = bwlabel(l);
    resultat = zeros(1,max(bw));
     
    for k=1:max(bw)
       resultat(k) = max(l.*(bw==k));
    end
    Par contre je ne comprend pas pourquoi 7 8 2 0 6 n'ai q'un groupe?
    Peux-tu mieux expliquer ta définition du groupe.

    Rque:
    Si il faut mettre un critère de proximité entre les groupe.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2012
    Messages : 15
    Points : 11
    Points
    11
    Par défaut
    Bonjour,

    un groupe de données est un groupe de valeur dont les 2 extrémités sont non nul et les groupes sont séparer par plusieurs 0 (séparé par n 0 pour n>=2).

    J'espère avoir mieux défini ce qu'été mes groupes de donnée, maintenant je vais étudier ton code, merci bien .

  6. #6
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Une solution utilisant strfind :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    V = [0 0 0 3 6 4 0 0 0 0 0 0 0 0 0 0 0 3 2 6 7 6 0 0 0 0 0 0 0 0 0 0 7 8 2 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0];
    n = 2; % nombre de zéros minimum séparant les données
    idx = [zeros(1,n) V zeros(1,n)]~=0;
    debut = strfind(idx,[false(1,n) true]); % indices marquant le début de chaque groupe
    fin = strfind(idx,[true false(1,n)])-n; % indices marquant la fin de chaque groupe
     
    data = arrayfun(@(from, to) V(from:to) , debut,fin,'UniformOutput',false); % groupes
    data{:}
     
    maxima = arrayfun(@(from, to) max(V(from:to)) , debut,fin) % max de chaque groupe
    % ou : cellfun(@(d) max(d) , data)
    Dernière modification par Invité ; 23/07/2012 à 14h48. Motif: correction

  7. #7
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2012
    Messages
    291
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 291
    Points : 434
    Points
    434
    Par défaut
    Citation Envoyé par baalk42 Voir le message
    Bonjour,

    un groupe de données est un groupe de valeur dont les 2 extrémités sont non nul et les groupes sont séparer par plusieurs 0 (séparé par n 0 pour n>=2).

    J'espère avoir mieux défini ce qu'été mes groupes de donnée, maintenant je vais étudier ton code, merci bien .
    D'accord dans ce cas un petit changement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    n = 2;
    l = [0 0 0 3 6 4 0 0 0 0 0 0 0 0 0 0 0 3 2 6 7 6 0 0 0 0 0 0 0 0 0 0 7 8 2 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0];
    tic
    s = imclose(l>0, strel('line', 2*n+1, 1) ); 
    bw = bwlabel(s);
    resultat = zeros(1,max(bw));
     
    for k=1:max(bw)
       resultat(k) = max(l.*(bw==k));
    end
    toc
     
    resultat
    Marche très bien ici. Les fonctions utilisées sont en générale pour le traitement d'image. Mais je remarque ici que le temps d'exécution reste court.

    A comparer à celle de Winjerome ( qui à mon sens reste plus adapté dans votre cas):
    Pour un jeu de données de 500000:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    V = rand(1,50000).*(rand(1,50000)<0.3);
    Winjerome: Elapsed time is 0.108319 seconds.
    Gakusei: Elapsed time is 0.552182 seconds.

  8. #8
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2012
    Messages : 15
    Points : 11
    Points
    11
    Par défaut
    Un grand merci a tous les 2 pour vos solutions.

    Par contre Gakusei mon MATLAB ne reconnait les fonctions imclose, strel et bwlabel. Je n'ai pas Image Processing Toolbox sur ma version MATLAB...

  9. #9
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2012
    Messages : 15
    Points : 11
    Points
    11
    Par défaut
    @Winjerome:

    T'as fonction règle mon dernier petit problème (c'est super !) :
    pour un groupe de donnée 4 8 6 5 7 coupé de cet façon 4 8 6 | 5 7 par reshape, j'ai peur qu'il me trouve par la suite 2 max pour un groupe de donnée...
    Par contre n'étant sur matlab que depuis peu, je n'arrive pas à comprendre et à trouver une explication sur l'help de Matlab ou sur internet à ce terme:
    Aurais tu un liens, un FAQ ou ton explication qui me permettais de comprendre ?

    Et enfin je tien à m'excuser se n'est pas le max de chaque groupe que je cherche mais les indices du max de chaque groupe .
    Donc je me permet de modifier ton code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    V = [0 0 0 3 6 4 0 0 0 0 0 0 0 0 0 0 0 3 2 6 7 6 0 0 0 0 0 0 0 0 0 0 7 8 2 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0];
    n = 2; % nombre de zéros minimum séparant les données
    idx = [zeros(1,n) V zeros(1,n)]~=0;
    debut = strfind(idx,[false(1,n) true]); % indices marquant le début de chaque groupe
    fin = strfind(idx,[true false(1,n)])-n; % indices marquant la fin de chaque groupe
    
    data = arrayfun(@(from, to) V(from:to) , debut,fin,'UniformOutput',false); % groupes
    data{:}
    
    [~,idxDMax] = arrayfun(@(from, to) max(V(from:to)) , debut,fin) ;% max de chaque groupe 
    idxDMax=idxDMax+debut-1;

  10. #10
    Invité
    Invité(e)
    Par défaut
    Cette syntaxe permet de créer ce que l'on appelle une fonction anonyme (ou anonymous Function en anglais). (from , to) représentent ses entrées (qui sont tour à tour tirées de debut et fin fournis à la fonction arrayfun), et V(from:to) ce qu'elle retourne.
    Tu pourras trouver plus de détails dans ce topic de la FAQ.

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

Discussions similaires

  1. Question bête sur l'écriture de données dans un fichier
    Par bourgui78 dans le forum Général Python
    Réponses: 9
    Dernier message: 27/03/2014, 15h23
  2. Group by et max sur une liste
    Par jbrasselet dans le forum Linq
    Réponses: 2
    Dernier message: 25/04/2012, 09h45
  3. Question sur la sélection de donnée dans une base
    Par Masmeta dans le forum Langage SQL
    Réponses: 2
    Dernier message: 17/04/2008, 17h16
  4. Réponses: 9
    Dernier message: 09/05/2006, 17h11
  5. question sur le rafraichissement des données dans la base
    Par vbcasimir dans le forum Bases de données
    Réponses: 8
    Dernier message: 06/06/2005, 13h44

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