【问题标题】:simple python sort over csv简单的python对csv排序
【发布时间】:2012-01-03 01:04:04
【问题描述】:

我有两个 csv 文件:一个是 98 mb,另一个是 152 kb。较小的文件是较大文件的随机子集,我想从大 csv 中写入第三个文件,以便行对应于较小 csv 文件中的每一行。

大文件(摘录):

ZINC_ID MWT LogP    Desolv_apolar   Desolv_polar    HBD HBA tPSA    Charge  NRB SMILES
ZINC00000017    281.337 1.33    3.07    -19.2   2   6   87  0   4   CCC[S@](=O)c1ccc2c(c1)[nH]/c(=N/C(=O)OC)/[nH]2
ZINC00000036    151.141 0.37    3.51    -45.3   1   3   60  -1  2   c1ccc(cc1)[C@@H](C(=O)[O-])O
ZINC00000048    222.24  2.42    3.78    -8.68   0   4   37  0   4   COc1cc(c(c2c1OCO2)OC)CC=C
ZINC00000053    179.151 1.43    6.59    -56.84  0   4   66  -1  3   CC(=O)Oc1ccccc1C(=O)[O-]

小文件(摘录):

SMILES
CCOc1ccc(cc1)NC(=O)C[C@@H](C)O
C[C@@H](c1ccc2c(c1)nc(o2)c3ccc(cc3)Cl)C(=O)[O-]
CC(=O)Oc1ccccc1C(=O)[O-]
COc1cc(c(c2c1OCO2)OC)CC=C

这是我的代码:

import csv

writer = csv.writer(open('/Users/Eric/Desktop/newZincSubset.csv','wb'))
count = 0
with open('/Users/Eric/Desktop/test700.csv','rU') as i:
    with open('/Users/Eric/Desktop/initial_data.csv','rU') as j:
        subject = csv.reader(i)
        reference = csv.reader(j)
        for row in subject:
            smiles = row[0]
            for reference_row in reference:
                suspect = reference_row[10]
                if (smiles == suspect):
                    writer.writerow(reference_row)

似乎可以很好地写入标题(ZINC_ID MWT LogP),但停止搜索每一行。是内存问题还是我的代码有问题?

谢谢!

【问题讨论】:

  • 是标题ZINC_ID MWT LogP还是整行?
  • ZINC_ID MWT LogP Desolv_apolar Desolv_polar HBD HBA tPSA Charge NRB SMILES 是标题。

标签: python csv


【解决方案1】:

CSV 阅读器只能迭代一次。第一次内部迭代完成后,底层文件对象到达文件末尾。一旦您第二次尝试迭代 reference 阅读器,就没有更多可阅读的内容了。

我建议您先将小文件读取到字典中,然后在较大的文件上迭代,搜索内存中数据的匹配项。您还可以根据最终要查找的内容来键入字典中的元素(我认为是参考 [10]),因此不需要嵌套循环。

【讨论】:

  • 他可以只读取样本(非常小)一次,将其存储在内存中,然后在大文件中的每一行对其进行迭代(避免占用大量 RAM)
  • +1 用于识别问题,尽管我实际上建议只将小文件读入内存并从其行中构建一个set。然后您仍然可以遍历大文件并对其进行处理,而无需将整个文件加载到内存中。
  • 正确,对于之前的评论者。我已经更新了最后一段。我实际上建议构建一个dict 而不是set,因为他可以使用密钥来有效查找他加入的属性。
  • @thesamet:set 也将允许高效查找 :),并且无需为每个键添加空值!
  • 谢谢,我将较小的文件加载到内存中,然后使用“for iterable in bigfile:”循环加载到较小内存中的文件中的每一行。
【解决方案2】:

一个实现(使用DictReaderDictWriter,利用标头):

import csv

with open('sample.csv','rU') as i: 
    smiles = set(x['SMILES'] for x in csv.DictReader(i))

with open('init.csv','rU') as j:
    reference = csv.DictReader(j, delimiter = '\t')
    fields = reference.fieldnames
    writer = csv.DictWriter(open('newZincSubset.csv','wb'),
                            fields,
                            delimiter = '\t')
    writer.writerow(dict((x,x) for x in fields))
    for reference_row in reference:
        if reference_row['SMILES'] in smiles:
            writer.writerow(reference_row)

【讨论】:

  • 注意:刚刚编辑了代码以使其使用制表符作为分隔符(似乎是示例中使用的)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-06
  • 2017-06-23
  • 1970-01-01
  • 1970-01-01
  • 2015-08-15
  • 2015-03-31
  • 2016-07-01
相关资源
最近更新 更多