计算文件中的行数

时间:2012-10-16 18:11:19

标签: python perl

我有一个文本文件,包含数百万个这样的矢量: -

V1
V1
V1
V3
V4
V1
V1

注意: - ORDER很重要。在上面的输出文件中,我计算了第一个向量3次。在第5行之后重复相同的模式两次。数量应该不同。

我想计算每个矢量线重复的次数,并将其添加到输出文本文件中,如下所示: -

在上述7个向量中,前3行是相同的,其余2是不同的,然后最后的行是相同的。因此输出应如下所示: -

V1 count 3
V3
V4
V1 count 2

虽然第一个和最后一个模式是相同的,但它们的计数方式不同,因为它们的顺序不同。

我可以使用pythonperl。我知道行(向量)的最大长度,但我如何将每行(向量)与其他行进行比较。请帮忙

7 个答案:

答案 0 :(得分:4)

perl -nle'
   if ($c && $_ ne $last) {
      print $c > 1 ? "$last repeat$c;" : "$last;";
      $c = 0;
   }

   $last = $_;
   ++$c;

   END {
      if ($c) {
         print $c > 1 ? "$last repeat$c;" : "$last;";
      }
   }
' file

(您可以将所有内容放在一行,或保持原样。)

输出:

V1 repeat3
V3
V4
V1 repeat2

此解决方案是平均O(N)CPU和O(1)内存。它和inspectorG4dget是七个现有答案中仅有的两个,它们以您请求的格式和顺序提供输出。

答案 1 :(得分:2)

只需在命令提示符下运行

sort text.txt | uniq -c > output.txt

如果要保留排序(仅计算连续的唯一行),请删除排序

uniq -c text.txt > output.txt

或者这将提供所需的精确输出(ikegami建议的解决方案)

uniq -c text.txt \
| perl -ple's/^\s*(\d+) //; $_ .= " repeat$1" if $1 > 1; \
> output.txt

答案 2 :(得分:1)

如果订单不重要

如果你真的想在python中这样做(而不是像Jean建议的那样sort filepath | uniq -c),那么我会这样做:

import collections
with open('path/to/file') as f:
    counts = collections.Counter(f)
    outfile = open('path/to/outfile', 'w')
    for line,occ in counts.iteritems():
        outfile.write("%s repeat %d\n" %(line.strip(), occ))
    outfile.close()

如果订单重要

如果订单很重要(如果条目i出现在输入文件中的条目j之前,则条目i必须出现在输出文件中的条目j之前),然后你需要的是一个改进的行程编码器。但请注意,如果您有以下输入文件:

v1
v1
v1
v2
v2
v3
v1

然后,您的输出文件将如下所示:

v1 repeat 3
v2 repeat 2
v3
v1

with open('infilepath') as infile:
    outfile = open('outfilepath', 'w')
    curr = infile.readline().strip()
    count = 1
    for line in infile:
        if line.strip() == curr:
            count += 1
        else:
            outfile.write(curr)
            if count-1:
                outfile.write(" repeat %d\n" %count)
            else:
                outfile.write("\n")
            curr = line.strip()
            count = 1
    outfile.write(curr)
    if count-1:
        outfile.write(" repeat %d\n" %count)
    outfile.close()

当然,uniq -c infilepath > outfilepath会做同样的事情

希望这有帮助

答案 3 :(得分:0)

我认为你不能以低于O(n ^ 2)的方式做到这一点......(我可能错了)

一种方式是(在python中)

with open("some_file_with_vectors") as f:
          data = f.read()

counts  = dict([(line,data.count(line)) for line in data.splitlines()])
print counts
#if you want to save to a file
with open("output.txt") as f:
   for key in counts:
       print >> f, key ,"=",counts[key]

答案 4 :(得分:0)

如果这一切都适合记忆,那么你可以这样做:

from collections import Counter

with open('vectors') as fin:
    counts = Counter(fin)

或者,如果大,那么你可以使用sqlite3:

import sqlite3

db = sqlite3.conncet('/some/path/some/file.db')
db.execute('create table vector (vector)')
with open('vectors.txt') as fin:
    db.executemany('insert into vector values(?)', fin)
    db.commit()

for row in db.execute('select vector, count(*) as freq from vector group by vector'):
    print row # do something suitable here

如果向量总是连续的:

from itertools import groupby
with open('vector') as fin:
    for vector, vals in groupby(fin):
        print '{} {}repeat'.format(vector, sum(1 for _ in vals))

答案 5 :(得分:0)

假设python 2.7,内存密集度较低的解决方案

from collections import Counter
with open("some_file.txt") as f:
    cnt = Counter(f)
    print cnt

答案 6 :(得分:0)

vectors = {}
for vector in open("vect.txt").readlines():
    vectors[vector] = vectors.setdefault(vector, 0) + 1
print vectors