根据电子表格中的两列计算唯一值的数量

根据电子表格中的两列计算唯一值的数量

我需要根据电子表格中的两列计算唯一值的数量。

假设文件如下所示,按姓名、姓氏、公司排序:

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

答案1

使用 GNU awk 解决方案二维数组

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]++对于每个名字和姓氏的组合,增加计数
  • 然后循环遍历名字以及与每个名字相关的公司名称。

另一种可以awk使用旧形式的多维数组的方法是:

awk -F $'\t' '{a[$1, $3]++} END{for (i in a) {split (i, sep, SUBSEP); print sep[1], sep[2], a[i]}}' foo.txt
  • 由于旧方法实际上使用了以 分隔的索引的连接SUBSEP,因此我们必须进行拆分SUBSEP才能返回原始索引。

答案2

这是一个使用模块Counter类的Pythonic 解决方案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])

答案3

您可以利用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

答案4

以下 perl 单行程序将为您提取数据:

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

相关内容