2015-10-20 45 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