Мне нужно подсчитать количество уникальных значений на основе двух столбцов в электронной таблице.
Предположим, что файл выглядит так, упорядоченный по имени, фамилии, компании:
joe allen ibm
joe smith ibm
joe allen google
joe smith google
rachel allen google
И мне нужно подсчитать количество уникальных первых имен для каждой компании, игнорируя фамилию:
joe ibm 2
joe google 2
rachel google 1
У меня есть этот код:
sort file.tsv | uniq -ci | awk '{print $2,$1}'
Если я просто удалите столбец фамилии, этот код будет работать. Но если я не хочу удалять этот столбец, просто попробуйте awk игнорировать его и сохранить вывод в новый файл?
Данные разделяются вкладками \ t
Здесь находится решение Pythonic, использующее Counter класс модуля collections, который будет подсчитывать количество вхождений каждого элемента в итерируемый:
#!/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])
Вы можете использовать cut, чтобы сначала выбрать столбцы, которые вы хотите использовать. Поэтому, учитывая, что ваши столбцы разделены пробелом и являются FNAME SNAME COMPANY, нас интересуют только столбцы 1 и 3, которые мы можем использовать:
cut -d' ' -f1,3 file.tsv | sort | uniq -ci
Это говорит cut отделить использование одного пробел '' как разделитель и передать столбцы 1 и 3 в сортировку.
Он произведет некоторый вывод, подобный:
cut -d' ' -f1,3 file.tsv | sort | uniq -ci
2 joe google
2 joe ibm
1 rachel google
Следующий файл perl oneliner будет извлекать данные для вас:
perl -e '/(.*)\t.*\t(.*)/ and $a{"$1 $2"}++ for (<>); print "$_ $a{$_}\n" foreach (keys%a);' file.tsv
Выход:
joe ibm 2
joe google 2
rachel google 1