このチュートリアルは、PyMongoArrow の操作の紹介を目的としています。チュートリアルでは、読者が PyMongoとMongoDB の基本的な概念を理解していることを前提としています。
Install PyMongoArrow
PyMongoArrowは、次の 3 つの方法でインストールできます。
Pip
Conda
元のソース
Pip を使用したインストール
すべてのプラットフォームに pip を使用して PyMongoArrow をインストールすることを推奨します。PyMongoArrow は PyPI で利用できます。
python -m pip install pymongoarrow
PyMongoの特定のバージョンを取得するには、次の手順に従います。
python -m pip install pymongoarrow==1.5.1
pip を使用してアップグレードするには、以下を行います。
python -m pip install --upgrade pymongoarrow
重要
ValueError: Could
not find "libbson-1.0" libraryなどのエラーが原因でインストールが失敗した場合、 pipはプラットフォームに適したディスクを見つけられませんでした。 最初にpip >= 20.3 がインストールされていることを確認することをお勧めします。 pipをアップグレードするには、次の shell コマンドを実行します。
$ python -m pip install --upgrade pip
その後にpymongoarrowを再インストールしてみてください。
現在、x86_64 アーキテクチャ上の macOS、Windows、および Linux 用のキーを配布しています。
To test your installation, run the following code in the Python shell. If PyMongoArrow is correctly installed, you won't see any errors or exceptions.
import pymongoarrow as pma
Conda を使用したインストール
PyMongoArrow は、次の shell コマンドを実行することで、 condaユーザーが利用できます。
$ conda install --channel conda-forge pymongoarrow
To test your installation, run the following code in the Python shell. If PyMongoArrow is correctly installed, you won't see any errors or exceptions.
import pymongoarrow as pma
ソースからインストール
上記のオプションを使用してシステムに pymongoarrow をインストールできない場合は、ソースからインストールできます。その方法については、貢献ガイドを参照してください。
Dependencies
Linuxにソースからインストールするには、次の依存関係が必要です。
GCC バージョン12以降
CMax
pkg-config
オプションの依存関係を必要とする PyMongo 機能で PyMongoArrow を使用するには、PyMongo をインストールするときにオプションとして依存関係を設定する必要があります。
注意
PyMongo のオプションの依存関係の詳細については、 PyMongoドキュメントの「 依存関係 」を参照してください。
たとえば、クライアント側のフィールドレベル暗号化で PyMongoArrow を使用するには、PyMongoArrow のインストールに加えて、 encryptionオプションを使用して PyMongo をインストールする必要があります。
python -m pip install 'pymongo[encryption]' pymongoarrow
PyMongoArrow API を使用してクエリ結果セットをpandas.DataFrameインスタンスとして返すアプリケーション~pymongoarrow.api.find_pandas_all()など)には、 pandasもインストールされている必要があります。
python -m pip install pandas
To test your installation, run the following code in the Python shell. If PyMongoArrow is correctly installed, you won't see any errors or exceptions.
import pymongoarrow as pma
MongoDB のインストール
This tutorial assumes that a MongoDB instance is running on the default host and port. After you have downloaded and installed MongoDB, you can start it as shown in the following code example:
$ mongod
サンプル データの挿入
Run the following code to insert sample data into your cluster:
from datetime import datetime from pymongo import MongoClient client = MongoClient() client.db.data.insert_many([ {'_id': 1, 'amount': 21, 'last_updated': datetime(2020, 12, 10, 1, 3, 1), 'account': {'name': 'Customer1', 'account_number': 1}, 'txns': ['A']}, {'_id': 2, 'amount': 16, 'last_updated': datetime(2020, 7, 23, 6, 7, 11), 'account': {'name': 'Customer2', 'account_number': 2}, 'txns': ['A', 'B']}, {'_id': 3, 'amount': 3, 'last_updated': datetime(2021, 3, 10, 18, 43, 9), 'account': {'name': 'Customer3', 'account_number': 3}, 'txns': ['A', 'B', 'C']}, {'_id': 4, 'amount': 0, 'last_updated': datetime(2021, 2, 25, 3, 50, 31), 'account': {'name': 'Customer4', 'account_number': 4}, 'txns': ['A', 'B', 'C', 'D']}])
スキーマを定義する
PyMongoArrow は、クエリ結果セットを表形式にマーシャリングするためにデータ スキーマに依存します。 このスキーマを指定しない場合、PyMongoArrow は のデータから 1 つのスキーマを推論します。 次の例に示すように、 Schemaオブジェクトを作成し、フィールド名を type 指定子にマッピングすることで、スキーマを定義できます。
from pymongoarrow.api import Schema schema = Schema({'_id': int, 'amount': float, 'last_updated': datetime})
MongoDB は、ネストされたデータを表すために埋め込みドキュメントを使用します。 PyMongoArrow は、次のドキュメントに対するファーストクラスのサポートを提供します。
schema = Schema({'_id': int, 'amount': float, 'account': { 'name': str, 'account_number': int}})
PyMongoArrow は、リストとネストされたリストもサポートしています。
from pyarrow import list_, string schema = Schema({'txns': list_(string())}) polars_df = client.db.data.find_polars_all({'amount': {'$gt': 0}}, schema=schema)
Tip
PyMongoArrow includes multiple permissible type-identifiers for each supported BSON type. For a full list of these data types and their associated type-identifiers, see Data Types.
検索操作
次のコード例は、 amountフィールドの値がゼロ以外のすべてのレコードをpandas.DataFrameオブジェクトとしてロードする方法を示しています。
df = client.db.data.find_pandas_all({'amount': {'$gt': 0}}, schema=schema)
また、 pyarrow.Tableインスタンスと同じ結果セットを読み込むこともできます。
arrow_table = client.db.data.find_arrow_all({'amount': {'$gt': 0}}, schema=schema)
または、 polars.DataFrameインスタンスの場合には、次のようにします。
df = client.db.data.find_polars_all({'amount': {'$gt': 0}}, schema=schema)
または NumPy arraysオブジェクトとして次のようにします。
ndarrays = client.db.data.find_numpy_all({'amount': {'$gt': 0}}, schema=schema)
NumPy を使用する場合、返される値は、キーがフィールド名で値が対応するnumpy.ndarrayインスタンスである辞書です。
注意
前述のすべての例では、次の例に示すように スキーマを省略できます。
arrow_table = client.db.data.find_arrow_all({'amount': {'$gt': 0}})
スキーマを省略すると、PyMongoArrow は最初のバッチに含まれるデータに基づいてスキーマを自動的に適用しようとします。
集計操作
集計操作の実行は検索操作の実行と似ていますが、実行するには一連の操作が必要です。
以下は、すべての_id値がグループ化され、それらのamount値が合計された新しいデータフレームを出力するaggregate_pandas_all()メソッドの簡単な例です。
df = client.db.data.aggregate_pandas_all([{'$group': {'_id': None, 'total_amount': { '$sum': '$amount' }}}])
埋め込みドキュメントに対して集計操作を実行することもできます。 次の例では、ネストされたtxnフィールドの値を展開し、各値の数をカウントし、降順でソートされた NumPy ndarrayオブジェクトのリストとして結果を返します。
pipeline = [{'$unwind': '$txns'}, {'$group': {'_id': '$txns', 'count': {'$sum': 1}}}, {'$sort': {"count": -1}}] ndarrays = client.db.data.aggregate_numpy_all(pipeline)
Tip
集計パイプラインの詳細については、 MongoDB Server のドキュメント を参照してください。
MongoDB への書き込み
write()メソッドを使用して、次のタイプのオブジェクトを MongoDB に書込み (write) できます。
Arrow
TablePandas
DataFrameNumPy
ndarray北極と南極
DataFrame
from pymongoarrow.api import write from pymongo import MongoClient coll = MongoClient().db.my_collection write(coll, df) write(coll, arrow_table) write(coll, ndarrays)
注意
NumPy 配列はdict[str, ndarray]として指定されます。
Ignore Empty Values
write() メソッドはオプションでブール値の exclude_none パラメータを受け入れます。このパラメータを True に設定すると、ドライバーはデータベースに空の値を書込みません。このパラメータを False に設定するか空白のままにすると、ドライバーは空のフィールドごとに None を書き込みます。
次の例のコードでは、Arrow Table をMongoDBに 2 回書込みます。'b'フィールドの値の 1 つが None に設定されています。
write() メソッドの最初の呼び出しでは exclude_none パラメータが省略されているため、デフォルトは False になります。None を含む Table 内のすべての値は、データベースに書き込まれます。write() メソッドへの 2 回目の呼び出しでは、exclude_none が True に設定されるため、'b'フィールドの空の値は無視されます。
data_a = [1, 2, 3] data_b = [1, None, 3] data = Table.from_pydict( { "a": data_a, "b": data_b, }, ) coll.drop() write(coll, data) col_data = list(coll.find({})) coll.drop() write(coll, data, exclude_none=True) col_data_exclude_none = list(coll.find({})) print(col_data) print(col_data_exclude_none)
{'_id': ObjectId('...'), 'a': 1, 'b': 1} {'_id': ObjectId('...'), 'a': 2, 'b': None} {'_id': ObjectId('...'), 'a': 3, 'b': 3} {'_id': ObjectId('...'), 'a': 1, 'b': 1} {'_id': ObjectId('...'), 'a': 2} {'_id': ObjectId('...'), 'a': 3, 'b': 3}
他の形式への書き込み
結果セットを読み込んだ後、パッケージがサポートする任意の形式に結果セットを書込むことができます。
たとえば、変数arrow_tableが参照するテーブルをexample.parquetという名前の Compass ファイルに書き込むには、次のコードを実行します。
import pyarrow.parquet as pq pq.write_table(arrow_table, 'example.parquet')
Pandoraは、CSV や FD などのさまざまな形式へのDataFrameインスタンスの書き込みもサポートしています。 変数dfが参照するデータフレームをout.csvという名前の CSV ファイルに書き込むには、次のコードを実行します。
df.to_csv('out.csv', index=False)
Tars API は、前述の 2 つの例が組み合わされています。
import polars as pl df = pl.DataFrame({"foo": [1, 2, 3, 4, 5]}) df.write_parquet('example.parquet')
注意
ネストされたデータは、parquet の読み取りおよび書込み操作でサポートされていますが、CSV の読み取りおよび書込み操作の Arrow または Pandora ではサポートされていません。
PyMongo の拡張
pymongoarrow.monkeyモジュールは、PyMongo をその場でパッチし、PyMongoArrow 機能をCollectionインスタンスに直接追加するためのインターフェースを提供します。
from pymongoarrow.monkey import patch_all patch_all()
monkey.patch_all()メソッドを実行すると、 Collectionクラスの新しいインスタンスに PyMongoArrow API など、 pymongoarrow.api.find_pandas_all()メソッドが含まれます。
注意
また、PyMongoArrow API は、 pymongoarrow.apiモジュールからインポートして使用することもできます。 その場合は、API メソッドを呼び出すときに、操作が実行されるCollectionのインスタンスを最初の引数として渡す必要があります。
トラブルシューティング
undefined symbolソースから PyMongoArrow をインストールするときに エラーが発生するのはなぜですか?
Linux 環境に GCC バージョン12以降がインストールされていない場合、PyMongoArrow ではこのエラーが発生します。 このエラーが発生した場合は、GCC バージョン12以降がインストールされていることを確認してください。
Why Do I Get ModuleNotFoundError: No module named 'polars' When Using PyMongoArrow?
PyMongoArrow では、Python 環境にpolarsがインストールされていない状態で、クエリ結果セットをpolars.DataFrameインスタンスとして返す PyMongoArrow API をアプリケーションが使用しようとすると、このエラーが発生します。 polarsは PyMongoArrow の直接依存関係ではないため、 pymongoarrowをインストールしても自動的にインストールされることはありません。 次の shell コマンドを使用して、 polarsを個別にインストールする必要があります。
python -m pip install polars