2013-05-20 149 views
0

我有兩個文本文件都有索引行。我想比較file1file2並將相似的行發送到新的文本文件。我一直在使用googling一段時間,並一直試圖以各種形式grep,但我覺得我陷入了我的頭。我最終希望看到來自file2的'Mon - ######'出現在file1中,並打印出來自file1的相應的行。比較兩個文件並打印相似的行

(該文件較大,我把它們剪下來簡潔起見)

對於時間更加明確:

文件1的格式的條目:

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

文件2具有的條目的形式:

Mon-000101 
Mon-000171 

因此,如果標識符(例如Mon-000101)fr om file2在file1中列出我希望以Mon-000101開頭的整行打印到單獨的文件中。如果它沒有在file2中列出,它可以被丟棄。

因此,如果文件是僅作爲上述文件作爲大型新產生的文件將有

Mon-000101 100.27242 9.608597 11.082 10.034 

單個條目,因爲這是唯一的一個共同的兩者。

+0

您是否嘗試過使用python?閱讀第二個文件以創建出現的Mon-xxxx列表,然後讀取第一個文件,分割每一行並檢查第一個字段是否出現在該列表中 – xuanji

+0

請編輯該問題以澄清:您的意思是*相同*行(在這種情況下'comm'或'diff'應該工作)還是真的只是「相似」?如果是後者,請詳細說明你的相似概念(編輯距離,相同的字母,相同的語義,什麼?) – tripleee

回答

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,以便th以下是更多共同點)。

首先,讀取數據:

>>> 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 
+0

感謝!那正是我所需要的......並使用熊貓......獎金。再次感謝。 – Matt

0
$ join <(sort file1) <(sort file2) > duplicated-lines 
+0

在這種情況下,很容易改變命令從每個文件首先獲得唯一的行... –

+0

我有更改命令以在單獨的文件中搜索重複項。 –

+0

我不認爲「通信」將解決這個問題。你嘗試過「加入」嗎?請注意,這些文件只有一個共同的列。 – mattbornski

1

既然你添加的蟒蛇標籤,看來你想是這樣的:

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 
+0

太棒了!我更喜歡命令行方式;-) –

+0

@carlosdc - 我試圖運行你的建議,我不斷收到'Traceback(最近呼叫最後): 文件「split.py」,第8行,在 dialect = csv .Sniffer()。sniff(csvfile,方言) NameError:名稱'方言'未定義'任何想法爲什麼可能會發生? – Matt

+0

我不做嗅探(csvfile,方言)我做嗅探(csvfile.read(10024)) – carlosdc

0

的一種方式(提供的文件不是太大)將是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) 

有可能這樣做的更有效的方式,但是這將做的工作,並讓你把更多的邏輯要求。

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') 
0

bash使用grepsed。對於非常大的文件,這可能不是很好。

grep -f <(sed 's/^/^/' file2.txt) file1.txt 
相關問題