3

私の質問は、HDF5 ファイルを書き込んだ後に無期限に閉じる方法です。

データを HDF5 ファイルに保存しようとしています。約 200 のフォルダーがあり、各フォルダーには今年の毎日のデータが含まれています。

HDFStoreiPython コンソールで次のコードを使用して pandasを使用してデータを取得して保存すると、しばらくすると関数が自動的に停止します (エラー メッセージは表示されません)。

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を使用しています。

その上、特にMethod 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
4

1 に答える 1

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)]]

したがって、この手法を使用すると、コードをデバッグして、開いているファイルの数が異常になる場所を見つけることができます。

于 2016-08-17T20:41:26.013 に答える