web-dev-qa-db-ja.com

pandasをHDF5に書き込むときに、pickleプロトコルを指定することは可能ですか?

Pandasに特定のピクルプロトコル(例:4)を使用するよう指示する方法はありますかHDF5ファイルを書き込むときに

これが状況です(かなり単純化されています):

  • クライアントAは_python=3.8.1_(および_pandas=1.0.0_および_pytables=3.6.1_)を使用しています。 Aはdf.to_hdf(file, key)を使用していくつかのDataFrameを書き込みます。

  • クライアントBは_python=3.7.1_を使用しています(そして、偶然にも、_pandas=0.25.1_および_pytables=3.5.2_-それは無関係です)。 Bはpd.read_hdf(file, key)を使用してAによって書き込まれたデータを読み取ろうとし、_ValueError: unsupported pickle protocol: 5_で失敗します。

ちなみに、これは純粋に数値のDataFrame(例:pd.DataFrame(np.random.normal(size=(10,10))))では発生しません。再現可能な例を次に示します。

_(base) $ conda activate py38
(py38) $ python
Python 3.8.1 (default, Jan  8 2020, 22:29:32)
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pandas as pd
>>> df = pd.DataFrame(['hello', 'world']))
>>> df.to_hdf('foo', 'x')
>>> exit()
(py38) $ conda deactivate
(base) $ python
Python 3.7.4 (default, Aug 13 2019, 20:35:49)
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pandas as pd
>>> df = pd.read_hdf('foo', 'x')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/anaconda3/lib/python3.7/site-packages/pandas/io/pytables.py", line 407, in read_hdf
    return store.select(key, auto_close=auto_close, **kwargs)
  File "/opt/anaconda3/lib/python3.7/site-packages/pandas/io/pytables.py", line 782, in select
    return it.get_result()
  File "/opt/anaconda3/lib/python3.7/site-packages/pandas/io/pytables.py", line 1639, in get_result
    results = self.func(self.start, self.stop, where)
  File "/opt/anaconda3/lib/python3.7/site-packages/pandas/io/pytables.py", line 766, in func
    return s.read(start=_start, stop=_stop, where=_where, columns=columns)
  File "/opt/anaconda3/lib/python3.7/site-packages/pandas/io/pytables.py", line 3206, in read
    "block{idx}_values".format(idx=i), start=_start, stop=_stop
  File "/opt/anaconda3/lib/python3.7/site-packages/pandas/io/pytables.py", line 2737, in read_array
    ret = node[0][start:stop]
  File "/opt/anaconda3/lib/python3.7/site-packages/tables/vlarray.py", line 681, in __getitem__
    return self.read(start, stop, step)[0]
  File "/opt/anaconda3/lib/python3.7/site-packages/tables/vlarray.py", line 825, in read
    outlistarr = [atom.fromarray(arr) for arr in listarr]
  File "/opt/anaconda3/lib/python3.7/site-packages/tables/vlarray.py", line 825, in <listcomp>
    outlistarr = [atom.fromarray(arr) for arr in listarr]
  File "/opt/anaconda3/lib/python3.7/site-packages/tables/atom.py", line 1227, in fromarray
    return six.moves.cPickle.loads(array.tostring())
ValueError: unsupported pickle protocol: 5
>>>
_

注:_pandas=1.0.0_で_pytables=3.6.1_(および_python=3.7.4_)を使用して読むことも試みました。これも失敗するので、Pythonバージョン(3.8ライターvs 3.7リーダー)が問題の原因であると考えています。これは、ピクルスプロトコル5が PEP- 574 for Python 3.8。

3
Pierre D

私は同じ問題に直面していました...私はそれを解決する方法を「知っています」、あなたもそうだと思います...解決策は、データ全体をピクル(またはcsv)に再処理し、それを再変換することですpython3.7からhdf5へ(プロトコル4のみを認識)。

フローは次のようなものです:python3.8-> hdf5-> python3.8-> csv/pickle-> python3.7-> hdf5(両方のバージョンと互換性があります)

エクスポートされるデータフレームのデータのチャンクがあり、多数のファイルが作成されるため、このルートを回避しました。

実際にpython3.7の使用に制限されていますか?私は今のところ(公式に)3.7までしかサポートしていないtensorflowによって制限されていましたが、tensorflow-nightly-buildをインストールでき、python 3.8で動作します

問題を確実に解決できる3.8への移行が可能かどうかを確認してください。 :)

0
André Carvalho