我有一个文本文件,包含数百万个这样的矢量: -
V1
V1
V1
V3
V4
V1
V1
注意: - ORDER很重要。在上面的输出文件中,我计算了第一个向量3次。在第5行之后重复相同的模式两次。数量应该不同。
我想计算每个矢量线重复的次数,并将其添加到输出文本文件中,如下所示: -
在上述7个向量中,前3行是相同的,其余2是不同的,然后最后的行是相同的。因此输出应如下所示: -
V1 count 3
V3
V4
V1 count 2
虽然第一个和最后一个模式是相同的,但它们的计数方式不同,因为它们的顺序不同。
我可以使用python
或perl
。我知道行(向量)的最大长度,但我如何将每行(向量)与其他行进行比较。请帮忙
答案 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