【问题标题】:Find only the rows that exist in one csv but not the other仅查找存在于一个 csv 中但不存在于另一个 csv 中的行
【发布时间】:2017-04-24 14:50:22
【问题描述】:

CSV_1.csv 具有以下结构:

ABC
DEF
GHI
JKL
MNO
PQR

CSV_2.csv 具有以下结构:

XYZ
DEF
ABC

CSV_2.csvCSV_1.csv 小很多,CSV_2.csv 中存在的许多行出现在CSV_1.csv 中。我想知道CSV_2.csv 中是否存在行但CSV_1.csv 中不存在。

这些文件没有排序。

较大的 csv 有接近 1000 万行,较小的表有大约 700 万行。

我该怎么做呢?我尝试了 python,但是从 CSV_2.csv 中获取每一行并与 CSV_1.csv 中的 1000 万行进行比较需要很多时间。

这是我在 python 中尝试过的:

with open('old.csv', 'r') as t1, open('new.csv', 'r') as t2:
    fileone = t1.readlines()
    filetwo = t2.readlines()

with open('update.csv', 'a') as outFile:
    for line in filetwo:
        if line not in fileone:
            outFile.write(line)

awk 浮现在脑海中。 awk 的确切代码是什么?

【问题讨论】:

标签: python csv awk


【解决方案1】:

是的,您的方法非常低效。以下应该更快,使用集合的O(1) 查找时间,并懒惰地遍历t2 中的行:

with open('old.csv', 'r') as t1, open('new.csv', 'r') as t2:
    fileone = frozenset(t1)

    with open('update.csv', 'a') as outFile:
        for line in t2:
            if line not in fileone:
                outFile.write(line)

【讨论】:

  • 你的解决方案给了我:fileone = freezeset(1) TypeError: 'int' object is not iterable
  • @Shoumik 这不是我的解决方案,我写了fileone = frozenset(t1),所以frozenset(**t1**) 不是frozenset(1)
【解决方案2】:

为了加快 Python 的实现速度,您应该使用查找速度快的数据结构。你应该试试set

变化:

fileone = t1.readlines()

收件人:

fileone = set(t1.readlines())

这将大大加快生产线:

if line not in fileone:

【讨论】:

    【解决方案3】:

    您可以使用 pandas 数据框。 从两个 csv 创建 2 个数据框。

    import pandas as pd
    df1= pd.DataFrame.from_csv('CSV_1.csv')
    df2= pd.DataFrame.from_csv('CSV_2.csv')
    >>> df1
       val
    0  ABC
    1  DEF
    2  GHI
    3  JKL
    4  MNO
    5  PQR
    >>> 
    >>> df2
       val
    0  XYZ
    1  DEF
    2  ABC
    >>> df = pd.merge(df1, df2, how='outer', indicator=True)
    >>> df
       val      _merge
    0  ABC        both
    1  DEF        both
    2  GHI   left_only
    3  JKL   left_only
    4  MNO   left_only
    5  PQR   left_only
    6  XYZ  right_only
    >>> uniqueRowsInCsv2 = df[ df['_merge'] == 'right_only' ]
    >>> uniqueRowsInCsv2
       val      _merge
    6  XYZ  right_only
    >>> 
    

    【讨论】:

      【解决方案4】:

      您可以将数据加载到集合中并使用集合差异操作来加速:

      with open('old.csv', 'r') as t1, open('new.csv', 'r') as t2:
          old_set = set(t1.readlines())
          new_set = set(t2.readlines())
      
      # values in new_set but not in old_set
      differences =  new_set.difference(old_set)
      with open('update.csv', 'a') as outFile:
          for difference in differences:
              outFile.write(difference)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-30
        • 1970-01-01
        • 2021-09-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-27
        相关资源
        最近更新 更多