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

Langage Perl Discussion :

parcours d'un tableau et suppression d'élements


Sujet :

Langage Perl

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Janvier 2010
    Messages
    257
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 257
    Par défaut parcours d'un tableau et suppression d'élements
    Bonjour à tous,
    J'ai un problème que je ne parviens pas à résoudre.
    J'ai un fichier qui ressemble à ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    AAAACCCGAAACCGTTTAGCTGT
    AAAAACCCGAAACCGTTTAGCTGT
    AAAACCCGAAACCGTTTAGCTGTT
    AAAACCCGAAACCGTTTAGCTGTTC
    AAAACCCGAAACCGTTTAGCTGTTT
    AAAACCCGAAACCGTTTAGCTGTTCT
    AGAAAAACCCGAAACCGTTTAGCTGT
    AAAACCCGAAACCGTTTAGCTGTTCTC
    AAAACCCGAAACCGTTTAGCTGTTCTCC
    AAAACCCGAAACCGTTTAGCTGTTCTCCG
    ATAACCCGAAACCGTTTAGCTGTTCTCCG
    Tous les séquences sont rangées par taille et par ordre alphabétique dans mon fichier.

    Je souhaite supprimer la redondance en supprimant toutes les séquences contenant entièrement une autre séquences (le début doit être identique )par exemple :
    Par exemple, pour la première séquence :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AAAACCCGAAACCGTTTAGCTGT
    j'ai toutes ces séquences :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    AAAACCCGAAACCGTTTAGCTGTT
    AAAACCCGAAACCGTTTAGCTGTTC
    AAAACCCGAAACCGTTTAGCTGTTT
    AAAACCCGAAACCGTTTAGCTGTTCT
    AAAACCCGAAACCGTTTAGCTGTTCTC
    AAAACCCGAAACCGTTTAGCTGTTCTCC
    AAAACCCGAAACCGTTTAGCTGTTCTCCG
    Mais je ne souhaite garder que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AAAACCCGAAACCGTTTAGCTGT
    puisque toutes les autres séquences commencent par cette séquence.
    A la fin, j'aimerai avoir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    AAAACCCGAAACCGTTTAGCTGT
    AAAAACCCGAAACCGTTTAGCTGT
    AGAAAAACCCGAAACCGTTTAGCTGT
    ATAACCCGAAACCGTTTAGCTGTTCTCCG
    J'ai donc écris ce script perl :
    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
    my ($file_file,$out_file);
    my (%hash,%dico);
    my (@results,@sort_all_seq,@tmp);
     
    GetOptions("file=s" => \$file_file); 
    open(my $file,'<',$file_file) or die "$file_file : $!\n\n";
     
    while(<$file>){
            chomp;
            push(@sort_all_seq,$_);
    }
    print "seq in array : OK !\n";
     
    my $i=0;
    foreach my $value(@sort_all_seq){
    	push(@tmp,$value);
    	my @dix = grep  { $sort_all_seq[$_] =~ m/^$value/ } 0..$#sort_all_seq ;
    	push(@tmp,$value) if(scalar(@dix)>1);
    	my $o = 0;
    	foreach my $val (@dix) {
        		splice (@sort_all_seq,$val-$o,1);	
    		$o++;
     
    	}   	
    	$i++;	
    }
    print "tmp : @tmp\n";
    qui me retourne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    AAAACCCGAAACCGTTTAGCTGT 
    AAAACCCGAAACCGTTTAGCTGT 
    AGAAAAACCCGAAACCGTTTAGCTGT
    Je pense que cela vient du fait que je modifie à chaque fois mon tableau @sort_all_seq.
    Auriez vous une idée pour résoudre mon problème ?
    Merci d'avance

  2. #2
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Billets dans le blog
    1
    Par défaut
    Hmmm, modifier un tableau (ajouter ou retirer des éléments) alors que l'on est en train de le balayer avec une boucle for est une mauvaise idée.

    Lis ton tableau et travaille sur une copie du même tableau. Quelque chose comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    my @result = @sort_all_seq;
    foreach my $value(@sort_all_seq){
         @result = grep { not m/^$value/ } @result ; # note comment cette syntaxe est plus simple
         unshift @result, $value;
    }
    On pourrait ajouter des optimisations, mais l'essentiel y est.

  3. #3
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Billets dans le blog
    1
    Par défaut
    En fait, en y réfléchissant, l'optimisation à laquelle je pensais n'est pas seulement une optimisation, elle est nécessaire au bon fonctionnement de l'algo.

    Je te propose ceci:

    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
     
    use strict;
    use warnings;
    use feature qw /say/;
     
    my @sort_all_seq = split /\s+/, 
    "AAAACCCGAAACCGTTTAGCTGT
    AAAAACCCGAAACCGTTTAGCTGT
    AAAACCCGAAACCGTTTAGCTGTT
    AAAACCCGAAACCGTTTAGCTGTTC
    AAAACCCGAAACCGTTTAGCTGTTT
    AAAACCCGAAACCGTTTAGCTGTTCT
    AGAAAAACCCGAAACCGTTTAGCTGT
    AAAACCCGAAACCGTTTAGCTGTTCTC
    AAAACCCGAAACCGTTTAGCTGTTCTCC
    AAAACCCGAAACCGTTTAGCTGTTCTCCG
    ATAACCCGAAACCGTTTAGCTGTTCTCCG";
     
     
    my @result = @sort_all_seq;
    my $old_val= "W"; # une valeur quelconque qui ne peut être reconnue dans les chaînes de bases
    foreach my $value(@sort_all_seq){
         next if $value =~ $old_val; # l'optimisation nécessaire au bon fonctionnement
         @result = grep { not /^$value/ } @result ; # note comment cette syntaxe est plus simple
         unshift @result, $value; # on a éliminé toutes les chaines ressemblant à $value, il faut remettre $value
         $old_val = $value;
    }
    print "$_\n" for sort {length ($a) <=> length ($b)} @result;
    Ce qui imprime:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ perl tableau_genes.pl
     
    AAAACCCGAAACCGTTTAGCTGT
    AAAAACCCGAAACCGTTTAGCTGT
    AGAAAAACCCGAAACCGTTTAGCTGT
    ATAACCCGAAACCGTTTAGCTGTTCTCCG

  4. #4
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 986
    Par défaut
    @Lolo78, n'y aurait il pas intérêt à trier le tableau auparavant?

    Quelque chose comme ça?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    foreach my $val(sort @sort_all_seq) {
        if ($val !~ /^$old_value/) {
            print "$val\n";
            $old_value = $val;
        }
    }

  5. #5
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Billets dans le blog
    1
    Par défaut
    Oui, tu as raison. J'avais compris que le fichier d'origine était trié, mais il est fait trié par taille de séquence. Pour que la variable $old_val puisse pleinement jouer son rôle, il faudrait tries les données par ordre alphabétique. En revanche, comme le tableau @sort_all_seq n'est modifié à aucun moment, il faut le trier une seule fois, avant d'entrer dans la boucle for, et pas dans la bouclo for. Ce qui donne (pas testé):

    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
     
    use strict;
    use warnings;
    use feature qw /say/;
     
    my @sort_all_seq = sort split /\s+/, 
    "AAAACCCGAAACCGTTTAGCTGT
    AAAAACCCGAAACCGTTTAGCTGT
    AAAACCCGAAACCGTTTAGCTGTT
    AAAACCCGAAACCGTTTAGCTGTTC
    AAAACCCGAAACCGTTTAGCTGTTT
    AAAACCCGAAACCGTTTAGCTGTTCT
    AGAAAAACCCGAAACCGTTTAGCTGT
    AAAACCCGAAACCGTTTAGCTGTTCTC
    AAAACCCGAAACCGTTTAGCTGTTCTCC
    AAAACCCGAAACCGTTTAGCTGTTCTCCG
    ATAACCCGAAACCGTTTAGCTGTTCTCCG";
     
     
    my @result = @sort_all_seq;
    my $old_val= "W"; # une valeur quelconque qui ne peut être reconnue dans les chaînes de bases
    foreach my $value(@sort_all_seq){
         next if $value =~ $old_val; # l'optimisation nécessaire au bon fonctionnement
         @result = grep { not /^$value/ } @result ; # note comment cette syntaxe est plus simple
         unshift @result, $value; # on a éliminé toutes les chaines ressemblant à $value, il faut remettre $value
         $old_val = $value;
    }
    print "$_\n" for sort {length ($a) <=> length ($b)} @result;
    Mais je pense que ça marchera mieux et sans tri d'aucune sorte si on remplace ces deux lignes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        @result = grep { not /^$value/ } @result ; # note comment cette syntaxe est plus simple
         unshift @result, $value;
    par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
         @result = grep { $_ eq $value or not /^$value/ } @result ;

  6. #6
    Membre éclairé
    Inscrit en
    Janvier 2010
    Messages
    257
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 257
    Par défaut
    Merci.
    En fait, je voulais supprimer les éléments de mon tableau au fur et à mesure car j'ai beaucoup de séquences (4millions de séquences uniques) et je voulais limiter le temps de calcul au maximum. J'avais essayé autre chose et le script à tourner 3 jours sans me donner de résultat ...
    Je vais essayer avec votre solution et voir ce que ça donne !

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

Discussions similaires

  1. [Tableaux] Parcours d'un tableau
    Par wormseric dans le forum Langage
    Réponses: 2
    Dernier message: 31/10/2006, 13h53
  2. [MySQL] Parcours d'un tableau et suppression des entrées
    Par padoberg dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 18/07/2006, 13h41
  3. probleme de parcours d'un tableau
    Par rodriguez_du35 dans le forum Langage
    Réponses: 4
    Dernier message: 29/05/2006, 09h16
  4. parcours d un tableau de l interface graphique
    Par natasha84 dans le forum MFC
    Réponses: 7
    Dernier message: 26/05/2006, 23h29
  5. Parcour d un tableau dynamique
    Par harris_macken dans le forum Débuter
    Réponses: 12
    Dernier message: 24/05/2005, 22h23

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