2014-03-31 82 views
1

我有兩個文件作爲輸入。 (它們各自有更多的列,但我只將其縮小到重要的列)Python數據操作

A 15.6   A D 
B 10.3   A B 
C 12.5   A E 
D 14.5   A Y 
E 11.4   C A 
F 23.7   C B 
        C R 
        D A 
        D R 
        D F 

第一個文件是一種索引。我想查看第二個文件,並通過在第一個文件中查找它們的值並打印出具有較小值的鍵(如果其中一個鍵不在索引文件中,然後打印另一個鍵默認)。之後,我想刪除所有的重複條目,即

D 14.5 
B 10.3 
E 11.4    A 15.6 
A 15.6    B 10.3 
C 12.5 -------> C 12.5 
B 10.3    D 14.5 
C 12.5    E 11.4 
D 14.5 
D 14.5 
D 14.5 

所以,它本質上是一個索引文件的減少。必須有在Python優雅的方式做這件事......

+0

你基本上將第一個文件減少爲只有在s中具有值的條目第二個文件中的第二列.. –

+0

使用集合https://docs.python.org/2/library/sets.html – UnX

回答

2
mapping = dict() 
result = set() 

with open(filename1, 'r') as f1, open(filename2, 'r') as f2: 
    for line in f1: 
     line = line.split() 
     if line: 
      key, val = line 
      mapping[key] = float(val) #1 

    for line in f2: 
     line = line.split()   
     if line: 
      key1, key2 = line 
      if key1 in mapping: #4 
       result.add(min(line, key=lambda x: mapping.get(x, float('inf')))) #2 

for key in result: 
    print('{k} {v}'.format(k=key, v=mapping[key])) #3 
  1. 負載從第一個文件中的數據到一個字典(稱爲mapping )。
  2. 收集集合中與最小值關聯的所有密鑰(稱爲result)。
  3. 報告密鑰。請注意,因爲resultset,所以沒有 預定義的順序,其中將會報告密鑰。
  4. 根據註釋中的額外要求,忽略其中key1 不在第一個文件中的行。
+0

真棒代碼!謝謝!快速的問題 - 如果filename2碰巧是一個多列的大文件,我只想考慮key1與filename2中任何一個鍵匹配的行 - 如何修改上面的代碼? (在我的基本bash腳本中,我會grep文件名1中的每個鍵的大文件名2 ...這是相當低效的)。再次感謝! –

+0

您可以在映射中使用'if key1'。我已經編輯了上面的帖子來顯示位置。 – unutbu

+0

我可能通過看到有人使用這個知道了這一點,儘管我不記得誰或我在哪裏。它工作的原因是[記錄在這裏](https://docs.python.org/3/library/stdtypes.html#truth-value-testing):空元組的真值是False,否則爲True。因此'如果行'(在使用'line = line.split()'在空白處分割之後)是測試'行'是否具有非空白內容的方式。 – unutbu

1

這可能是一個辦法:

#1. Make a dictionary of the first file, so the look up is faster 

a_dict = {} 
for line in first_file: 
    a, b = line.strip().split() 
    a_dict[a] = b 

#2. Get the second item in each line of second file and get 
# its corresponding value from the dictionary we built. 
# op is another dict and will take care of getting rid of 
# duplicates. 

op = defaultdit(list) 
for line in second_file: 
    a, b = line.split().strip() 
    op[a].append(a_dict[b]) 

#3. Get the minimum value of all the candidates 

res = {} 
for k, v in op: 
    res[k] = min(v) 

print res 
1

您可以使用壓縮如下:

with open("file1.txt","r") as file1, open("file2.txt","r") as file2: 
    for l1,l2 in zip(file1.readlines(), file2.readlines()): 
     l1d=l1.split() 
     l2d=l2.split() 
     if l1d[0]==l2d[0]: 
      if float(l1d[1]) < float(l2d[1]): 
       print l1 
      else: 
       print l2 
  1. 閱讀這兩個文件
  2. 使用拉鍊迭代基於分割結果這兩個文件系
  3. 搜索最小值,並顯示最小保串
+0

工作很好,更容易爲noob(像我一樣)閱讀和理解。我給unutbu解決方案複選標記,雖然...該代碼是如此緊張...只是研究它給了我一個更大的理解和python的感覺。謝謝。 –