2013-05-20 92 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 
相关问题