2015-10-20 89 views
-1

我是一名Python初學者,我試圖比較兩個csv文件中的兩個字段(時間戳),如果它們匹配,則將它們合併到第三個文件中。輸入文件看起來像:比較和合並兩個CSV文件中的字段

文件1:

name,time,operation 
Cassandra,2015-10-06T15:07:22.333662984Z,INSERT 
Cassandra,2015-10-06T15:07:24.334536781Z,INSERT 
Cassandra,2015-10-06T15:07:27.339662984Z,READ 

文件2:

name,time,host,instance,type,type_instance,value 
cpu_value,2015-10-06T15:07:22.333662984Z,vm1-VirtualBox,0,cpu,user,24874 
cpu_value,2015-10-06T15:07:24.334536781Z,vm1-VirtualBox,0,cpu,nice,592 
cpu_value,2015-10-06T15:07:27.339662984Z,vm1-VirtualBox,0,cpu,system,2932 

這是我到目前爲止已經試過:

import csv 

with open('f1.csv', 'rb') as f1, open ('f2.csv', 'rb') as f2: 
    next(f1) #skip line 1 
    next(f2) #skip line 1 
    reader1 = csv.reader(f1) 
    reader2 = csv.reader(f2) 
    for row1 in reader1: 
      for row2 in reader2: 
        if row1[1] == row2[1]: 
          data = [row1[0],row2[0]] 
          print data 

然後,我得到這個錯誤:

['cpu_value', 'Cassandra'] 
Traceback (most recent call last): 
File "merger.py", line 10, in <module> 
if row1[1] == row2[1]: 
IndexError: list index out of range 

更新

預期輸出:

Cassandra,2015-10-06T15:07:22.333662984Z,INSERT,cpu_value,vm1-VirtualBox,0,cpu,user,24874 
Cassandra,2015-10-06T15:07:24.334536781Z,INSERT,cpu_value,vm1-VirtualBox,0,cpu,nice,592 
Cassandra,2015-10-06T15:07:27.339662984Z,READ,cpu_value,vm1-VirtualBox,0,cpu,nice,592 

您可以通過這個link訪問這些文件。如果你有任何想法,請告訴我。謝謝。

+0

什麼是您預期的輸出? – aerokite

+0

@AerofoilKite我更新了帖子。 – arazx

+0

是否有可能這些csv文件之一有一個看似空的行或只有沒有足夠的字段的行?這就是錯誤信息暗示的原因。如果你不知道,你應該考慮添加一個鏈接到這兩個文件,以便其他人可以檢查他們。 –

回答

2

如果我們可以作一個假設,所有時間戳是獨一無二的,他們將完全匹配(即無插值是需要的),那麼我們可以通過將第一個文件讀入字典中,其中的鍵是時間戳並且值是CSV行來開始。

然後,我們讀取第二個文件,並且對於每個CSV行,在字典中查找。如果有匹配的行,我們可以打印它,或者存儲它,或者其他任何東西。此外,我們使用pop來刪除匹配的行,以便我們可以輕鬆找到最後無法匹配的行!

以下代碼應爲您的2 * 3行測試數據提供所需的輸出。

import csv 

matches = [] 
unmatched1 = [] 
unmatched2 = [] 
f1_dict = {} 

with open('f1.csv', 'r') as f1: 
    next(f1) # skip line 1 
    reader1 = csv.reader(f1) 
    for row1 in reader1: 
     f1_dict[row1[1]] = row1 

with open('f2.csv', 'r') as f2: 
    next(f2) # skip line 1 
    reader2 = csv.reader(f2) 
    for row2 in reader2: 
     row1 = f1_dict.pop(row2[1], None) 
     if row1 is None: 
      unmatched2.append(row2) 
     else: 
      matches.append((row1, row2)) 

unmatched1 = list(f1_dict.values()) 
for row1, row2 in matches: 
    output_row = row1 + [row2[0]] + row2[2:] 
    print(','.join(output_row)) # or use csv.writer 
+0

謝謝。我更新了該數據的訪問鏈接。 – arazx

+0

如何在特定時間多行? 你的地圖可以處理那 – aerokite

+0

@AerofoilKite:不,它不能處理 - 它只有在我們假設時間戳是唯一的(同一個文件中沒有兩個相同的時間戳)並且它們完全匹配兩個文件時才起作用(no插值需要) –

0
import csv 

L1 = [] 
L2 = [] 

with open('f1.csv', 'rb') as f1, open ('f2.csv', 'rb') as f2: 
    next(f1) #skip line 1 
    next(f2) #skip line 1 
    reader1 = csv.reader(f1) 
    reader2 = csv.reader(f2) 

    for row in reader1: 
     L1.append(row) 

    for row in reader2: 
     L2.append(row) 


for row1 in L1: 
    for row2 in L2: 
     if row1[1] == row2[1]: 
      data = row1+[row2[0]]+row[2:] 
      print data 

輸出:

['Cassandra', '2015-10-06T15:07:22.333662984Z', 'INSERT', 'cpu_value', 'vm1-VirtualBox', '0', 'cpu', 'system', '2932'] 
['Cassandra', '2015-10-06T15:07:24.334536781Z', 'INSERT', 'cpu_value', 'vm1-VirtualBox', '0', 'cpu', 'system', '2932'] 
['Cassandra', '2015-10-06T15:07:27.339662984Z', 'READ', 'cpu_value', 'vm1-VirtualBox', '0', 'cpu', 'system', '2932'] 

您可以嘗試熊貓據幀太:https://stackoverflow.com/a/33244071/1924666

+0

如何合併排序更正式的東西? –

1

您也可以使用熊貓據幀:pandas package

import csv 
import pandas as pd 

L1 = pd.read_csv('f1.csv') 
L2 = pd.read_csv('f2.csv') 

result = pd.merge(L1, L2, on='time') 

for row in result.values: 
    print row 

輸出:

['Cassandra' '2015-10-06T15:07:22.333662984Z' 'INSERT' 'cpu_value' 'vm1-VirtualBox' 0L 'cpu' 'user' 24874L] 
['Cassandra' '2015-10-06T15:07:24.334536781Z' 'INSERT' 'cpu_value' 'vm1-VirtualBox' 0L 'cpu' 'nice' 592L] 
['Cassandra' '2015-10-06T15:07:27.339662984Z' 'READ' 'cpu_value' 'vm1-VirtualBox' 0L 'cpu' 'system' 2932L] 

更多:http://pandas.pydata.org/pandas-docs/stable/merging.html