【问题标题】:Checking if csv files have same items检查csv文件是否有相同的项目
【发布时间】:2017-05-14 14:28:08
【问题描述】:

我有两个 .csv 文件。一个有info1,一个有info2。文件如下所示
文件1:

20170101,,,d,4,f,SWE
20170102,a,,,d,f,r,RUS  <-

文件2:

20170102,a,s,w,,,,RUS  <-
20170103,d,r,,,,FIN

我想将这两行(标记为“

20170102,a,s,w,d,f,r,RUS 

我知道我可以编写类似这样的脚本:

for row1 in csv_file1:
    for row2 in csv_file2:
        if (row1[0] == row2[0] and row1[1] == row2[1]):
            do something

有没有其他方法可以找出哪些行在开头有相同的项目,或者这是唯一的方法?这是找出相似之处的非常慢的方法,并且需要几分钟才能在 100 000 个行文件上运行。

【问题讨论】:

  • 我建议合并文件,然后按前两列而不是嵌套循环排序
  • 哪些列使行匹配?它只是第一列(例如,RUS 不会有 20170101)还是组合?另外,顺序重要吗?
  • 一行有35个项目。项目 0-4 在两个文件中,5-9 在文件 1 中,10-20 在文件 2 中,21-34 在两个文件中。

标签: python list csv


【解决方案1】:

您的实现是O(n^2),将一个文件中的所有行与另一个文件中的所有行进行比较。如果您为第一个文件中的每一行重新读取第二个文件,那就更糟了。

您可以通过从第一个文件的内容构建索引来显着加快这一速度。索引可以像字典一样简单,文件的第一列作为键,行作为值。 您可以在第一个文件上一次构建该索引。 然后对第二个文件进行一次传递, 如果 id 在索引中,则检查每一行。 如果是,则打印合并的行。

index = {row[0]: row for row in csv_file1}

for row in csv_file2:
    if row[0] in index:
        # do something

特别感谢@martineau 提供dict comprehension 版本的索引构​​建。

如果第一个文件中可以有多个具有相同 id 的项目, 那么索引可以指向这些行的列表:

index = {}
for row in csv_file1:
    key = row[0]
    if key not in index:
        index[key] = []
    index[key].append(row)

这可以使用defaultdict 稍微简化一下:

from collections import defaultdict

index = defaultdict(list)
for row in csv_file1:
    index[rows[0]].append(row)

【讨论】:

  • 感谢@martineau,发现得很好! (用你的学分更新了帖子)
  • 有多个项目具有相同的日期(= 行中的第一个项目),这不起作用。
  • @tmi12 你忘了在问题中提到这一点:-/我更新了我的答案来处理这种情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-21
  • 1970-01-01
  • 2015-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多