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 :

hash de hash sans tri


Sujet :

Langage Perl

  1. #1
    Membre régulier
    Inscrit en
    Mars 2010
    Messages
    157
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 157
    Points : 80
    Points
    80
    Par défaut hash de hash sans tri
    Bonsoir,

    J'ai fais un code qui permet de lire des lignes à partir de deux fichiers, j'ai utilisé un hash de hash

    Le problème c'est que ces résultats sont triés automatiques par les hash, alors que moi je veux qu'elle soit triés selon des valeurs particulières:

    les fichier d'origine sont triés et on les deux cette forme:
    1 Q0 DerOpthalmologe/80950033 0 5.960979448916666 TF_IDF
    1 Q0 DerRadiologe/80380710 1 5.836199971080442 TF_IDF
    1 Q0 MonatsschriftKinderheilkunde/01480013 2 5.836199971080442 TF_IDF
    1 Q0 DerHautarzt/90500127 3 5.601683110384085 TF_IDF
    1 Q0 DerAnaesthesist/80470024 4 5.4913531937974644 TF_IDF
    2 Q0 ZfuerKardiologie/90880788 0 7.950456651153142 TF_IDF
    2 Q0 DerChirurg/90701174 1 7.677017765795651 TF_IDF
    2 Q0 DerUnfallchirurg/81010830 2 7.503564829783422 TF_IDF
    2 Q0 DerChirurg/80690854 3 7.503564829783422 TF_IDF

    le problème c'est que les scores c'est à dire le 4ème champs de la ligne n'est plus triés, les valeurs sont hasard, de même pour le premier champs ou on peut trouver le numéro 103 au début puis 19, comment triés ces résultats selon le champs 1 puis le champs 4?

    voila 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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    #!/usr/bin/perl
     
    print "bonjour\n";
    open(FIC, $ARGV[0]);
    open(FICC, $ARGV[1]);
     
      my @a = ();
      my @b = ();
      my $l=0;
      my $v=0;
     
    print "choisis un nom de fichier\n";
     
     
    chomp(my $fic2=<STDIN>);
    open(FIC2, ">$fic2");
     
     
     
    $i=0;
    $j=0;
    $u=0;
     
    while (<FIC>) {
    my $ligne=$_;
     
    @aa=split(/\s/,$ligne);
    $who = $aa[0];
     
     
            $key=$aa[2]; 
            $HoH{$who}{$key} = $aa[4];
     
     
     
     
     
    $i++;
    }
     
     
     
    while (<FICC>) {
    my $ligne=$_;
     
    @aa=split(/\s/,$ligne);
    $who = $aa[0];
     
     
            $key=$aa[2];
            $HoH2{$who}{$key} = $aa[4];
     
     
     
     
     
    $i++;
    }
    print "\n";
     
     
    foreach my $k (  keys %HoH2){
    #print "$k: ";
    $i=0;
    foreach (  keys%{HoH2{$k}}){
     
    $l= (0.1*$HoH2{$k}{$_})+ (0.9*$HoH{$k}{$_});
    print FIC2 ("$k Q0 $_ $i $l TF_IDF \n");
    $i++;
    #print "$kk \n";
    }}
    merci

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

    le problème est qu'un hachage stocke les données dans un ordre pseudo-aléatoire et imprévisible.

    Il faut donc faire un sort sur les clefs du hash quand c'est possible (facile pour le premier niveau de ton hash) ou utiliser une autre structure (tableau) quand il faut préserver l'ordre des données d'origine (il y a d'autres solutions un peu plus complexes).

    Ici, je suggère, si cela convient, d'utiliser un HoA plutôt qu'un HoH, afin de conserver l'ordre des structures internes.

    Comme je n'ai pas de fichier en entrée, j'ai fait la version très simplifiée (un seul hash au lieu de deux) suivante de ton programme avec un HoA:

    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
     
    #!/usr/bin/perl
    use strict;
    use warnings;
    use Data::Dumper;
     
    my %HoH;
    while (<DATA>) {
        my ($who, undef, $key, $val) = split /\s/, $_;
        push @{$HoH{$who}}, [$key, $val];
    }
     
    # print Dumper \%HoH;
     
    foreach my $k (sort keys %HoH){ # sort sur la clef de premier niveau
        my $i = 0;
        foreach (@{$HoH{$k}}){
            my $l = (0.1*$HoH{$k}[$i][2])+ (0.9*$HoH{$k}[$i][2]); # nb: comme il n'y a qu'un hash, renvoie valeur d'origine
            print "$k Q0 $_->[0] $i $l TF_IDF \n";
            $i++;
        }
    }
    __DATA__
    1 Q0 DerOpthalmologe/80950033 0 5.960979448916666 TF_IDF
    1 Q0 DerRadiologe/80380710 1 5.836199971080442 TF_IDF
    1 Q0 MonatsschriftKinderheilkunde/01480013 2 5.836199971080442 TF_IDF
    1 Q0 DerHautarzt/90500127 3 5.601683110384085 TF_IDF
    1 Q0 DerAnaesthesist/80470024 4 5.4913531937974644 TF_IDF
    2 Q0 ZfuerKardiologie/90880788 0 7.950456651153142 TF_IDF
    2 Q0 DerChirurg/90701174 1 7.677017765795651 TF_IDF
    2 Q0 DerUnfallchirurg/81010830 2 7.503564829783422 TF_IDF
    2 Q0 DerChirurg/80690854 3 7.503564829783422 TF_IDF
    Ce qui affiche:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    1 Q0 DerOpthalmologe/80950033 0 5.96097944891667 TF_IDF
    1 Q0 DerRadiologe/80380710 1 5.83619997108044 TF_IDF
    1 Q0 MonatsschriftKinderheilkunde/01480013 2 5.83619997108044 TF_IDF
    1 Q0 DerHautarzt/90500127 3 5.60168311038409 TF_IDF
    1 Q0 DerAnaesthesist/80470024 4 5.49135319379746 TF_IDF
    2 Q0 ZfuerKardiologie/90880788 0 7.95045665115314 TF_IDF
    2 Q0 DerChirurg/90701174 1 7.67701776579565 TF_IDF
    2 Q0 DerUnfallchirurg/81010830 2 7.50356482978342 TF_IDF
    2 Q0 DerChirurg/80690854 3 7.50356482978342 TF_IDF
    ce qui correspond à l'ordre que tu désires, si j'ai bien compris.

    Enlève la mise en commentaire de la ligne "print Dumper..." si tu désires visualiser la structure de données obtenue. Elle est du type:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     {
              '1' => [
                       [
                         'DerOpthalmologe/80950033',
                         '0',
                         '5.960979448916666'
                       ],
                       [
                         'DerRadiologe/80380710',
                         '1',
                         '5.836199971080442'
                       ],
    ...

  3. #3
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    Citation Envoyé par africanwinners Voir le message
    le problème c'est que les scores c'est à dire le 4ème champs de la ligne n'est plus triés, les valeurs sont hasard, de même pour le premier champs ou on peut trouver le numéro 103 au début puis 19, comment triés ces résultats selon le champs 1 puis le champs 4?
    dans ta double boucle finale, au lieu d'imprimer directement les lignes, tu peux construire un tableau de résultats @res comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    my @res;
    foreach my $k (  keys %HoH2){
    #print "$k: ";
    $i=0;
    foreach (  keys%{HoH2{$k}}){
    
    $l= (0.1*$HoH2{$k}{$_})+ (0.9*$HoH{$k}{$_});
    print FIC2 ("$k Q0 $_ $i $l TF_IDF \n");
    push @res, [$k, 'Q0', $_, $i, $l, 'TD_IDF'];
    $i++;
    #print "$kk \n";
    }}
    que tu peux ensuite trier comme tu veux, par exemple (par ordre ascendant des champs 0 et 4) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (sort { $a->[0] <=> $b->[0] or $a->[4] <=> $b->[4] } @res) { 
      print FIC2 join(" ", @$_),"\n"
    }
    si tu voulais plutôt être en ordre ascendant sur le champ 0 mais descendant pour le champ 4 il suffit d'inverser a et b dans la deuxième expression du sort : $a->[0] <=> $b->[0] or $b->[4] <=> $a->[4].

    Dernier point, si tu veux trier par ordre numérique il faut utiliser l'opérateur <=>, si tu veux trier par ordre lexicographique il faut utiliser l'opérateur cmp. Quand tu fais un simple sort keys %h c'est l'ordre lexicographique qui est utilisé par défaut. Donc si tu voulais un tri simple mais dans l'ordre numérique il faudrait écrire sort { $a <=> $b } keys %h.
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  4. #4
    Membre régulier
    Inscrit en
    Mars 2010
    Messages
    157
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 157
    Points : 80
    Points
    80
    Par défaut
    Bonsoir

    Merci Lolo78 , mais la solution que vous proposez ne fait pas ce que vous dites, j'ai essayé avec un autre exemple, les résultats ne sont pas triés, essayer juste avec cet exemple:
    1 Q0 DerOpthalmologe/80950033 0 5.96097944891667 TF_IDF
    1 Q0 DerRadiologe/80380710 1 5.83619997108044 TF_IDF
    1 Q0 MonatsschriftKinderheilkunde/01480013 2 5.83619997108044 TF_IDF
    1 Q0 DerHautarzt/90500127 3 5.60168311038409 TF_IDF
    1 Q0 DerAnaesthesist/80470024 4 5.49135319379746 TF_IDF
    2 Q0 ZfuerKardiologie/90880788 0 7.95045665115314 TF_IDF
    2 Q0 DerChirurg/90701174 1 7.67701776579565 TF_IDF
    2 Q0 DerUnfallchirurg/81010830 2 7.50356482978342 TF_IDF
    2 Q0 DerChirurg/80690854 3 7.50356482978342 TF_IDF
    3 Q0 DerGynaekologe/00330028 4 6.95622437827284 TF_IDF
    3 Q0 ZfuerHerzThoraxGefaesschirurgie/80120160 5 6.758456738014428 TF_IDF
    3 Q0 Herz/00250113 6 6.22883492477801 TF_IDF
    3 Q0 ZfuerKardiologie/70860982 7 6.079279095991491 TF_IDF
    3 Q0 IntensiveMedizin/80350375 8 6.0409006440268165 TF_IDF
    3 Q0 Psychotherapeut/70420307 9 5.938209461239149 TF_IDF
    3 Q0 DerGynaekologe/90320496 10 5.88558547308398 TF_IDF
    3 Q0 DerAnaesthesist/80470136 11 5.7932945782497915 TF_IDF
    3 Q0 DerAnaesthesist/80470925 12 5.7932945782497915 TF_IDF
    3 Q0 Bundesgesundheitsblatt/00430882 13 5.540313834612012 TF_IDF
    3 Q0 DerGynaekologe/00330583 14 5.540313834612012 TF_IDF
    115 Q0 DerUrologeA/80370066 0 7.8389562409286375 TF_IDF
    115 Q0 DerOpthalmologe/60930558 1 7.424283948209753 TF_IDF
    115 Q0 DerAnaesthesist/60451004 2 6.735397448741252 TF_IDF
    115 Q0 ZfuerHerzThoraxGefaesschirurgie/80120193 3 6.448090927821654 TF_IDF
    115 Q0 Psychotherapeut/90440220 4 6.4148912263179145 TF_IDF

    La réponse de cmcmc est plus correcte, et retourne des résultats triés.

    Un autre problème réside dans le champs 3, qui n'est plus correcte:
    1 Q0 Arthroskopie/80110154 412 9.15542762616609 TD_IDF
    1 Q0 Arthroskopie/00130229 346 8.1277467943887 TD_IDF
    1 Q0 Arthroskopie/80110200 668 7.3415404360369 TD_IDF normalement ca ne commence pas avec 412 mais avec 0.

    je crois ce problème survient lors du remplissage des hash, y a t'il pas un moyen de garder cette information

    Merci

  5. #5
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut
    Citation Envoyé par africanwinners Voir le message
    Un autre problème réside dans le champs 3, qui n'est plus correcte:
    1 Q0 Arthroskopie/80110154 412 9.15542762616609 TD_IDF
    1 Q0 Arthroskopie/00130229 346 8.1277467943887 TD_IDF
    1 Q0 Arthroskopie/80110200 668 7.3415404360369 TD_IDF normalement ca ne commence pas avec 412 mais avec 0.
    C'est normal. Essaie quelque chose comme (non testé)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    my ($p, $rank) ;
    for (sort { $a->[0] <=> $b->[0] or $b->[4] <=> $a->[4] } @res) { 
      if (!defined($p) or $_->[0] != $p) {
        $p = $_->[0];
        $rank = 0;
      }
      $_->[3] = $rank++;
      print FIC2 join(" ", @$_),"\n"
    }
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

  6. #6
    Membre régulier
    Inscrit en
    Mars 2010
    Messages
    157
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 157
    Points : 80
    Points
    80
    Par défaut
    Merci à tous , le code marche bien maintenant

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

Discussions similaires

  1. hash de hsah et tri
    Par pontarose dans le forum Bioinformatique
    Réponses: 5
    Dernier message: 13/03/2014, 14h36
  2. Hash à valeurs multiples et tris.
    Par wulfeir dans le forum Langage
    Réponses: 2
    Dernier message: 27/11/2007, 15h39
  3. Tri par valeur d un hash de hash
    Par LeLaulau dans le forum Langage
    Réponses: 4
    Dernier message: 28/09/2005, 10h33
  4. Parcours d'un hash de hash de hash
    Par ngere dans le forum Langage
    Réponses: 5
    Dernier message: 06/07/2005, 09h53
  5. [langage] probleme avec un hash de hash
    Par planetevoyage dans le forum Langage
    Réponses: 4
    Dernier message: 06/06/2003, 12h55

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