web-dev-qa-db-ja.com

Pandas PySparkで作成された寄木細工のファイルを読み取ることができません

私はSpark DataFrameから次の方法で寄木細工のファイルを書いています:

df.write.parquet("path/myfile.parquet", mode = "overwrite", compression="gzip")

これにより、複数のファイルを含むフォルダーが作成されます。

これをパンダに読み込もうとすると、使用するパーサーに応じて次のエラーが発生します。

import pandas as pd
df = pd.read_parquet("path/myfile.parquet", engine="pyarrow")

PyArrow:

Pyarrow.lib.check_statusのファイル "pyarrow\error.pxi"、83行目

ArrowIOError:無効な寄木細工ファイル。破損したフッター。

fastparquet:

ファイル「C:\ Program Files\Anaconda3\lib\site-packages\fastparquet\util.py」、38行目、default_openでreturn open(f、mode)

PermissionError:[Errno 13]権限が拒否されました: 'path/myfile.parquet'

次のバージョンを使用しています。

  • Spark 2.4.0
  • パンダ0.23.4
  • pyarrow 0.10.0
  • fastparquet 0.2.1

Gzipとsnappy圧縮を試しました。どちらも機能しません。もちろん、Pythonに読み取り/書き込みの権限がある場所にファイルがあることを確認しました。

誰かがこのエラーを再現できれば、すでに役に立ちます。

3
Thomas

これはまだ新しいpandas=バージョンでも問題になるようですので、大きなpysparkヘルパーライブラリの一部としてこれを回避するためにいくつかの関数を書きました:

_import pandas as pd
import datetime

def read_parquet_folder_as_pandas(path, verbosity=1):
  files = [f for f in os.listdir(path) if f.endswith("parquet")]

  if verbosity > 0:
    print("{} parquet files found. Beginning reading...".format(len(files)), end="")
    start = datetime.datetime.now()

  df_list = [pd.read_parquet(os.path.join(path, f)) for f in files]
  df = pd.concat(df_list, ignore_index=True)

  if verbosity > 0:
    end = datetime.datetime.now()
    print(" Finished. Took {}".format(end-start))
  return df


def read_parquet_as_pandas(path, verbosity=1):
  """Workaround for pandas not being able to read folder-style parquet files.
  """
  if os.path.isdir(path):
    if verbosity>1: print("Parquet file is actually folder.")
    return read_parquet_folder_as_pandas(path, verbosity)
  else:
    return pd.read_parquet(path)
_

これは、実際にはフォルダーである、寄木細工の「ファイル」内の関連ファイルが「.parquet」で終わることを前提としています。これは、databricksによってエクスポートされた寄木細工のファイルで機能し、他のユーザーでも機能する可能性があります(期待外れ、コメントへのフィードバックに満足しています)。

関数read_parquet_as_pandas()は、フォルダかどうかが事前にわからない場合に使用できます。

1
Thomas

問題は、Sparkは、その分散性のためにファイルをパーティション分割することです(各エグゼキュータは、ファイル名を受け取るディレクトリ内にファイルを書き込みます)。これは、ファイルを期待するPandasによってサポートされているものではありません。パスではありません。

この問題はさまざまな方法で回避できます。

3
martinarroyo