0

インデックス行を持つ 2 つのテキスト ファイルがあります。file1file2を比較し、同様の行を新しいテキスト ファイルに送信したいと考えています。私はこれをしばらくグーグルで調べていて、さまざまな形式でgrepを試してきましたが、頭がいっぱいになっていると感じています。私が最終的に望むのは、file1 に表示される file2 の 'Mon-######' を確認し、対応する file1 の行を出力することです。

(ファイルはかなり大きいので、簡潔にするために省略しています)

さらに明確にするために:

file1 には次の形式のエントリがあります。

Mon-000101  100.27242   9.608597   11.082   10.034
Mon-000102  100.18012   9.520860   12.296   12.223

file2 には次の形式のエントリがあります。

Mon-000101
Mon-000171

したがって、file2 の識別子 (たとえば、Mon-000101) が file1 にリストされている場合、Mon-000101 で始まる行全体を別のファイルに出力します。file2 にリストされていない場合は、破棄できます。

したがって、ファイルが上記のファイルと同じくらい大きい場合、新しく生成されたファイルには次の単一のエントリが含まれます。

Mon-000101  100.27242   9.608597   11.082   10.034

それが両方に共通する唯一のものだからです。

4

6 に答える 6

1

Since you added the python tag, it seems you want something like this:

import csv
f = open('file2')
l = set([l.strip() for l in f.readlines()])
with open('file1', 'rb') as csvfile:
    dialect = csv.Sniffer().sniff(csvfile.read(10024))
    csvfile.seek(0)
    reader = csv.reader(csvfile, dialect)
    cnt = 0
    for item in reader:
        if cnt >0:
           data = item[0]
           if data in l:
               print item
        cnt = cnt + 1
于 2013-05-20T03:24:20.137 に答える
1
$ join <(sort file1) <(sort file2) > duplicated-lines
于 2013-05-20T03:13:57.810 に答える
0

以前の質問から、 pandasに少なくとも少し慣れているので、どうですか:

import pandas as pd
df1 = pd.read_csv("file1.csv", sep=r"\s+")
df2 = pd.read_csv("file2.csv", sep=r"\s+")
merged = df1.merge(df2.rename_axis({"Mon-id": "NAME"}))
merged.to_csv("merged.csv", index=False)

いくつかの説明 (file2.csv共通の要素が増えるように変更したことに注意してください) を次に示します。

まず、データを読み取ります。

>>> import pandas as pd
>>> df1 = pd.read_csv("file1.csv", sep=r"\s+")
>>> df2 = pd.read_csv("file2.csv", sep=r"\s+")
>>> df1.head()
         NAME         RA       DEC  Mean_I1  Mean_I2
0  Mon-000101  100.27242  9.608597   11.082   10.034
1  Mon-000102  100.18012  9.520860   12.296   12.223
2  Mon-000103  100.24811  9.586362    9.429    9.010
3  Mon-000104  100.26741  9.867225   11.811   11.797
4  Mon-000105  100.21005  9.814060   12.087   12.090
>>> df2.head()
       Mon-id
0  Mon-000101
1  Mon-000121
2  Mon-000131
3  Mon-000141
4  Mon-000151

次に、df2 で軸の名前を変更できます。

>>> df2.rename_axis({"Mon-id": "NAME"}).head()
         NAME
0  Mon-000101
1  Mon-000121
2  Mon-000131
3  Mon-000141
4  Mon-000151

その後、merge単に正しいことを行います:

>>> merged = df1.merge(df2.rename_axis({"Mon-id": "NAME"}))
>>> merged
         NAME         RA       DEC  Mean_I1  Mean_I2
0  Mon-000101  100.27242  9.608597   11.082   10.034
1  Mon-000121  100.45421  9.685027   11.805   11.777
2  Mon-000131  100.20533  9.397307 -100.000   11.764
3  Mon-000141  100.26134  9.388555 -100.000   12.571

最後に、インデックス列を追加しないように指示して、これを書き出すことができます。

>>> merged.to_csv("output.csv", index=False)

次のようなファイルを作成します

NAME,RA,DEC,Mean_I1,Mean_I2
Mon-000101,100.27242,9.608597,11.082,10.034
Mon-000121,100.45421,9.685027,11.805,11.777
Mon-000131,100.20533,9.397307,-100.0,11.764
Mon-000141,100.26134,9.388555,-100.0,12.571
于 2013-05-20T03:29:43.470 に答える
0

これを解決する 1 つの方法 (ファイルが大きすぎない場合) はfile1、データを読み込んでdict、各行がインデックス (最初の列) とデータ (残りの列) によってキー付けされる場所として保存することです。次に、キーのリストとして読み取りfile2ます。これをジェネレーターとして使用して、 のデータから一致する行を抽出できますfile1

迅速で汚い解決策:

#!/usr/bin/env python

DATA_FILE='file1.txt'
KEY_FILE='file2.txt'

# Read a list of keys to search for
keys = []
lineno = 1
for line in open(KEY_FILE):
    if lineno > 1:
        keys.append(line.strip())
    lineno += 1

# Read data 
data = {}
lineno = 1
for line in open(DATA_FILE):
    if lineno > 1:
        fields = line.split()
        data[fields[0]] = fields[1:]
    lineno += 1

    # Extract data using keys

extracted_data = [[k, data[k]] for k in keys if k in data]

for k, v in extracted_data:
    print k, ' '.join(v)

これを行うにはおそらくもっと効率的な方法がありますが、これでうまくいき、必要に応じてより多くのロジックを入れることができます。

于 2013-05-20T03:36:48.250 に答える
0

ファイルが大きくなる可能性があるため、このアプローチはどうですか。sqlite を使用してファイル操作を処理します。

import sqlite3
import csv
import os

conn = sqlite3.connect('temp.db')

c = conn.cursor()
c.execute('''CREATE TABLE master
          (id text, ra text, dec text, mean1 text, mean2 text)''')
conn.commit() # Write changes

with open('master.csv') as f:
    reader = csv.reader(f, delimiter=',')
    next(reader) # skips header
    for row in reader:
        c.execute('INSERT INTO master VALUES (?,?,?,?,?)', row)
        conn.commit()

with open('filter.txt') as f, open('diff.txt','w') as out:
    writer = csv.writer(out, delimiter=',')
    writer.writerow(('NAME','RA','DEC','Mean_I1','Mean_I2'))
    for line in f:
         c.execute('SELECT * FROM master WHERE id = ?',(line.strip(),))
         row = c.fetchone()
         if row:
             writer.writerow(row)
conn.close()
os.remove('temp.db')
于 2013-05-20T06:07:50.613 に答える
0

とを使用grepsedますbash。これは、非常に大きなファイルではパフォーマンスが低下する可能性があります。

grep -f <(sed 's/^/^/' file2.txt) file1.txt
于 2013-05-20T15:21:03.437 に答える