2

glob用来将文件名提供给这样的循环:

inputcsvfiles = glob.iglob('NCCCSM*.csv')

for x in inputcsvfiles:

    csvfilename = x
    do stuff here

我用来制作此脚本原型的玩具示例适用于 2、10 甚至 100 个输入 csv 文件,但我实际上需要它来循环 10,959 个文件。当使用这么多文件时,脚本在第一次迭代后停止工作并且无法找到第二个输入文件。

鉴于脚本在“合理”数量的条目(2-100)下工作得非常好,但不是我需要的(10,959)是否有更好的方法来处理这种情况,或者我可以设置的某种参数允许大量迭代?

PS-最初我使用的是glob.glob,但 glob.iglob fairs 并没有更好。

编辑:

上面的扩展以获得更多上下文......

    # typical input file looks like this: "NCCCSM20110101.csv", "NCCCSM20110102.csv", etc.   
    inputcsvfiles = glob.iglob('NCCCSM*.csv')

    # loop over individial input files    
      for x in inputcsvfiles:

        csvfile = x
        modelname = x[0:5]

        # ArcPy
        arcpy.AddJoin_management(inputshape, "CLIMATEID", csvfile, "CLIMATEID", "KEEP_COMMON")

        do more stuff after

该脚本在 ArcPy 行失败,其中“csvfile”变量被传递到命令中。报告的错误是找不到指定的csv文件(例如,“NCCSM20110101.csv”),而实际上,csv肯定在目录中。难道你不能像我上面所说的那样多次重用声明的变量(x)吗?同样,如果要 glob'd 的目录只有 100 个左右的文件,这将正常工作,但如果有很多(例如,10,959),它似乎会在列表中的某个地方任意失败。

4

3 回答 3

1

尝试为这 10,000 个条目在 shell 上执行 ls *,shell 也会失败。遍历目录并为您的目的一一生成这些文件怎么样?

#credit - @dabeaz - generators tutorial

import os
import fnmatch

def gen_find(filepat,top):
    for path, dirlist, filelist in os.walk(top):
        for name in fnmatch.filter(filelist,filepat):
            yield os.path.join(path,name)

# Example use

if __name__ == '__main__':
    lognames = gen_find("NCCCSM*.csv",".")
    for name in lognames:
        print name
于 2012-07-26T18:11:42.210 回答
1

如果它适用于 100 个文件但对于 10000 个文件失败,则检查它在完成后arcpy.AddJoin_management关闭。csvfile

一个进程在任何时候可能拥有的打开文件的数量是有限制的(您可以通过运行来检查ulimit -n)。

于 2012-07-26T22:01:06.467 回答
1

出现的一个问题不是 Python 本身,而是 ArcPy 和/或MS 处理 CSV 文件(我认为更多的是后者)。随着循环的迭代,它会创建一个schema.ini文件,其中添加和存储循环中处理的每个 CSV 文件的信息。随着时间的推移,它schema.ini变得相当大,我相信这就是性能问题出现的时候。

我的解决方案虽然可能不优雅,但schema.ini在每个循环期间删除文件以避免该问题。这样做让我能够处理 10k+ CSV 文件,虽然速度相当慢。说实话,我们最终使用了 GRASS 和 BASH 脚本。

于 2014-08-20T02:05:56.247 回答