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 :

Utiliser le script vlookup en boucle


Sujet :

MATLAB

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2012
    Messages
    200
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 200
    Points : 46
    Points
    46
    Par défaut Utiliser le script vlookup en boucle
    Hello, je me permets d'exposer mon problème.

    J'ai un vecteur de date noté : date;
    Une matrice notée M avec en colonne 1 des dates et en 2ème des valeurs.

    Je souhaite créer une matrice C avec en première colonne le vecteur date (complet), et en 2ème colonne la valeur de la 2ème colonne correspond à la date.

    J'utilise le script vlookup trouvé sur google :

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
     
    function [content, index] = vlookup(m, e, column, lookcolumn)
    %VLOOKUP the function as vlookup in Excel
    %
    %   [content, index] = vlookup(m, e, column, lookcolumn) look for 'e' in 
    %   the 'lookcolumn'-th column of 'm', and return the coresponding
    %   'column'-th element of 'm' in the same row.
    %
    %   the 'm' could be a numeric matrix of a cell matrix.
    % 
    %   lookcolumn is 1 by default if omitted.
    % 
    % Example:
    % 
    %     m = {1, 'a', [2 3];
    %     2, 'b', 'cd'
    %     3, 'a', true;};
    %      [content, index] = vlookup(m, 'a', 3, 2) then
    %     content = {[2 3], 1};
    %     index = [1;3]
     
    % Copyright: zhang@zhiqiang.org, 2010
    % author: http://zhiqiang.org/blog/tag/matlab
     
    if isempty(m) || isempty(e), return; end
    if nargin <= 3, lookcolumn = 1; end
     
    isechar = ischar(e);
    assert(isechar || isnumeric(e), 'the second parameter must be a string or numeric');
     
    if iscell(m)
        content = {}; index = [];
        if isechar
            index = find(strcmp(e, m(:, lookcolumn)));
            content = m(index, column);
        else
            for i = 1:size(m, 1)
                if isnumeric(m{i, lookcolumn}) && m{i, lookcolumn} == e
                    content = [content; m(i, column)]; %#ok<*AGROW>
                    index = [index; i];
                end
            end
        end
    else
        assert(~isechar, 'When the first para is a matrix, the second para must be numeric');
     
        index = find(m(:, lookcolumn) == e);
        content = m(index, column);
    end

    En suivant le commentaire du script j'écris :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
      for k=1:numel(date)
             e=date(k,1); %Permet d'avoir la valeur à chercher dans la 1ère colonne de M 
             [content, index] = vlookup(M, e, 2, 1); %Vlookup qui renvoi dans content, la valeur de la 2ème colonne de  lorsque "e" est trouvé dans la première colonne.  de M 
     
             C=date; %Création d'une matrice pour avoir toutes les dates en 1ère colonne et 2ème colonne la valeur correspondant 
             C(k,2)=content; %Ici le problème les dimensions ne passe pas 
     
         end
    Donc mon problème vient des dimensions dans la dernière ligne, comme dans C, la première colonne de C contient toutes les dates, je pensais que lorsque k correspond à une date non trouvé dans M, C(k,2) sera remplacé par rien, et dans le cas où "e" est trouvé dans M, alors C(k,2) sera remplacé par le scalaire contenu dans l'output de vlookup "content".

    Mais cela ne fonctionne pas, une idée ?

    Merci

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2012
    Messages
    200
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 200
    Points : 46
    Points
    46
    Par défaut
    Le problème de dimension vient du fait que lorsqu'il ne trouve pas la valeur, content est une matrice vide 0x1;

    Donc il y'a un problème de dimension, comment régler ce problème ? merci

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

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for k=1:numel(date)
        ...      
        C=date;
         ...   
    end
    Si tu réassigne date à C à chaque itération, tu perds les C(k,2)=content; que tu mers aux tours précédents. => Cette ligne serait à mettre avant la boucle.

    Pour ce qui est de l'erreur sur la dimension, cela arrive lorsque content est vide alors que C(k,2) attend une valeur. => Une simple vérification if ~isempty(content) suffit. Remarque : la date correspondante n'étant pas trouvée, tu voudras peut-être y mettre une valeur spéciale du genre NaN.

    À noter que tu peux faire ceci simplement avec la fonction ismember :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    C = [date(:,1) nan(size(date,1),1)];
    [idx, loc] = ismember(C(:,1), M(:,1));
    C(idx,2) = M(loc(loc>0),2);

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2012
    Messages
    200
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 200
    Points : 46
    Points
    46
    Par défaut
    Ta seconde solution me renvoie l'erreur suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Conversion to struct from double is not possible.
    
    Error in Import_spread_script (line 41)
            C = [date(:,1) nan(size(date,1),1)];
     


    Mais j'ai réussi avec une boucle, j'ai ma matrice, j'ai mis 0 quand content est 0x1.

    Maintenant je souhaiterais supprimer les colonnes dont le nombre de zéro est >10 ou dont le nombre de NaN est > 10

    J'ai coder ça :

    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
     
    [n,p] = size(C);
     
    for i = 1:p
     
        A=isnan(C(:,i));
        A=sum(A);
        B=length(find(C(:,i)==0));
     
        if A > 20 || B>10
     
            C(:,i)=[];
     
            p=p-1;
        end
    end
    Le problème vient de la taille de C qui diminue et le p=p-1 ne permet pas de palier le problème, ce qui fait que je dépasse la taille de la matrice.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Pour l'erreur, je soupçonne que tu aies une variable nan déjà définie.
    Il faut éviter de définir des variables du même nom que des fonctions MATLAB. (C'est d'ailleurs aussi le cas pour date.)
    Cf. Conventions de noms : variables.

    B=length(find(C(:,i)==0)); peut se simplifier en B = sum(C(:,i)==0);.

    Tu trouveras sinon la réponse dans la FAQ.

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2012
    Messages
    200
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 200
    Points : 46
    Points
    46
    Par défaut
    Merci pour ta réponse c'est corriger,

    dans la FAQ j'ai uniquement trouvé comment supprimer une colonne, mais ça ne répond pas à mon problème :

    http://matlab.developpez.com/faq/?pa...uter_supprimer

  7. #7
    Invité
    Invité(e)
    Par défaut
    N'as-tu pas rencontré un message d'erreur ?

    => Index of element to remove exceeds matrix dimensions.

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2012
    Messages
    200
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 200
    Points : 46
    Points
    46
    Par défaut
    Merci je ne pensais pas trouver ça là !

  9. #9
    Invité
    Invité(e)
    Par défaut
    À noter que ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    n = 10;
    for i = 1:n
       disp(i)
       n = n-1;
    end
    n'ira pas jusqu'à 5 comme on pourrait le penser, mais bien jusqu'à 10.
    La limite supérieure for i = 1:n est fixée dès cette ligne et constante tout le long de la boucle. Modifier la valeur de n n'y changera rien.

    => Si tu souhaites avoir une limite non fixe, utilise une boucle while.

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2012
    Messages
    200
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 200
    Points : 46
    Points
    46
    Par défaut
    Parfait merci beaucoup pour ton aide, tout fonctionne parfaitement !

Discussions similaires

  1. Utiliser un script perl en php
    Par Batmat01 dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 05/07/2006, 14h31
  2. [VB.Net] Comment utiliser du script xml ?
    Par manu49 dans le forum VB.NET
    Réponses: 3
    Dernier message: 13/04/2006, 10h21
  3. Réponses: 3
    Dernier message: 31/01/2006, 15h54
  4. utiliser un script pour inserer des objets 3D
    Par s_mihai dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 09/08/2005, 13h52
  5. Réponses: 4
    Dernier message: 02/11/2004, 15h18

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