Python 如何搜索非常大的csv文件?

Python 如何搜索非常大的csv文件?,python,csv,Python,Csv,我有两个csv文件(其中一个是.tab),都有两列数字。我的工作是检查第一个文件的每一行,看看它是否与第二个文件中的任何一行匹配。如果有,我会在输出csv文件中打印一个空行。否则,我会将“R,R”打印到输出csv文件中。我当前的算法执行以下操作: 扫描第二个文件的每一行(每行两个整数),转到2D数组中这两个整数的位置(因此,如果整数是2和3,我将转到位置[2,3]),并指定一个值1 检查第一个文件的每一行,检查每一行的两个整数在数组中的位置是否为1,然后根据第三个csv文件打印相应的输出 不幸的

我有两个csv文件(其中一个是.tab),都有两列数字。我的工作是检查第一个文件的每一行,看看它是否与第二个文件中的任何一行匹配。如果有,我会在输出csv文件中打印一个空行。否则,我会将“R,R”打印到输出csv文件中。我当前的算法执行以下操作:

  • 扫描第二个文件的每一行(每行两个整数),转到2D数组中这两个整数的位置(因此,如果整数是2和3,我将转到位置[2,3]),并指定一个值1
  • 检查第一个文件的每一行,检查每一行的两个整数在数组中的位置是否为1,然后根据第三个csv文件打印相应的输出
  • 不幸的是,csv文件非常大,所以我在运行此程序时立即得到“MemoryError:”。扫描大型csv文件的替代方法是什么

    我用的是Jupyter笔记本。我的代码:

    import csv
    import numpy
    
    def SNP():
        thelines = numpy.ndarray((6639,524525))
        tempint = 0
        tempint2 = 0
        with open("SL05_AO_RO.tab") as tsv:
            for line in csv.reader(tsv, dialect="excel-tab"):
                tempint = int(line[0])
                tempint2 = int(line[1])
                thelines[tempint,tempint2] = 1
        return thelines
    
    def common_sites():
        tempint = 0
        tempint2 = 0
        temparray = SNP()
        print('Checkpoint.')
        with open('output_SL05.csv', 'w', newline='') as fp:
            with open("covbreadth_common_sites.csv") as tsv:
                for line in csv.reader(tsv, dialect="excel-tab"):
                    tempint = int(line[0])
                    tempint2 = int(line[1])
                    if temparray[tempint,tempint2] == 1:
                        a = csv.writer(fp, delimiter=',')
                        data = [['','']]
                        a.writerows(data)
                    else:
                        a = csv.writer(fp, delimiter=',')
                        data = [['R','R']]
                        a.writerows(data)
        print('Done.')
        return
    
    common_sites()
    
    档案:
    而你所看到的数据集实际上并没有那么大,但它相对稀疏。您没有使用稀疏结构来存储导致问题的数据。
    只需使用元组的
    集合
    来存储所看到的数据,然后在该
    集合
    上的查找是
    O(1)
    ,例如:

    In [1]:
      import csv
      with open("SL05_AO_RO.tab") as tsv:
          seen = set(map(tuple, csv.reader(tsv, dialect="excel-tab")))
      with open("covbreadth_common_sites.csv") as tsv:
          common = [line for line in csv.reader(tsv, dialect="excel-tab") if tuple(line) in seen]
      common[:10]
    Out[1]:
      [['1049', '7280'], ['1073', '39198'], ['1073', '39218'], ['1073', '39224'], ['1073', '39233'],
       ['1098', '661'], ['1098', '841'], ['1103', '15100'], ['1103', '15107'], ['1103', '28210']]
    
    10 loops, best of 3: 150 ms per loop
    
    In [2]:
      len(common), len(seen)
    Out[2]:
      (190, 138205)
    
    我有两个csv文件(其中一个是.tab),都有两列数字。我的工作是检查第一个文件的每一行,看看它是否与第二个文件中的任何一行匹配。如果有,我会在输出csv文件中打印一个空行。否则,我会将“R,R”打印到输出csv文件中

    将numpy导入为np
    f1=np.loadtxt('SL05\u AO\u RO.tab')
    f2=np.loadtxt('covWidth\u common\u sites.csv')
    f1.排序(轴=0)
    f2.排序(轴=0)
    i、 j=0,0
    而if2[j][0]:
    j+=1
    而jf2[j][1]:
    j+=1
    如果j
  • 将数据加载到
    ndarray
    以优化内存使用
  • 排序数据
  • 在排序数组中查找匹配项
  • 总的复杂度是O(n*log(n)+m*log(m))
    ,其中n和m是输入文件的大小


    使用
    set()
    不会减少每个唯一项的内存使用量,因此我不建议将其用于大型数据集。

    问题可能是:
    numpy.ndarray((6639524525))
    。您不应该使用
    ndarray
    构造函数,应该使用
    array
    zero
    。但不管怎样,您正在制作一个6639*524525数组,该数组包含
    np.float64
    ,至少需要
    6639*524525*1e-9*(64/8)
    =
    27.8585718
    gig。但是看看你的文件,它们很小,你可以把它们都加载到内存中,从一个文件中创建一个集合,然后遍历另一个文件,检查集合的成员资格。使用与可能得到的数字相同大小的数组可能是实现这一点的内存效率最低的方法。
    import numpy as np
    
    f1 = np.loadtxt('SL05_AO_RO.tab')
    f2 = np.loadtxt('covbreadth_common_sites.csv')
    
    f1.sort(axis=0)
    f2.sort(axis=0)
    
    i, j = 0, 0
    while i < f1.shape[0]:
        while j < f2.shape[0] and f1[i][0] > f2[j][0]:
            j += 1
        while j < f2.shape[0] and f1[i][0] == f2[j][0] and f1[i][1] > f2[j][1]:
            j += 1
        if j < f2.shape[0] and np.array_equal(f1[i], f2[j]):
            print()
        else:
            print('R,R')
        i += 1