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 :

Optimiser le comptage d'éléments dans un vecteur


Sujet :

MATLAB

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    182
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2007
    Messages : 182
    Points : 52
    Points
    52
    Par défaut Optimiser le comptage d'éléments dans un vecteur
    Hello à toutes et à tous,

    Voilà, je me heurte à un petit problème, j'ai un vecteur qui peut être de grande taille (en millions d'éléments), et je recherche dans celui-ci les valeurs qui ressortent 4 fois exactement.
    Etant donné la taille des vecteurs, j'essaie d'éviter les boucles, mais la je ne sais pas trop quoi faire...
    Un exemple pour illustrer ma question:

    A =
    57
    57
    57
    57
    58
    58
    58
    58
    59
    59
    64
    65
    65
    66
    66
    66
    66
    67
    ...

    Ce que je cherche à obtenir est donc (pour cet exemple): A = [57, 58, 66],

    Quelles pistes me conseillez vous?

    Merci par avance,

    Gian

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

    En combinant les fonctions DIFF et STRFIND.

  3. #3
    Modérateur

    Homme Profil pro
    Ingénieur en calculs scientifiques
    Inscrit en
    Août 2007
    Messages
    4 639
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Ingénieur en calculs scientifiques

    Informations forums :
    Inscription : Août 2007
    Messages : 4 639
    Points : 7 614
    Points
    7 614
    Par défaut
    Bonjour,

    on peut aussi utiliser les fonctions unique et hist.
    Pour une bonne utilisation des balises code c'est ici!
    Petit guide du voyageur MATLABien : Le forum La faq Les tutoriels Les sources


    La nature est un livre écrit en langage mathématique. Galilée.

  4. #4
    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
    Si j'ai bien compris winjerome, il faudrai que tu sort le vecteur avant.
    Regardes unique(), elle doit faire ce que tu veux (mais sera peut etre trop lente)

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    182
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2007
    Messages : 182
    Points : 52
    Points
    52
    Par défaut
    Merci pour ces bonnes idées, ceci dit unique() ne me permet que d'éliminer les doublons, j'ai besoin de réaliser le comptage avant, la piste de hist() me semble intéressante, mais je crois que cette fonction est relativement lente aussi (je dis ca, mais c'est à tester).

    Je pense aussi réaliser cette fonction en MEX (C++) avec des bêtes boucles for(), j'y gagnerais peut etre aussi...

    Je regarde ces pistes.

    Gian

  6. #6
    Membre du Club
    Homme Profil pro
    Étudiant:chaque jour on aprend des choses ;)
    Inscrit en
    Septembre 2011
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Espagne

    Informations professionnelles :
    Activité : Étudiant:chaque jour on aprend des choses ;)
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2011
    Messages : 43
    Points : 68
    Points
    68
    Par défaut
    Salut,

    Voice un code que je pense que fonctionne bien. N'est pas très ortodoxe, mais eficace

    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
    V = uint32(round(rand(1000000,1)*100000)+1);%Vecteur aleatoire avec valeurs entre 1 et 100000
    nrep=6;%Nombre de valeurs repetees dans le bloc
    V = sort(V);
    Vdiff = boolean([~boolean(diff(V));0]);
    %Construction matrice pour recherche des blocks avec exactement nrep elements par bloc
    %On ajoute colonnes en déplaçant une position a chaque fois le vecteur Vdiff
    for ii=1:nrep-1
        Vdiff(:,ii+1) = [0;Vdiff(1:end-1,ii)];
    end
    %Si la somme d'une ligne (sauf ça derniere colonne) est nrep-1, voila, on a un bloc avec >=nrep elements
    %Si la somme d'une ligne complet est nrep, le bloc a >nrep elements
    %Suprimme les elements du 2eme cas dans les element du 1er cas et ça y est.
    Vrep = setdiff(unique(V.*uint32(([sum(Vdiff(:,1:end-1),2)==nrep-1]))),unique(V.*uint32(([sum(Vdiff,2)==nrep]))));
     
    %Lignes pour tester que les calculs sont correctes.
    %CETTE PARTIE EST LA PLUS LENTE. A SUPPRIMER
    for jj=1:length(Vrep)
        if length(find(V==Vrep(jj)))~=nrep
            Vrep(jj)
        end
        if mod(jj,1000)==0
           jj 
        end
    end
    Le temps calcul que j'ai mesuré est 12 secondes pour un vecteur 10millon d'elements, 100mil valeurs possibles et bloc de 6 élements.

    Cordialement

  7. #7
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par VV33D Voir le message
    Si j'ai bien compris winjerome, il faudrai que tu sort le vecteur avant.
    Oui c'est bien cela, ce qui semble être le cas dans l'exemple de Giansolo.
    Ce qui donnerait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    A =[57 57 57 57 58 58 58 58 59 59 64 65 65 66 66 66 66 67];
    NbRep = 4;
    D = ~diff([Inf A Inf]);
    Vrep = A(strfind(D,[false true(1,NbRep-1) false]));
    @KR4ZY_GUI: quelques remarques sur ton code:
    • length(find(V==Vrep(jj))) peut s'écrire plus simplement: sum(V==Vrep(jj));
    • De même uint32(round(rand(1000000,1)*100000)+1); en randi(100000,1000000,1,'uint32');
    • Les crochets:
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      Vrep = setdiff(unique(V.*uint32(([sum(Vdiff(:,1:end-1),2)==nrep-1]))),unique(V.*uint32(([sum(Vdiff,2)==nrep]))));
      N'ont pas lieu d'être.

  8. #8
    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 magelan Voir le message
    on peut aussi utiliser les fonctions unique et hist.
    Plutôt HISTC :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    [uA,a,b] = unique(A);
    n = histc(b,unique(b));
     
    uA(n==4)
    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)

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    182
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2007
    Messages : 182
    Points : 52
    Points
    52
    Par défaut
    Merci pour ces réponses très documentées! Un vrai plaisir ce forum
    Je vais tester un peu les temps d’exécutions et je verrais pour prendre le plus rapide.

    Merci à vous!

    Gian

  10. #10
    Modérateur

    Homme Profil pro
    Ingénieur en calculs scientifiques
    Inscrit en
    Août 2007
    Messages
    4 639
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Ingénieur en calculs scientifiques

    Informations forums :
    Inscription : Août 2007
    Messages : 4 639
    Points : 7 614
    Points
    7 614
    Par défaut
    Citation Envoyé par Dut Voir le message
    Plutôt HISTC :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    [uA,a,b] = unique(A);
    n = histc(b,unique(b));
     
    uA(n==4)
    C'est vrai que hist fera appel à histc, donc autant utiliser directement histc. Par contre on peut économiser un appel de unique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    uA = unique(A);
    n = histc(A,uA);
     
    uA(n==4)
    Pour une bonne utilisation des balises code c'est ici!
    Petit guide du voyageur MATLABien : Le forum La faq Les tutoriels Les sources


    La nature est un livre écrit en langage mathématique. Galilée.

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

Discussions similaires

  1. Réponses: 24
    Dernier message: 19/03/2009, 16h18
  2. recherche un élément dans un vecteur trié
    Par jena dans le forum Signal
    Réponses: 5
    Dernier message: 10/12/2008, 12h02
  3. Suppression d'un élément dans un vecteur
    Par C.R.E.A.M dans le forum SL & STL
    Réponses: 6
    Dernier message: 02/02/2008, 23h11
  4. Comptage d'élèments dans une chaine
    Par wabo67 dans le forum Excel
    Réponses: 2
    Dernier message: 09/11/2007, 12h32
  5. Comptage d'élèments dans une chaine
    Par zephirsoul dans le forum Excel
    Réponses: 3
    Dernier message: 05/11/2007, 16h44

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