在编写多个HDF5文件时,Windows中打开的文件太多

时间:2016-08-17 17:31:08

标签: python pandas hdf5 hdfstore

我的问题是如何在编写后无限期关闭HDF5文件

我正在尝试将数据保存到HDF5文件 - 大约有200个文件夹,每个文件夹包含今年每天的一些数据。

当我使用iPandthon控制台中的以下代码使用pandas HDFStore检索和保存数据时,该功能会在一段时间后自动停止(无错误信息)。

import pandas as pd

data = ... # in format as pd.DataFrame
# Method 1
data.to_hdf('D:/file_001/2016-01-01.h5', 'type_1')
# Method 2
with pd.HDFStore('D:/file_001/2016-01-01.h5', 'a') as hf:
    hf['type_1'] = data

当我尝试使用相同的脚本再次下载数据时,它说:

  

[Errno 24]打开的文件过多:...

有些帖子建议在Linux中使用 ulimit -n 1200 来解决问题,但不幸的是我正在使用Windows。

此外,我认为我已经使用带有闭包的显式关闭文件,尤其是在方法2 中。为什么iPython仍将这些文件视为开放?

我的循环如下:

univ = pd.read_excel(univ_file, univ_tab)
for dt in pd.DatetimeIndex(start=start_date, end=end_date, freq='B'):
    for t in univ:
        data = download_data(t, dt)
        with pd.HDFStore(data_file, 'a') as hf:
            # Use pd.DataFrame([np.nan]) instead of pd.DataFrame() to save space
            hf[typ] = EMPTY_DF if data.shape[0] == 0 else data

先谢谢!

1 个答案:

答案 0 :(得分:1)

您可以使用psutil模块在​​Windows中检查/列出属于Python进程的所有打开文件。

演示:

In [52]: [proc.open_files() for proc in psutil.process_iter() if proc.pid == os.getpid()]
Out[52]:
[[popenfile(path='C:\\Windows\\System32\\en-US\\KernelBase.dll.mui', fd=-1),
  popenfile(path='C:\\Users\\Max\\.ipython\\profile_default\\history.sqlite-journal', fd=-1),
  popenfile(path='C:\\Users\\Max\\.ipython\\profile_default\\history.sqlite', fd=-1)]]

一旦我们完成以下块,文件处理程序将立即关闭:

In [53]: with pd.HDFStore('d:/temp/1.h5', 'a') as hf:
   ....:     hf['df2'] = df
   ....:

证明:

In [54]: [proc.open_files() for proc in psutil.process_iter() if proc.pid == os.getpid()]
Out[54]:
[[popenfile(path='C:\\Windows\\System32\\en-US\\KernelBase.dll.mui', fd=-1),
  popenfile(path='C:\\Users\\Max\\.ipython\\profile_default\\history.sqlite', fd=-1)]]

检查psutil是否正常工作(注意D:\\temp\\aaa):

In [55]: fd = open('d:/temp/aaa', 'w')

In [56]: [proc.open_files() for proc in psutil.process_iter() if proc.pid == os.getpid()]
Out[56]:
[[popenfile(path='C:\\Windows\\System32\\en-US\\KernelBase.dll.mui', fd=-1),
  popenfile(path='D:\\temp\\aaa', fd=-1),
  popenfile(path='C:\\Users\\Max\\.ipython\\profile_default\\history.sqlite', fd=-1)]]

In [57]: fd.close()

In [58]: [proc.open_files() for proc in psutil.process_iter() if proc.pid == os.getpid()]
Out[58]:
[[popenfile(path='C:\\Windows\\System32\\en-US\\KernelBase.dll.mui', fd=-1),
  popenfile(path='C:\\Users\\Max\\.ipython\\profile_default\\history.sqlite', fd=-1)]]

因此,使用这种技术,您可以调试代码并找到打开文件数量疯狂的地方