【问题标题】:compare columns in two csv files and extract the matched column in a third csv file比较两个 csv 文件中的列并在第三个 csv 文件中提取匹配的列
【发布时间】:2013-12-14 02:03:45
【问题描述】:

我想比较两个 csv 文件中的列并提取匹配的值,如下所示:

file1.csv 是

115.06603, 5.9

114.74721, 5.4

114.85107, 6.2

111.17744, 5.5

192.77787, 3.2

189.70226, 5

0.46762, 3.7

2.21539, 3.5

2.96667, 3.6

而file2.csv是

115.06603

115.06603

114.74721

114.74721

114.74721

114.74721

114.85107

114.85107

114.85107

114.85107

114.85107

111.17744

111.17744

输出文件 file3.csv 应该是

115.06603, 5.9

115.06603, 5.9

114.74721, 5.4

114.74721, 5.4

114.74721, 5.4

114.74721, 5.4

114.85107, 6.2

114.85107, 6.2

114.85107, 6.2

114.85107, 6.2

114.85107, 6.2

111.17744, 5.5

111.17744, 5.5

我使用了以下代码,但输出文件只给出第一列而不是两列。你能帮我解决这个问题吗?

>>> with open("file1.csv", "rb") as in_file1, open("file2.csv", "rb") as in_file2,    open("file3.csv", "wb") as out_file:
...   reader1 = csv.reader(in_file1)
...   reader2 = csv.reader(in_file2)
...   writer = csv.writer(out_file)
...   for row2 in reader2:
...     for row1 in reader1:
...       if row2[0] == row1[0]:
...         row2[1] = row1[1]
...     writer.writerow(row2)

编辑 我使用了你的代码,但第一部分给出了以下错误:

data1 = {}
with open("file1.csv", "rb") as in_file1:
...   reader1 = csv.reader(in_file1)
...   for row1 in reader1:
...     data1[row1[0]] = row1[1]
... 
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
IndexError: list index out of range

因为 file1.csv 中的分隔符是 ;不是,我加了 delimiter=';'如下

data1 = {}
with open("file1.csv", "rb") as in_file1:
...   reader1 = csv.reader(in_file1, delimiter=';')
...   for row1 in reader1:
...     data1[row1[0]] = row1[1]
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
IndexError: list index out of range

和你看到的一样的错误

我添加了 in.file.seek(0) 如下

data1 = {}
with open("file1.csv", "rb") as in_file1:
...   reader1 = csv.reader(in_file1)
...   for row1 in reader1:
...     in_file1.seek(0)
...     data1[row1[0]] = row1[1]
... 
Traceback (most recent call last):
File "<stdin>", line 5, in <module>
IndexError: list index out of range

同样的错误。问题是什么?我好郁闷。

编辑

我用来删除空行的代码

with open("file2.csv", "r") as in_file2, open("out.csv", "w") as out_file:
...  reader2 = csv.reader(in_file2)
...  writer = csv.writer(out_file)
...  for row in reader2:
...    if any(field.strip() for field in row):
...      writer.writerow(row)

【问题讨论】:

  • 编辑下的第一个块对我来说适用于没有空行的逗号分隔文件。所以:1.你为什么使用“b”模式来读取文件,2.你的输入文件中有空行,如果有,你需要把它们去掉(或者如果 row1 的长度为 0,则忽略它们)跨度>
  • 我将 file1.csv 中的分隔符从 ; ,并且它正在工作。但是这段代码也没有与 file2.csv 匹配。可能是什么问题呢?您之前是否使用过此代码并工作过?
  • 如果您回答我在上一条评论中提出的问题,我可能会为您提供更好的帮助。
  • 1-我从代码中省略了b,因为不需要使用“b”模式。 2-是的,我在 file1.csv 中有空行,但我忽略了它们。
  • 您是否尝试在遍历第一个文件时放置一个打印语句以查看实际存储到 data1 中的内容?你忽略空行的代码是什么?

标签: python csv


【解决方案1】:

这一行

row2[1] = row1[1]

不起作用,因为 row2[1] 还不存在。

你应该使用

row2.append(row1[1])

改为。

编辑 此外,内部 for 循环也只执行第一次,因为文件只能迭代一次。您应该执行以下操作:

data1 = {}
with open("file1.csv", "rb") as in_file1:
     reader1 = csv.reader(in_file1)
     for row1 in reader1:
         data1[row1[0]] = row1[1]
with open("file2.csv","rb") as in_file2, open("file3.csv","wb") as out_file:
    reader2 = csv.reader(in_file2)
    writer = csv.writer(out_file)
    for row2 in reader2:
        if row2[0] in data1:
            row2.append(data1[row2[0]])
        writer.writerow(row2)

请注意,这实际上会将所有 file1 加载到内存中。如果这是一个问题,您可以通过在原始代码中迭代 reader1 后添加 in_file1.seek(0) (或类似的东西来倒带与 csv 阅读器一起播放的文件)来解决仅读取文件一次的问题。不过这种方法会比我提供的要慢。

【讨论】:

  • 我将代码中的行 row2[1] = row1[1] 替换为 row2.push(row1[1]) 但也只在第一列给出了相同的结果。
  • 哦,我刚刚意识到您正在为第二个文件的每一行迭代第一个文件。为此,您需要每次在外循环中倒回第一个文件。但是,循环遍历第一个文件一次,并将数据存储在字典中,以第一列作为键,然后遍历第二个文件并根据该键查找值会更有效。
  • 我很抱歉,但我是使用 python 的新手,所以我听不懂你说的。请把它翻译成我可以使用的代码吗?
【解决方案2】:

Awk 会为您轻松做到这一点:

awk -F, 'FNR==NR{a[$1]=$0;next}{print a[$1]}' file1.csv file2.csv

结果:

115.06603, 5.9
115.06603, 5.9
114.74721, 5.4
114.74721, 5.4
114.74721, 5.4
114.74721, 5.4
114.85107, 6.2
114.85107, 6.2
114.85107, 6.2
114.85107, 6.2
114.85107, 6.2
111.17744, 5.5
111.17744, 5.5

这是它的工作原理...首先,“-F”表示字段分隔符是逗号。然后,“FNR==NR”部分告诉 awk 在查看第一个文件 (file1.csv) 时只处理第一组花括号 ({}) 之间的内容。也就是说,将整行 ($0) 存储到一个名为“a”的数组中,该数组位于 file1.csv 的第一列指定的位置。第二组花括号 ({}) 之间的部分适用于 file2.csv 的处理。它说在当前文件(file2.csv)的第一列给定的索引处打印数组“a”中的条目。

【讨论】:

  • 报错>>> awk -F, 'FNR==NR{A[$1]=$0;next}{print a[$1]}' file1.csv file2.csv File " ", line 1 awk -F, 'FNR==NR{A[$1]=$0;next}{print a[$1]}' file1.csv file2.csv ^ SyntaxError: invalid syntax
  • 你有 A[] 而不是 a[]。
  • 尝试复制和粘贴命令,而不是自己输入命令 - 它应该可以正常工作 - 如果我从上面复制它并将其粘贴到我的机器上,它是 Mac 和 Ubuntu。
  • 我认为问题出在 file1.csv 因为分隔符是 ;不是,我应该在代码中更改什么?
  • awk -F";" 'FNR==NR{a[$1]=$0;next}{print a[$1]}' file1.csv file2.csv
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-24
  • 1970-01-01
相关资源
最近更新 更多