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 :

Découpage d'un vecteur


Sujet :

MATLAB

  1. #1
    Membre chevronné
    Homme Profil pro
    Éternel universitaire
    Inscrit en
    Avril 2012
    Messages
    421
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Éternel universitaire

    Informations forums :
    Inscription : Avril 2012
    Messages : 421
    Par défaut Découpage d'un vecteur
    Bonjour,

    Voilà maintenant quelques heures que je me creuse la tête pour découper un vecteur d'une façon particulière.

    J'ai par exemple un vecteur Qobs90s (il s'appelle comme ça chez moi) qui est défini comme tel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Qobs90s=[31 22 71 -999 -999 12 31 11 -999 -999 17 -999 -999 21 41 -999]
    Ce que je veux, c'est extraire l'emplacement des chiffres précédents et suivants les -999 mais aussi ajouter 1 dans le cas où la série de commence pas par un -999 et ajouter une length(Qobs90s) dans le cas où la série ne se termine pas par un -999. Donc ici la réponse désirée serait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    idx =
    1 3
    6 8
    11 11
    14 15
    J'ai écris ce qui se trouve dessous mais je n'arrive pas à surmonter le problème où il y a deux -999 séparés seulement d'une seule valeur positive (ça fonctionne mais j'ai un nombre d'élément impair dans mon vecteur idx ce qui m’empêche d'utiliser le reshape). C'est un bout de code qui devrait préparer des bases de données et je voudrais donc qu'il soit robuste.

    Le petit bout de code :
    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
    28
    29
    Qobs90s=Qobs90s';
    idx=1;
    for m=1:length(Qobs90s)-1
        if Qobs90s(m)<0
            if Qobs90s(m-1)>0
                idx=[idx,m-1];
                if Qobs90s(m+1)>0
                    idx=[idx,m+1];
                end
            end
            if Qobs90s(m+1)>0
                idx=[idx,m+1];
            end
        end
    end
     
    idx=unique(idx);
     
    if idx==1
        idx=[1;length(Qobs90s)];
    else
        if Qobs90s(end)<0
            idx=reshape(idx,2,[]);
        else
            idx=[idx,length(Qobs90s)];
            idx=reshape(idx,2,[]);
        end
    end
    disp((idx'));
    Merci beaucoup à ceux qui auront des idées (et à ceux qui n'en n'auront pas mais qui auront pris le temps de lire ce message )

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

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    i= find(Qobs90s == -999); %indices des -999
    idx= [i(:)-1; i(:)+1]; % indices avant et après les -999
    idx= idx(idx>0 & idx <= length(Qobs90s ));
    idx= setdiff(idx,i); %enlève les -999 adjacents à un -999 (pas sur si c'est demandé)
     
    data= Qobs90s (idx);
    @FLB: ma méthode va effectivement doubler certaines valeurs, il faut rajouter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    idx= unique(idx); % enlève les doublons

  3. #3
    FLB
    FLB est déconnecté
    Modérateur
    Avatar de FLB
    Homme Profil pro
    Ing. Aérospatiale
    Inscrit en
    Juin 2003
    Messages
    770
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Ing. Aérospatiale
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juin 2003
    Messages : 770
    Par défaut
    Salut,
    je me permet d'ajouter une autre solution, moins sexy mais qui permet d'avoir le 11 en double.
    Je me suis inspiré du post http://www.developpez.net/forums/d89...zeros-vecteur/
    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
    %On commence par s'assurer de l'état des bords du vecteur
    if Qobs90s(1)>0
         Qobs90s = [-999 Qobs90s];
         enleverUn = 1;
    else
        enleverUn = 0;
    end
    if Qobs90s(end)>0
         Qobs90s = [Qobs90s -999];
    end
    snz=diff(find(~[0 Qobs90s>0 0]))-1 ; 
    numElem = snz(snz~=0);%on compte les suites de nombres positifs
    liste = find(Qobs90s>0); %pour aller chercher l'indice du premier et dernier element de chaque suite de nombres positifs
    idstart = cumsum([1 numElem(1:end-1)]);
    idend = cumsum(numElem(1:end));
    [liste(idstart)' liste(idend)']-enleverUn

  4. #4
    Membre chevronné
    Homme Profil pro
    Éternel universitaire
    Inscrit en
    Avril 2012
    Messages
    421
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Éternel universitaire

    Informations forums :
    Inscription : Avril 2012
    Messages : 421
    Par défaut
    Hehe ! Il semblerait en fait que ce ne soit pas si simple que ce que je pensais. Le code que FLB propose est en effet assez "sexy" mais il présente exactement le même problème que le mien, c'est à dire que pour une séquence -999 12 -999 il va me rendre [2] au lieu de [2,2]. Le deuxième code semble présenter quelque problèmes au niveau des indices...

    +astucieux l'usage du setdiff

  5. #5
    Membre chevronné
    Homme Profil pro
    Éternel universitaire
    Inscrit en
    Avril 2012
    Messages
    421
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Éternel universitaire

    Informations forums :
    Inscription : Avril 2012
    Messages : 421
    Par défaut
    Citation Envoyé par VV33D Voir le message
    @FLB: ma méthode va effectivement doubler certaines valeurs, il faut rajouter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    idx= unique(idx); % enlève les doublons
    Tu es certain que ta fonction puisse doubler les valeurs qui sont entourées de -999 de part et d'autre ? Je reprend l'exemple que j'ai posté dans mon message précédent : si on prend Qobs90s = -999 12 -999, idx= 2 et non pas 2 2 (ce que je désire)

  6. #6
    FLB
    FLB est déconnecté
    Modérateur
    Avatar de FLB
    Homme Profil pro
    Ing. Aérospatiale
    Inscrit en
    Juin 2003
    Messages
    770
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Ing. Aérospatiale
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juin 2003
    Messages : 770
    Par défaut
    si je lance mon code sur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Qobs90s=[-999 12 -999];
    J'obtiens
    C'est bien ce que tu veux, non?

  7. #7
    Invité
    Invité(e)
    Par défaut
    Bonsoir,

    Une autre solution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Qobs90s = [31 22 71 -999 -999 12 31 11 -999 -999 17 -999 -999 21 41 -999];
    idxBefore = strfind([Qobs90s==-999 true], [false true]);
    idxAfter = strfind([true Qobs90s==-999], [true false]);
     
    [idxAfter(:) idxBefore(:)]

  8. #8
    Membre chevronné
    Homme Profil pro
    Éternel universitaire
    Inscrit en
    Avril 2012
    Messages
    421
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Éternel universitaire

    Informations forums :
    Inscription : Avril 2012
    Messages : 421
    Par défaut
    Citation Envoyé par FLB Voir le message
    si je lance mon code sur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Qobs90s=[-999 12 -999];
    J'obtiens
    C'est bien ce que tu veux, non?
    Oui c'est ce que je veux... mais pas ce que j'obtiens.


  9. #9
    Membre chevronné
    Homme Profil pro
    Éternel universitaire
    Inscrit en
    Avril 2012
    Messages
    421
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Éternel universitaire

    Informations forums :
    Inscription : Avril 2012
    Messages : 421
    Par défaut
    Merci à tous. La solution de Winjerome me donne les résultats escomptés. (passer de la 20aine de ligne de mon code à 3 lignes qui fonctionnent mieux... je me dis que j'ai encore du chemin à faire ! )

    @VV33D. Bha... je comprends pas ce qui se passe !

  10. #10
    Membre Expert
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Par défaut
    Tu es certain que ta fonction puisse doubler les valeurs qui sont entourées de -999 de part et d'autre ?
    Je pensais au cas d'indices uniques. setdiff(a,b) lorsqu'il y a des doublons dans a enlève ces doublons pour être cohérent avec la notion d'ensemble (il me semble). Cela me permet aussi d'ignorer ce qu'il se passe au bord : si 1 est dans i lorsque je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    idx= [i(:)-1; i(:)+1]; et idx(idx>0 & idx <= length(Qobs90s ));
    Pour garder les doublons, je préférerais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    idx= find(values== -999);
    idx= [idx-1, idx+1];
    idx= idx(idx > 0 & idx<= length(values));
    idx( values(idx) == -999 )= [];

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

Discussions similaires

  1. Découpage de vecteur pour former une matrice
    Par Lord Bouillon dans le forum MATLAB
    Réponses: 6
    Dernier message: 08/07/2015, 18h01
  2. Opération de découpage d'un vecteur
    Par chiabodo dans le forum MATLAB
    Réponses: 10
    Dernier message: 29/10/2010, 16h29
  3. Récuperer les coordonnées d'un vecteur
    Par kerzut dans le forum OpenGL
    Réponses: 5
    Dernier message: 15/04/2003, 11h51
  4. Zoom sur des vecteurs ou lignes
    Par mat.M dans le forum Algorithmes et structures de données
    Réponses: 7
    Dernier message: 25/11/2002, 10h40
  5. matrices * vecteur
    Par delire8 dans le forum Algorithmes et structures de données
    Réponses: 15
    Dernier message: 07/09/2002, 14h15

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