python - 计算行出现次数并除以总行数 - unix/python

标签 python unix count text-files uniq

我有一个文本文件test.in:

english<tab>walawala
foo bar<tab>laa war
foo bar<tab>laa war
hello world<tab>walo lorl
hello world<tab>walo lorl
foo bar<tab>laa war

期望的输出应该是:

english<tab>walawala<tab>0.1666
foo bar<tab>laa war<tab>0.5
hello world<tab>walo lorl<tab>0.3333

新列是行数除以总行数。

目前我正在这样做:

cat test.in | uniq -c | awk '{print $2"\t"$3"\t"$1}' > test.out

但这只给我行数而不是概率。另外,我的文件非常大,大约 1,000,000,000 行,每列至少 20 个字符。

如何正确快速地获得所需的输出?

有没有一样快的 pythonic 解决方案?

最佳答案

请注意,uniq 只计算重复的行,并且必须在它之前加上 sort 才能考虑文件中的所有行。对于 排序 | uniq -c,以下代码使用collections.Counter更有效,因为它根本不需要对任何东西进行排序:

from collections import Counter

with open('test.in') as inf:
    counts = sorted(Counter(line.strip('\r\n') for line in inf).items())
    total_lines = float(sum(i[1] for i in counts))
    for line, freq in counts:
         print("{}\t{:.4f}".format(line, freq / total_lines))

这个脚本输出

english<tab>walawala<tab>0.1667
foo bar<tab>laa war<tab>0.5000
hello world<tab>walo lorl<tab>0.3333

对于您的描述中给出的输入。


但是,如果您只需要合并连续的行,例如 uniq -c,请注意任何使用 Counter 的解决方案都会给出在中给出的输出你的问题,但是你的 uniq -c 方法不会uniq -c 的输出将是:

  1 english<tab>walawala
  2 foo bar<tab>laa war
  2 hello world<tab>walo lorl
  1 foo bar<tab>laa war

不是

  1 english<tab>walawala
  3 foo bar<tab>laa war
  2 hello world<tab>walo lorl

如果这是您想要的行为,您可以使用itertools.groupby :

from itertools import groupby

with open('foo.txt') as inf:
    grouper = groupby(line.strip('\r\n') for line in inf)
    items = [ (k, sum(1 for j in i)) for (k, i) in grouper ]
    total_lines = float(sum(i[1] for i in items))
    for line, freq in items:
        print("{}\t{:.4f}".format(line, freq / total_lines))

不同之处在于,如果 test.in 具有您规定的内容,uniq 管道将不会产生您在示例中提供的输出,而您会得到:

english<tab>walawala<tab>0.1667
foo bar<tab>laa war<tab>0.3333
hello world<tab>walo lorl<tab>0.3333
foo bar<tab>laa war<tab>0.1667

因为这不是您的输入示例所说的,可能是您不能在没有 sort 的情况下使用 uniq 来解决您的问题 - 那么您需要求助于我的第一个示例和 Python 肯定会比您的 Unix 命令行更快。


顺便说一下,这些在所有 Python 2.6 中的工作方式相同。

关于python - 计算行出现次数并除以总行数 - unix/python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25156747/

相关文章:

MySQL COUNT() 或 SUM()

python - 查找部分子集python

python - 使用Python将欧拉公式转化为矩阵逼近

unix - 在 Unix 中将文本向上移动一行

linux - 如何使用 rsync 命令在 Linux 中复制当前日期文件或特定日期文件?

mysql - 计算组内的最小记录数

python - 套接字错误 [错误 10060]

python - 没有 kv 语言的 Kivy 图像

macos - 从文件尾部修剪 N 行的简单方法是什么(不使用 'head' )?

java - 计算文件中的字符出现次数