-5

私はこのような何百万ものベクトルで構成されるテキストファイルを持っています:-

V1
V1
V1
V3
V4
V1
V1

注:-順序は重要です。上記の出力ファイルで、最初のベクトルを3回カウントしました。同じパターンが5行目以降に2回繰り返されます。カウントは異なるはずです。

各ベクトル線が繰り返される回数を数え、次のように出力テキストファイルに追加します。-

上記の7つのベクトルでは、最初の3行は同じで、残りの2行は異なり、最後の行は同じです。したがって、出力は次のようになります。-

V1 count 3
V3
V4
V1 count 2

ただし、最初と最後のパターンは同じですが、順序が異なるため、カウントが異なります。

pythonまたはを使用できますperl。行(ベクトル)の最大長はわかっていますが、各行(ベクトル)を他の行と比較するにはどうすればよいですか。助けてください

4

7 に答える 7

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

(すべてを1行にまとめるか、そのままにしておくことができます。)

出力:

V1 repeat3
V3
V4
V1 repeat2

このソリューションは、平均的なケースのO(N)CPUとO(1)メモリです。それとinspectorG4dgetは、要求した形式と順序で出力を提供する7つの既存の回答のうちの2つだけです。

于 2012-10-16T18:22:22.307 に答える
2

コマンドプロンプトでこれを実行するだけです

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

順序を保持する場合は、並べ替えを削除します(連続する一意の行のみをカウントします)

uniq -c text.txt > output.txt

または、これにより、必要な正確な出力が得られます(池上が提案するソリューション)

uniq -c text.txt \
| perl -ple's/^\s*(\d+) //; $_ .= " repeat$1" if $1 > 1; \
> output.txt
于 2012-10-16T18:16:03.357 に答える
1

順序は関係ありません

sort filepath | uniq -c( Jeanが提案するように) Pythonでこれを本当に実行したい場合は、次のようにします。

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エントリの前にエントリが表示される場合は、出力ファイルのエントリの前にエントリが表示される必要があります)、必要なのは変更されたランレングスエンコーダです。ただし、次の入力ファイルがある場合は注意してください。jij

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同じことをします

お役に立てれば

于 2012-10-16T18:21:51.500 に答える
0

私はあなたがO(n ^ 2)未満でこれを行うことができるとは思わない...(私は間違っている可能性があります)

1つの方法は(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]
于 2012-10-16T18:15:54.097 に答える
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))
于 2012-10-16T18:22:37.757 に答える
0

Python 2.7を想定すると、メモリをあまり消費しないソリューション

from collections import Counter
with open("some_file.txt") as f:
    cnt = Counter(f)
    print cnt
于 2012-10-16T18:22:49.110 に答える
0
vectors = {}
for vector in open("vect.txt").readlines():
    vectors[vector] = vectors.setdefault(vector, 0) + 1
print vectors
于 2012-10-16T18:23:33.190 に答える