conta o número de valores exclusivos com base em duas colunas em uma planilha

2

Preciso contar o número de valores únicos com base em duas colunas em uma planilha.

Suponha que o arquivo tenha esta aparência, ordenado por nome, sobrenome, empresa:

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

E preciso contar o número de primeiros nomes exclusivos de cada empresa, ignorando o sobrenome:

joe ibm 2
joe google 2
rachel google 1

Eu tenho este código:

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

Se eu simplesmente excluir a coluna de sobrenome, esse código funcionará. Mas se eu não quiser apagar essa coluna, apenas o awk irá ignorá-la e salvar a saída em um novo arquivo?

Os dados são separados por tabulações, \ t

    
por Sveisa 03.03.2015 / 16:41

4 respostas

2

Uma solução GNU awk usando vetores bidimensionais :

gawk -F $'\t' '{a[][]++} END {for (i in a) for (j in a[i]) print i, j, a[i][j]}' foo.txt
  • a[][]++ para cada combinação de primeiro nome e sobrenome, incrementar a contagem
  • Em seguida, percorra os primeiros nomes e os nomes das empresas associados a cada nome.

Outra maneira de trabalhar com outros awk s usando a forma mais antiga de matrizes multidimensionais:

awk -F $'\t' '{a[, ]++} END{for (i in a) {split (i, sep, SUBSEP); print sep[1], sep[2], a[i]}}' foo.txt
  • Como o método antigo realmente usa uma concatenação dos índices separados por SUBSEP , temos que dividir em SUBSEP para recuperar os índices originais.
por muru 03.03.2015 / 16:59
3

Aqui está uma solução Python usando a classe Counter do módulo collections que contará o número de ocorrências de cada elemento em um iterável:

#!/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])
    
por heemayl 03.03.2015 / 17:03
2

Você pode usar cut para selecionar as colunas nas quais deseja operar primeiro. Então, dado que suas colunas são separadas por um espaço, e são FNAME SNAME COMPANY, onde estamos interessados apenas nas colunas 1 e 3, podemos usar:

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

Isto diz ao cut para separar usando um único espaço '' como um delimitador e para passar as colunas 1 e 3 para ordenação.

Produzirá alguma saída semelhante a:

 cut -d' ' -f1,3 file.tsv | sort | uniq -ci
      2 joe google
      2 joe ibm
      1 rachel google
    
por AJefferiss 03.03.2015 / 16:52
2

O seguinte perl oneliner irá extrair os dados para você:

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

Saída:

joe ibm 2
joe google 2
rachel google 1
    
por Sylvain Pineau 03.03.2015 / 17:32