pyarrow で Parquet メタデータを書き込むにはどうすればいいですか? 質問する

pyarrow で Parquet メタデータを書き込むにはどうすればいいですか? 質問する

私は pyarrow を使用して生物学的情報を含む Parquet テーブルを作成および分析しており、データの取得元となるサンプルや、データの取得方法および処理方法などのメタデータを保存する必要があります。

Parquetはサポートしているようですファイル全体のメタデータですが、pyarrowで書き込む方法が見つかりません。私が見つけた最も近いものは行グループメタデータの書き方しかし、ファイル内のすべての行グループのメタデータは同じであるため、これはやり過ぎのようです。

pyarrow を使用してファイル全体の Parquet メタデータを書き込む方法はありますか?

ベストアンサー1

Pyarrowはファイル全体のメタデータをテーブルのスキーマ内のフィールド名前付きメタデータ。残念ながら、これに関するドキュメントはまだありません。

Parquet メタデータ形式と Pyarrow メタデータ形式はどちらも、メタデータをキーと値のペアのコレクションとして表します。キーと値は両方とも文字列である必要があります。これは残念なことです。UTF-8 でエンコードされた JSON オブジェクトであれば、より柔軟になるからです。さらに、これらはstd::stringC++ 実装のオブジェクトであるため、Python では「b 文字列」(バイト) オブジェクトです。

Pyarrow は現在、メタデータ フィールドに独自の情報の一部を格納しています。組み込みキーが 1 つとb'ARROW:schema'、別の組み込みキーがありますb'pandas'。pandas の場合、値は UTF-8 でエンコードされた JSON オブジェクトです。これにより、名前空間が可能になります。「pandas」スキーマには必要な数のフィールドを含めることができ、それらはすべて「pandas」の下に名前空間化されます。Pyarrow は「pandas」スキーマを使用して、テーブルにあるインデックスの種類と、列が使用するエンコードの種類 (特定のデータ型に対して複数の pandas エンコードが可能な場合) に関する情報を格納します。 が何をb'ARROW:schema'表しているかはわかりません。認識できない方法でエンコードされているようで、実際に触ったことはありません。「pandas」スキーマに似たものを記録することを意図しているものだと思います。

質問に答えるために最後に知っておく必要があるのは、すべての pyarrow オブジェクトは不変であるということです。したがって、スキーマにフィールドを追加するだけでは不十分です。Pyarrow には、スキーマwith_metadataオブジェクトのクローンを返す schema ユーティリティ メソッドがありますが、これは独自のメタデータを持ちますが、既存のメタデータを置き換え、追加しません。Table オブジェクトには実験的なメソッドもありますreplace_schema_metadataが、これも置き換え、更新しません。したがって、既存のメタデータを保持したい場合は、さらに作業を行う必要があります。これらすべてをまとめると、次のようになります...

custom_metadata = {'Sample Number': '12', 'Date Obtained': 'Tuesday'}
existing_metadata = table.schema.metadata
merged_metadata = { **custom_metadata, **existing_metadata }
fixed_table = table.replace_schema_metadata(merged_metadata)

Sample Numberこのテーブルが parquet ファイルとして保存されると、およびのキー/値メタデータ フィールド (ファイル レベル) が含まれるようになりますDate Obtained

また、replace_schema_metadataおよびwith_metadataメソッドは、通常の Python 文字列 (私の例のように) を受け入れることに注意してください。ただし、これらは「b 文字列」に変換されるため、スキーマ内のフィールドにアクセスする場合は、「b 文字列」を使用する必要があります。たとえば、テーブルを読み込んでサンプル番号を取得したい場合は、 および を使用する必要がtable.schema.metadata[b'Sample Number']ありtable.schema.metadats['Sample Number']ますKeyError

これを使い始めると、常に整数にマッピングし直さなければならないのは面倒だと気づくかもしれませんSample Number。さらに、メタデータがアプリケーション内で大きなネストされたオブジェクトとして表される場合、このオブジェクトを文字列/文字列ペアのコレクションにマッピングするのは面倒です。また、常に「b 文字列」キーを覚えておくのも面倒です。解決策は、pandas スキーマと同じことを行うことです。まず、メタデータを JSON オブジェクトに変換します。次に、JSON オブジェクトを「b 文字列」に変換します。

custom_metadata_json = {'Sample Number': 12, 'Date Obtained': 'Tuesday'}
custom_metadata_bytes = json.dumps(custom_metadata_json).encode('utf8')
existing_metadata = table.schema.metadata
merged_metadata = { **{'Record Metadata': custom_metadata_bytes}, **existing_metadata }

これで、任意の標準 JSON タイプを使用して、必要な数のメタデータ フィールドを任意の方法でネストすることができ、すべてが単一のキー/値ペア (この場合は「レコード メタデータ」という名前) に名前空間化されます。

おすすめ記事