私は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'
次のバージョンを使用しています。
Gzipとsnappy圧縮を試しました。どちらも機能しません。もちろん、Pythonに読み取り/書き込みの権限がある場所にファイルがあることを確認しました。
誰かがこのエラーを再現できれば、すでに役に立ちます。
これはまだ新しい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()
は、フォルダかどうかが事前にわからない場合に使用できます。
問題は、Sparkは、その分散性のためにファイルをパーティション分割することです(各エグゼキュータは、ファイル名を受け取るディレクトリ内にファイルを書き込みます)。これは、ファイルを期待するPandasによってサポートされているものではありません。パスではありません。
この問題はさまざまな方法で回避できます。
pyarrow.parquet.ParquetDataset
などの代替ユーティリティを使用してファイルを読み取り、それをPandasに変換します(このコードはテストしていません)。
arrow_df = pyarrow.parquet.ParquetDataset('path/myfile.parquet')
pandas_df = arrow_df.to_pandas()
別の方法は、この回答が示唆するように、別々のフラグメントを個別に読み取ってからそれらを連結することです: フォルダー内の複数の寄木細工ファイルを読み取り、Pythonを使用して単一のcsvファイルに書き込みます