Hash et somme
Fermé
debousole
Messages postés
4
Date d'inscription
mardi 12 août 2014
Statut
Membre
Dernière intervention
29 septembre 2020
-
Modifié le 28 sept. 2020 à 18:18
Pat - 30 janv. 2021 à 09:44
Pat - 30 janv. 2021 à 09:44
A voir également:
- Hash et somme
- Formule somme excel colonne - Guide
- Somme si couleur - Guide
- Somme en anglais excel - Guide
- Somme de x dans excel ✓ - Forum Excel
- Erreur de somme de contrôle winrar - Forum Logiciels
3 réponses
[Dal]
Messages postés
6202
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
14 janvier 2025
1 097
Modifié le 28 sept. 2020 à 19:22
Modifié le 28 sept. 2020 à 19:22
Salut,
Il ne peut y avoir qu'une répétition d'élément, selon ce que je comprends, et il y a toujours 3 colonnes de données pour chaque élément ?
Si oui, j'aurai fait plus simple avec une regexp et un hash de tableaux :
donne sur ton jeu de données :
Dal
Il ne peut y avoir qu'une répétition d'élément, selon ce que je comprends, et il y a toujours 3 colonnes de données pour chaque élément ?
Si oui, j'aurai fait plus simple avec une regexp et un hash de tableaux :
#!/usr/bin/perl use strict; use warnings; my %data; while (<DATA>) { if (/(element\d+)\s+(\d)\s+(\d)\s+(\d)/) { # la ligne matche et nous avons capturé les 4 données if (!$data{$1}) { # si l'élément n'est pas déjà stocké dans le hash, on crée l'entrée $data{$1} = [$2, $3, $4]; } else { # si l'élément est déjà stocké dans le hash, on retraite les données $data{$1} = [ $2 + $data{$1}[0] == 2 ? 1 : $2 + $data{$1}[0], $3 + $data{$1}[1] == 2 ? 1 : $3 + $data{$1}[1], $4 + $data{$1}[2] == 2 ? 1 : $4 + $data{$1}[2] ]; } } } # affichage ordonné par clef foreach my $elem (sort keys %data) { print "$elem\t$data{$elem}[0]\t$data{$elem}[1]\t$data{$elem}[2]\n"; } __END__ element1 1 0 1 element2 0 1 1 element3 1 1 0 element1 0 0 1
donne sur ton jeu de données :
$ perl 36867025.pl element1 1 0 1 element2 0 1 1 element3 1 1 0
Dal
debousole
Messages postés
4
Date d'inscription
mardi 12 août 2014
Statut
Membre
Dernière intervention
29 septembre 2020
29 sept. 2020 à 14:30
29 sept. 2020 à 14:30
Merci bien.
Oui Il ne peut y avoir qu'une répétition d'élément,
J'ai 20 colonnes, en fait il y a toujours un nombre fixe de colonnes de donnée pour chaque élément
Ah oui nettement plus simple...
J'ai avancé et trouvé une solution (sauf pour le remplacement de 2 par 1, un sed après traitement au pire)
Encore MERCI
Oui Il ne peut y avoir qu'une répétition d'élément,
J'ai 20 colonnes, en fait il y a toujours un nombre fixe de colonnes de donnée pour chaque élément
Ah oui nettement plus simple...
J'ai avancé et trouvé une solution (sauf pour le remplacement de 2 par 1, un sed après traitement au pire)
open my $fh, '<', $fichier or die "Impossible de lire le fichier $fichier\n";
my %data;
my $i=0;
my $j=0;
while(my $ligne = <$fh>){
$i++;
chomp $ligne;
if($ligne =~ /gene.*/){
$j++;
my ($gene,$champ1,$champ2,$champ3) = split "\t", $ligne;
my $element =$champ1."\t".$champ2."\t".$champ3;
push @{$data{$gene}}, [$element];
}
}
for my $id (keys %data) {
my @array = @{$data{$id}};
$data{$id} = \@array;
}
#print Dumper \%data;
for my $id (keys %data) {
print "--$id\n";
my @tableau=();
my @array = @{$data{$id}};
my @sums;
for my $pair (@array) {
print ("\t$pair->[0]\n");
#faire la somme de chaque colonne quand la somme est égale à 2 remplacer par 1
my @nums = split("\t",$pair->[0]);
my $o = 0;
foreach my $num (@nums){
$sums[$o] += $num;
$o += 1;
}
}
print"=>\t";
foreach my $sum (@sums){
print("$sum\t");
}
print"\n";
}
Encore MERCI
[Dal]
Messages postés
6202
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
14 janvier 2025
1 097
Modifié le 29 sept. 2020 à 18:08
Modifié le 29 sept. 2020 à 18:08
De rien :-)
1.
Dans ton code, il suffit d'insérer la ligne suivante dans la boucle
Pour rectifier les données mises à 2 en 1.
2.
Ton code semble travailler sur 3 colonnes de données, et non 20.
Tu peux, bien sûr extrapoler ton code (ou le mien) pour traiter 20 colonnes de données, mais cela fait beaucoup de copier-collers de lignes et de variables ou indices à traquer correctement.
Avec une regexp et le modificateur
Si tu n'aimes pas les regexp,
C'est à dire :
1.
Dans ton code, il suffit d'insérer la ligne suivante dans la boucle
foreachentre
$sums[$o] += $num;et
$o += 1;:
$sums[$o] = 1 if $sums[$o] == 2;
Pour rectifier les données mises à 2 en 1.
2.
Ton code semble travailler sur 3 colonnes de données, et non 20.
Tu peux, bien sûr extrapoler ton code (ou le mien) pour traiter 20 colonnes de données, mais cela fait beaucoup de copier-collers de lignes et de variables ou indices à traquer correctement.
Avec une regexp et le modificateur
gtu peux répéter les matches et obtenir le résultat dans un tableau. Que tu aies 3 ou 20 colonnes de données ne changera rien au code.
Si tu n'aimes pas les regexp,
split(que tu utilises), fonctionne en contexte de liste, et te permet d'obtenir directement un tableau des éléments séparés par les tabulations. Tu peux alors supprimer le premier élément du tableau avec
shiftpour l'utiliser ultérieurement comme clef de ton hash, et du disposeras du tableau restant sans le premier élément pour en faire ce que tu veux.
C'est à dire :
if ($ligne =~ /gene.*/) { # obtention de toutes les colonnes dans un tableau my @arr = split "\t", $ligne; # on retire la donnée en première colonne, qui est notre clef my $key = shift @arr; # le tableau @arr contient désormais les données des colonnes # sauf la première qui a été retirée (...)
debousole
Messages postés
4
Date d'inscription
mardi 12 août 2014
Statut
Membre
Dernière intervention
29 septembre 2020
29 sept. 2020 à 18:37
29 sept. 2020 à 18:37
MERCI beaucoup!
Oui mon script est basé sur 3 colonnes pour que je puisse vérifier mon script rapidement...
Oui mon script est basé sur 3 colonnes pour que je puisse vérifier mon script rapidement...
30 janv. 2021 à 09:44