web-dev-qa-db-fra.com

Compter le nombre de valeurs uniques en fonction de deux colonnes dans une feuille de calcul

Je dois compter le nombre de valeurs uniques en fonction de deux colonnes dans une feuille de calcul.

Supposons que le fichier ressemble à ceci, classé par nom, prénom, société:

joe allen ibm
joe smith ibm
joe allen google
joe smith google
rachel allen google

Et je dois compter le nombre de prénoms uniques pour chaque entreprise en ignorant le nom de famille:

joe ibm 2
joe google 2
rachel google 1

J'ai ce code:

sort file.tsv | uniq -ci | awk '{print $2,$1}'

Si je supprime simplement la colonne de nom de famille, ce code fonctionnera. Mais si je ne veux pas supprimer cette colonne, awk doit simplement l’ignorer et enregistrer le résultat dans un nouveau fichier?

Les données sont séparées par des onglets \t

3
Sveisa

Une solution GNU awk utilisant tableaux à deux dimensions :

gawk -F $'\t' '{a[$1][$3]++} END {for (i in a) for (j in a[i]) print i, j, a[i][j]}' foo.txt
  • a[$1][$3]++ pour chaque combinaison de prénom et nom, incrémenter le nombre
  • Parcourez ensuite les prénoms et les noms de sociétés associés à chaque prénom.

Une autre façon de travailler avec les autres awks utilisant l'ancienne forme de tableaux multidimensionnels:

awk -F $'\t' '{a[$1, $3]++} END{for (i in a) {split (i, sep, SUBSEP); print sep[1], sep[2], a[i]}}' foo.txt
  • Comme l'ancienne méthode utilisait en réalité une concaténation des index séparés par SUBSEP, nous devons le scinder sur SUBSEP pour récupérer les index d'origine.
2
muru

Voici une solution Pythonic utilisant le module Counter de collections qui comptera le nombre d'occurrences de chaque élément dans un élément itératif:

#!/usr/bin/env python2
import collections
with open('file.txt') as f:
    names = []
    for line in f:
        names.append(line.strip().split()[0] + ' ' + line.strip().split()[2])
    result_dict = collections.Counter(names)
    for person in result_dict:
        print person + ' ' + str(result_dict[person])
3
heemayl

Vous pouvez utiliser cut pour sélectionner les colonnes que vous souhaitez utiliser en premier. Donc, étant donné que vos colonnes sont séparées par un espace, et sont FNAME SNAME COMPANY où nous ne sommes intéressés que par les colonnes 1 et 3, nous pouvons utiliser:

cut -d' ' -f1,3 file.tsv | sort | uniq -ci

Ceci indique à cut de se séparer en utilisant un seul espace '' comme séparateur et de passer les colonnes 1 et 3 en tri.

Il produira une sortie similaire à:

 cut -d' ' -f1,3 file.tsv | sort | uniq -ci
      2 joe google
      2 joe ibm
      1 rachel google
2
AJefferiss

Le Perl oneliner suivant extraira les données pour vous:

Perl -e '/(.*)\t.*\t(.*)/ and $a{"$1 $2"}++ for (<>); print "$_ $a{$_}\n" foreach (keys%a);' file.tsv

Sortie:

joe ibm 2
joe google 2
rachel google 1
2
Sylvain Pineau