2017-01-24 17 views
1

我有一个需要读取数据的项目,然后根据每行写入超过23个CSV文件。例如,如果线即将下,我们应该写temperature.csv,如果关于湿度,>>将humid.CSV等如何并行打开超过19个文件(Python)?

我试过如下:

with open('Results\\GHCN_Daily\\MetLocations.csv','wb+') as locations, \ 
      open('Results\\GHCN_Daily\\Tmax.csv','wb+')as tmax_d, \ 
      open('Results\\GHCN_Daily\\Tmin.csv','wb+')as tmin_d, \ 
      open('Results\\GHCN_Daily\\Snow.csv', 'wb+')as snow_d, \ 
      . 
      . 
      # total of 23 'open' statements 
      . 

      open('Results\\GHCN_Daily\\SnowDepth.csv','wb+')as snwd_d, \ 
      open('Results\\GHCN_Daily\\Cloud.csv', 'wb+')as cloud_d, \ 
      open('Results\\GHCN_Daily\\Evap.csv', 'wb+')as evap_d, \ 

我得到了以下错误

SystemError: too many statically nested blocks python 

我搜索了这个错误,我得到this post它说,

你会encount呃这个错误时,你组块超过20 这是Python解释器的设计决定限制它20

但我写的公开声明中打开并行的文件,而不是嵌套。

我在做什么错,我该如何解决这个问题?

在此先感谢。

+1

我不确定它是否适合您想要做的工作,但为什么不打开并读取文件并将它们存储在字典中,文件名作为关键字,在它上面工作并在完成后写入它们? – hashcode55

+0

或者您可以制作一个excel工作簿并制作一堆不同的工作表 – aberger

+0

非常感谢您的意见和建议@aberger。实际上,原始数据非常庞大(47 GB),因此生成的表格也是如此,这就是为什么无法使用Excel甚至是单个Access数据库的原因。 –

回答

2

每个打开的是一个嵌套的背景下,它只是Python语法允许你把它们放在一个逗号分隔列表。 contextlib.ExitStack是一个上下文容器,它允许您在堆栈中放置尽可能多的上下文,并在完成时退出每个上下文。所以,你可以做

import contextlib 

files_to_process = (
    ('Results\\GHCN_Daily\\MetLocations.csv', 'locations'), 
    ('Results\\GHCN_Daily\\Tmax.csv', 'tmax_d'), 
    ('Results\\GHCN_Daily\\Tmin.csv', 'tmin_d'), 
    # ... 
) 

with contextlib.ExitStack() as stack: 
    files = {varname:stack.enter_context(open(filename, 'rb')) 
     for filename, varname in files_to_process} 
    # and for instance... 
    files['locations'].writeline('my location\n') 

如果您发现dict访问比属性访问欠整齐,你可以创建一个简单的容器类

class SimpleNamespace: 

    def __init__(self, name_val_pairs): 
     self.__dict__.update(name_val_pairs) 

with contextlib.ExitStack() as stack: 
    files = SimpleNamespace(((varname, stack.enter_context(open(filename, 'rb'))) 
     for filename, varname in files_to_process)) 
    # and for instance... 
    files.locations.writeline('my location\n') 
+1

非常感谢@tdelaney,这解决了这个问题。 **附加说明:**我使用Python 2.7 *,其中'contextlib.ExitStack()'不可用。所以我导入了替代库'contextlib2.ExitStack()'。因此,Py2.7用户应该导入'contextlib2'而不是'context lib'。 –

0

如果数据不是很大,为什么不读取所有数据并按类别对数据进行分组(例如,将所有关于温度的数据放入一个组中),然后将分组数据一次写入相应的文件中?

+0

在处理数据时,OP可以更好地解决csvs问题。 – tdelaney

+0

的确,我的可扩展性 – OceanBlue

+0

数据非常庞大(47 GB)。这就是为什么我想把它们分成变量。 –

1

我将具有可能的文件=列表[“湿度”,“温度”,...]
使包含可能的文件,一个数据帧,该文件的路径,例如DIC:

main_dic = {} 

for file in possible_files: 

    main_dic[file][path] = '%s.csv' %file 
    main_dic[file][data] = pd.DataFrame([], columns=['value','other_column','another_column', ....]) 

事后,我WLD什么读什么文档,你都可以从价值观和EM存储在正确的字典数据帧。

完的时候只是节省CSV,例如数据:

for file in main_dic: 

    main_dic[file][data].to_csv('%s.csv' %file, index=False) 

希望它有助于

+0

我没有看到一堆核心数据框在这里是一个很好的解决方案。他只是煽动多个csvs。这会使内存膨胀并使解决方案的可扩展性降低。 – tdelaney

-1

这将是确定这种方式来打开> 20个文件。

# your list of file names 
file_names = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u'] 
fh = [] # list of file handlers 
for idx,f in enumerate(files): 
    fileName = f + '.txt' 
    fh.append(open(fileName,'w')) 

# do what you need here 
print "done" 

for f in fh: 
    f.close() 

虽然不知道你是否真的需要这样做。

+0

但是,OP希望将它们放在'with'子句中,以便文件在退出时自动关闭......即使在其中一个文件无法打开的情况下也是如此。您的解决方案不具有OP所需的功能。 – tdelaney