1
votes

soustraire les valeurs de la colonne 1 si la colonne 2 est la même

J'ai un fichier au format suivant:

0.018029 15150000000
0.012615 15150000001
0.007046 15150000002
0.012989 15150000003

Je voudrais soustraire la colonne 1 lorsque la colonne 2 est la même. Par exemple pour le fichier d'entrée, je voudrais avoir quelque chose comme ceci:

0.019059000     15150000000
0.037088000     15150000000
0.035007000     15150000001
0.047622000     15150000001
0.053359000     15150000002
0.060405000     15150000002
0.068598000     15150000003
0.081587000     15150000003

Toutes les valeurs de la colonne 2 du fichier d'entrée vont par paires par exemple 15150000000 n'existe que deux fois, 15150000001 n'existe que deux fois etc.

Toute aide est plus que bienvenue!


6 commentaires

Les mêmes valeurs dans la colonne 2 sont-elles toujours adjacentes?


pas nécessaire. Il peut sauter certaines valeurs. donc à partir de 15150000003, le suivant peut être 15150000004 ou 15150000005


Je veux dire dans le fichier, occupent-ils des lignes adjacentes?


oui, j'ai trié le fichier en fonction de la colonne 2.


Si le fichier n'est pas trié, soustrayez-vous le plus petit du plus grand ou le deuxième du premier ou quoi?


Oui si le fichier n'est pas trié, je voudrais ne pas avoir de valeurs négatives et soustraire le plus petit du plus grand puisque la première colonne représente le temps en secondes


3 Réponses :


4
votes

awk à la rescousse! (sans vérification d'erreur.)

$ awk 'function abs(x) {return x<0?-x:x}
       $2 in a {print abs($1-a[$2]),$2; delete a[$2]; next} 
               {a[$2]=$1}' file

pour les enregistrements non triés mais encore une fois doublés pour la même clé

$ awk '$2 in a {print $1-a[$2],$2; delete a[$2]; next} {a[$2]=$1}' file

0.018029 15150000000
0.012615 15150000001
0.007046 15150000002
0.012989 15150000003

si la deuxième valeur n'est pas toujours supérieure à le premier et vous voulez la différence absolue

$ awk 'p==$2 {print $1-pv,p} {p=$2; pv=$1}' file

0.018029 15150000000
0.012615 15150000001
0.007046 15150000002
0.012989 15150000003


1 commentaires

Merci beaucoup Karakfa! Il semble que cela fonctionne comme prévu! Une autre question rapide juste de la curiosité .. Cela ne semble pas fonctionner si le fichier n'est pas trié en premier en fonction de la colonne 2. Existe-t-il un moyen d'obtenir le même résultat même si le fichier n'est pas trié?



0
votes

Que diriez-vous de

awk '{a[$2] = $1 - a[$2]} END {for (b in a) print a[b], b}' file

Ah, je vois que vous avez des valeurs en paires . Allez donc avec la réponse de Karakfa.


0 commentaires

1
votes

Un autre dans awk, soustrait le plus petit du plus grand:

0.007046 15150000002
0.018029 15150000000
0.012615 15150000001
0.012989 15150000003

Un exemple de sortie (en raison de shufrandomness):

$ awk '{
    if($2 in a) {                              # if another $2 already met
        print ((s=$1-a[$2])>0?s:-s),$2         # subtract smaller from bigger
        delete a[$2]                           # delete to save memory
    } else 
        a[$2]=$1                               # else store $2
}' <(shuf file)                                # shuf file to demo random order
                                               # replace with just the file name


2 commentaires

vous pouvez remplacer a [$ 2] - $ 1 par -s


@karakfa Bon point, merci. C'est ce que fait une sieste trop longue à une personne ...: D.