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 :

tri d'un array de array


Sujet :

Langage Perl

  1. #1
    Membre émérite
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 44
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Points : 2 673
    Points
    2 673
    Par défaut tri d'un array de array
    Bonjour à tous,

    J'ai des données sous cette forme :
    Source.Name Characteristics.Subject.ID. Characteristics.Strain. Sample.Name
    atenolol_3_1000_1 102599 RATM Rattus norvegicus
    atenolol_3_1000_2 102613 RATM Rattus norvegicus
    atenolol_3_1000_3 102633 RATM Rattus norvegicus
    Que je place dans un array de array.

    $tab[$i][$j]

    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    @{$tab[0]} = ('Source.Name', 'Characteristics.Subject.ID.', 'Characteristics.Strain.', 'Characteristics.Organism.');
    @{$tab[1]} = ('atenolol_3_1000_1', '102599', 'RATM', 'Rattus norvegicus');
    @{$tab[2]} =  ('atenolol_3_1000_2', '102613', 'RATM', 'Rattus norvegicus');
    @{$tab[3]} =  ('atenolol_3_1000_3', '102633', 'RATM', 'Rattus norvegicus');
    si
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my @order = ('Characteristics.Strain.', 'Source.Name', 'Characteristics.Organism.', 'Characteristics.Subject.ID.');
    je veux que mon array de array soit réorganisé ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    @{$tab[0]} = ('Characteristics.Strain.', 'Source.Name', 'Characteristics.Organism.', 'Characteristics.Subject.ID.');
    @{$tab[1]} = ('RATM', 'atenolol_3_1000_1', 'Rattus norvegicus' , '102599');
    @{$tab[2]} =  ('RATM', 'atenolol_3_1000_2', 'Rattus norvegicus', '102613');
    @{$tab[3]} =  ('RATM', 'atenolol_3_1000_3', 'Rattus norvegicus', '102633');
    Les valeurs excédentaires, ne se trouvant pas dans @order, doivent être supprimées. @{$tab[1]} aura la même taille que @order et sera plus petite que sa taille initiale.
    Si ce n'est pas clair, n'hésitez pas à me poser des questions. Je vais continuer de regarder du côté de List::Compare et de List::MoreUtils ... et sort.


    D'avance merci.

    Voici mon 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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    #!/usr/bin/perl
     
    use strict;
    use warnings;
     
    use WWW::Mechanize::Query;
    use Data::Dumper;
     
    my $mech = WWW::Mechanize::Query->new();
     
    my $url= "ftp://ftp.ebi.ac.uk/pub/databases/microarray/data/dixa/DrugMatrix/archive/thighMuscle/s_thigh_muscle.txt";
    $mech->get($url);
     
    my @orders = qw/Sample.Name
    Source.Name
    Characteristics.Subject.ID.
    Characteristics.Strain.
    Characteristics.Organism.
    Characteristics.Sex.
    Factor.Value.Age.
    Characteristics.AgeUnit.
    Characteristics.Organ.
    Characteristics.Tissue.
    Characteristics.Cell.
    Characteristics.Assay.Type.
    Characteristics.Biological.Replicate.
    Characteristics.Technical.Replicate.
    Factor.Value.Compound.
    Characteristics.StdInChIKey.
    Comment.chEMBL.ID.
    Characteristics.Eniantiomer.
    Characteristics.Compound.Class.
    Characteristics.Control.
    Characteristics.Sample.Match.
    Factor.Value.Dose.
    Characteristics.DoseUnit.
    Factor.Value.Dose.Duration.
    Characteristics.Dose.DurationUnit.
    Factor.Value.Dose.Frequency.
    Characteristics.Vehicle.
    Characteristics.Route.
    Factor.Value.Sample.TimePoint.
    Characteristics.Sample.TimePointUnit.
    Characteristics.Treatment.Group./;
     
    if ($mech->success()) {
     
    	my ($file_name) = ($url =~ m/([^\/]*\.txt)/);
    	print $file_name."\n";
     
    	my @data = split (/\n/, ${$mech}{'content'});
     
    	my @tab;	
    	foreach my $i (0..$#data){ 
    		 @{$tab[$i]} = split (/\t/, $data[$i]);
    	}
     
    	print Dumper @tab;
     
    }
    -- Jasmine --

  2. #2
    Membre émérite
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 44
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Points : 2 673
    Points
    2 673
    Par défaut
    Voici un code (peut-être pas très beau) qui fonctionne :
    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
    if ($mech->success()) {
     
    	my ($file_name) = ($url =~ m/([^\/]*\.txt)/);
     
    	my @data = split (/\n/, ${$mech}{'content'});
    	 # foreach my $d (@data){$d=chomp($d)}
    	 #  map {chomp($_)} @data;
     
    	my @headers= split (/\t/, $data[0]);
     
    	my @index_list;
    	foreach my $v (@orders){
    		my $i = firstidx { $_ eq $v }  @headers;
    		push @index_list, $i;
    	}
     
    	my @tab;
    	my @tab_trans;
    	foreach my $i (0..$#data){ 
    		 @{$tab[$i]} = split (/\t/, $data[$i]);
     
    		 for my $j (0..$#index_list){
    			 my $j_trans=$index_list[$j];  
    			 $tab_trans[$i][$j]= $tab[$i][$j_trans]; 
    		 }		 
    	}
     
    	print Dumper @tab_trans;
    }
    1) Il me reste juste un problème du chomp qui ne fonctionne pas. Il reste un saut de ligne aux valeurs $tab_trans[$i][0] (qui vient de $tab[$i][-1]). Peut-être pcq le fichier vient d'n serveur linux.
    2) Toute proposition, de quelque chose de mieux, est la bien venue. J'ai vu qu'avec le sort, on peut aller très loin dans le tri de matrices, et aussi avec des transformations (Schwartzian transform) ... mais, c'est de trop haut niveau pour moi.
    Si ça intéresse quelqu'un, je trouve ce lien très intéressant, je vais m'y pencher et essayer de comprendre : http://mpihowto.com/index.php/perl/p...-sort-function

    PS : ajouter au code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    use List::MoreUtils qw(firstidx);

    D'avance merci,
    -- Jasmine --

  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
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    Bonjour Jasmine,

    à mon avis, un tableau de hachages serait sans doute plus pratique qu'un tableaux de tableaux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     
    %{$tab[1]} = (  Source.name                    => 'atenolol_3_1000_1',
                    Characteristics.Subject.ID.    => '102599', 
                    Characteristics.Strain.        => 'RATM', 
                    Characteristics.Organism.      => 'Rattus norvegicus'
                 );
    Ce qui peut aussi s'écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     
    $tab[1]}= {  Source.name                  => 'atenolol_3_1000_1',
                 Characteristics.Subject.ID.  => '102599', 
                 Characteristics.Strain.      => 'RATM', 
                 Characteristics.Organism.    => 'Rattus norvegicus'
              };
    ou, en simplifiant les intitulés:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    %{$tab[1]} = (  name =>      'atenolol_3_1000_1',
                    ID =>        '102599', 
                    Strain =>    'RATM', 
                    Organism =>  'Rattus norvegicus',
                 );
    Ensuite, si tu as cette commande:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    my @order = ('Characteristics.Strain.', 'Source.Name', 'Characteristics.Organism.', 'Characteristics.Subject.ID.');
    Quelque chose du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    my $line[$i] = [ map { $tab[1]{$_} } @order ];
    Ou, si tu préfères garder un tableaux de tableaux, alors faire un hachage de paramétrage faisant la liaison entre le nom des champs et les numéros des champs dans le tableau, un truc du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    my %fields = (
                      Source.Name    => 0, 
                      Characteristics.Subject.ID.=> 1,
                      Characteristics.Strain. => 2,
                      Characteristics.Organism. => 3,
                       => 3, 
                  );
    et un map pour faire la transcodification:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    my $line[$i] = [ map {  $tab[1]{$fields{$_} } } @order ];
    Si chomp ne marche pas (incompatibilités Linux /windows) remplace
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ... map {chomp($_)} @data;
    par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ... map { s/[\n\r]+// } @ data;
    Et, franchement, la transformation de Schwartz n'a rien de bien compliqué. Jette un coup d’œil à mon tuto abordant le sujet: http://laurent-rosenfeld.developpez....ris de données.

    Mais n'hésite pas à demander si tu cherches à en faire une et cales sur quelque chose.

    NB: j'ai écrit tout le code ci-dessus sans tester quoi que ce soit (pas le temps là tout de suite), il y a peut-être une petite erreur ici ou là, mais ça devrait donner l'idée.

  4. #4
    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
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    Re-bonsoir,

    voici un petit programme lancé à la ligne de commande qui semble faire à peu près ce que tu recherches:
    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
     
    $ perl -E  'use strict;
    > use warnings;
    >
    > my @tab;
    > @{$tab[0]} = ("Source.Name", "Characteristics.Subject.ID.", "Characteristics.Strain.", "Characteristics.Organism.");
    > @{$tab[1]} = ("RATM", "atenolol_3_1000_1", "Rattus norvegicus" , "102599");
    > @{$tab[2]} =  ("RATM", "atenolol_3_1000_2", "Rattus norvegicus", "102613");
    > @{$tab[3]} =  ("RATM", "atenolol_3_1000_3", "Rattus norvegicus", "102633");
    >
    > my %fields = (
    >                   "Source.Name"    => 0,
    >                   "Characteristics.Subject.ID." => 1,
    >                   "Characteristics.Strain." => 2,
    >                   "Characteristics.Organism." => 3,
    >               );
    >
    >
    > my @order = ("Characteristics.Strain.", "Source.Name", "Characteristics.Organism.", "Characteristics.Subject.ID.");
    >
    > for my $record (1..$#tab) {
    >     my @line =   @{$tab[$record]}[@fields{@order}];
    >     say join " ", @line;
    > }
    > '
    Rattus norvegicus RATM 102599 atenolol_3_1000_1
    Rattus norvegicus RATM 102613 atenolol_3_1000_2
    Rattus norvegicus RATM 102633 atenolol_3_1000_3
    La seule difficulté est dans la ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    my @line =   @{$tab[$record]}[@fields{@order}];
    On a:
    - @fields{@order} renvoie la liste des numéros de champs dans l'ordre (et au nombre) dans lequel il faut les prendre;
    - @{$tab[$record]} renvoie le tableau de l'enregistrement courant;
    - Au total, la ligne renvoie le tableau de l'enregistrement courant, avec les champs réorganisés dans l'ordre voulu.

    En changeant le tableau @order avec seulement deux champs:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    my @order = ("Source.Name", "Characteristics.Organism.");
    ça imprime que deux champs de chaque ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    RATM 102599
    RATM 102613
    RATM 102633

  5. #5
    Membre émérite
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 44
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Points : 2 673
    Points
    2 673
    Par défaut
    Bonjour Lolo,

    Je te remercie pour tes explications, j'ai réécrit mon script suivant tes conseils. Pour le saut de ligne à la linux, cela ne pose maintenant plus de problème.
    Pour tes tris et les transformations, je me pencherai sur ton tuto quand j'aurai un peu plus de temps.

    Je te remerci et te souhaite une bonne journée,

    Jasmine.

    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
     
    if ($mech->success()) {
     
    	my ($file_name) = ($url =~ m/([^\/]*\.txt)/);
     
    	my @data = split (/\n/, ${$mech}{'content'});
    	map { s/[\n\r]+// } @ data;
     
    	my @tab;
    	foreach my $i (0..$#data){ 
    		 @{$tab[$i]} = split (/\t/, $data[$i]);	 
    	}
     
    	my @headers= split (/\t/, $data[0]);
     
    	my %fields;
    	foreach my $i (0..$#headers){ 
    		$fields{$headers[$i]}=$i;
    	}
     
     
    	for my $record (1..$#tab) {
    	     my @line =   @{$tab[$record]}[@fields{@order}];
    	     say join " ", @line;
    	}
     
    }
    -- Jasmine --

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

Discussions similaires

  1. [Débutant] Tri doublon par colonne sur array à deux dimensions
    Par Greenlynx dans le forum VB.NET
    Réponses: 2
    Dernier message: 10/07/2015, 20h24
  2. [JavaScript] [FAQ] Tri alphanumérique d'un tableau (array)
    Par danielhagnoul dans le forum Contribuez
    Réponses: 1
    Dernier message: 16/12/2014, 23h52
  3. [Tableaux] array => fichier => array ?
    Par adimou dans le forum Langage
    Réponses: 2
    Dernier message: 26/08/2007, 21h22
  4. Déclaration de type array of array of variant
    Par Drooxy dans le forum Delphi
    Réponses: 4
    Dernier message: 14/12/2006, 19h25
  5. Comment faire le tri d'un array of array ?
    Par Tchouffy dans le forum Langage
    Réponses: 1
    Dernier message: 16/06/2005, 20h55

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