【问题标题】:Read the csv file and add only new entries in another csv file读取 csv 文件并在另一个 csv 文件中仅添加新条目
【发布时间】:2015-08-05 08:59:39
【问题描述】:

我有一个 csv 文件,我每天都会添加重复的和唯一的数据。这涉及太多重复项。我必须根据特定列删除重复项。例如:

csvfile1:

title1 title2 title3 title4 title5
abcdef 12     13     14     15
jklmn  12     13     56     76
abcdef 12     13     98     89
bvnjkl 56     76     86     96

现在,基于 title1、title2 和 title3,我必须删除重复项并将唯一条目添加到新的 csv 文件中。如您所见,abcdef 行不是唯一的,并且基于 title1、title2 和 title3 重复,因此应将其删除,输出应如下所示:

预期输出 CSV 文件:

title1 title2 title3 title4 title5
jklmn  12     13     56     76
bvnjkl 56     76     86     96

我尝试过的代码如下:CSVINPUT 文件 导入csv

f = open("1.csv", 'a+')

writer = csv.writer(f)

writer.writerow(("t1", "t2", "t3"))

a =[["a", 'b', 'c'], ["g", "h", "i"],['a','b','c']] #This list is changed daily so new and duplicates data get added daily


for i in range(2):
    writer.writerow((a[i]))

f.close()

重复删除脚本:

import csv




with open('1.csv','r') as in_file, open('2.csv','w') as out_file:
    seen = set() # set for fast O(1) amortized lookup
    for line in in_file:
        if line not in seen: continue # skip duplicate


        out_file.write(line)

我的输出: 2.csv:

t1 t2 t3
a  b  c
g  h  i

现在,我不希望 2.csv 中基于 t1 和 t2 的 b c 只有基于 t1 和 t2 的唯一 g h i

【问题讨论】:

  • 你有什么问题?

标签: python csv


【解决方案1】:

代码中的一些问题 -

  1. 在创建csv文件的python文件中,你只是迭代直到-range(2)range不包括在内,所以它只将前两列写入csv,而不是第三列,你可以直接遍历 csv,而不是遍历每个元素。此外,您不需要在 writer.writerow() 中使用那么多括号,例如 -

    for i in a:
        writer.writerow(i)
    
  2. 在您的重复删除脚本中,您实际上从未向 seen() 添加任何内容,因此您将永远不会删除任何内容。当您想根据列表的元素子集删除重复项时,您只需将这些元素(按特定顺序)添加到 seen 集合(作为元组),而不是列表,因为 set() 只接受可散列的元素。然后在检查集合中的包含时,仅检查您添加的那个子集。示例 -

    import csv
    with open('1.csv','r') as in_file, open('2.csv','w') as out_file:
        seen = set()
        seentwice = set()
        reader = csv.reader(in_file)
        writer = csv.writer(out_file)
        rows = []
        for row in reader:
            if (row[0],row[1]) in seen:
                seentwice.add((row[0],row[1]))
            seen.add((row[0],row[1]))
            rows.append(row)
        for row in rows:
            if (row[0],row[1]) not in seentwice:
                writer.writerow(row)
    

这将完全删除基于第一列和第二列重复的所有行。它甚至不会为这些行存储一行,我猜这就是你想要的。

seen - set - 用于存储我们已经看到的行。

seentwice - set - 如果我们遇到之前已添加到 seen 的行,则此 set 仅填充一行,这意味着该行是重复的。

现在最后,我们只想写不在 seentwice 内的 rows ,因为 seentwice 中的任何 row 都意味着它是重复的,该行至少有两个不同的行具有相似的值row[0]row[1]

【讨论】:

  • 你不需要向s中传递任何内容,当(row[0],row[1])中的列发生相应变化时,0表示第一列,1表示第二列。
  • 第一,第二和第三最后使用01-3
  • 不,你没有。上面的代码就足够了,你的新列在 (row[..],...) 中。
  • 实际上,我在理解所见所见有问题?它包含什么?因为 set 是空的,对吧?
  • 不,我们在第一个 for 循环中添加它。对吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-05
  • 1970-01-01
  • 2020-05-05
  • 1970-01-01
  • 2017-08-03
  • 1970-01-01
相关资源
最近更新 更多