PyMongoArrow admite la mayoría de los BSON types. Como Arrow y Polars ofrecen soporte de primera clase para listas y estructuras, esto incluye arreglos y documentos incrustados.
Se añadirá soporte para tipos adicionales en versiones posteriores.
Tip
Para obtener más información sobre los tipos BSON, consulta la Especificación BSON.
Tipo BSON | Identificadores de tipo |
|---|---|
String |
|
embeddedDocument |
|
Arreglo incrustado |
|
ObjectId |
|
Decimal128 |
|
Booleano |
|
punto flotante binario de 64 bits |
|
entero de 32 bits |
|
entero de 64 bits |
|
Fecha y hora UTC |
|
Datos binarios |
|
Código JavaScript |
|
Nulo |
|
Nota
PyMongoArrow solo admite Decimal128 en sistemas con orden de bytes little-endian. En sistemas big-endian, se usa null en su lugar.
Utilice identificadores de tipo para especificar que un campo es de un determinado tipo durante la declaración pymongoarrow.api.Schema. Por ejemplo, si tus datos tienen los campos f1 y f2 con los tipos entero de 32 bits y fecha-hora UTC, y un _id que es un ObjectId, puedes definir tu esquema de la siguiente manera:
schema = Schema({ '_id': ObjectId, 'f1': pyarrow.int32(), 'f2': pyarrow.timestamp('ms') })
Los tipos de datos no compatibles en un esquema causan un ValueError que identifica el campo y su tipo de datos.
Consideraciones sobre arreglos integrados
El esquema utilizado para un arreglo anidado debe usar el tipo pyarrow.list_(), para especificar el tipo de los elementos del arreglo. Por ejemplo,
from pyarrow import list_, float64 schema = Schema({'_id': ObjectId, 'location': {'coordinates': list_(float64())} })
Tipos de extensiones
PyMongoArrow implementa los tipos ObjectId, Decimal128, Binary data y JavaScript code como tipos de extensión para PyArrow y Pandas. Para las tablas flecha, los valores de estos tipos tienen el tipo de extensión pymongoarrow apropiado, como pymongoarrow.types.ObjectIdType. Puedes obtener el objeto de Python bson apropiado utilizando el método .as_py(), o llamando a .to_pylist() en la tabla.
from pymongo import MongoClient from bson import ObjectId from pymongoarrow.api import find_arrow_all client = MongoClient() coll = client.test.test coll.insert_many([{"_id": ObjectId(), "foo": 100}, {"_id": ObjectId(), "foo": 200}]) <pymongo.results.InsertManyResult at 0x1080a72b0> table = find_arrow_all(coll, {}) table pyarrow.Table _id: extension<arrow.py_extension_type<ObjectIdType>> foo: int32 ---- _id: [[64408B0D5AC9E208AF220142,64408B0D5AC9E208AF220143]] foo: [[100,200]] table["_id"][0] <pyarrow.ObjectIdScalar: ObjectId('64408b0d5ac9e208af220142')> table["_id"][0].as_py() ObjectId('64408b0d5ac9e208af220142') table.to_pylist() [{'_id': ObjectId('64408b0d5ac9e208af220142'), 'foo': 100}, {'_id': ObjectId('64408b0d5ac9e208af220143'), 'foo': 200}]
Al convertir a pandas, las columnas de tipo de extensión tienen un tipo de extensión pymongoarrow apropiado, como pymongoarrow.pandas_types.PandasDecimal128. El valor del elemento en el dataframe es del tipo adecuado bson.
from pymongo import MongoClient from bson import Decimal128 from pymongoarrow.api import find_pandas_all client = MongoClient() coll = client.test.test coll.insert_many([{"foo": Decimal128("0.1")}, {"foo": Decimal128("0.1")}]) <pymongo.results.InsertManyResult at 0x1080a72b0> df = find_pandas_all(coll, {}) df _id foo 0 64408bf65ac9e208af220144 0.1 1 64408bf65ac9e208af220145 0.1 df["foo"].dtype <pymongoarrow.pandas_types.PandasDecimal128 at 0x11fe0ae90> df["foo"][0] Decimal128('0.1') df["_id"][0] ObjectId('64408bf65ac9e208af220144')
Polars no admite tipos de extensión.
Valores nulos y conversión a DataFrames de Pandas
En Arrow y Polars, todos los arreglos son nulos. Pandas tiene tipos de datos admiten valores nulos experimentales, como Int64. Puede instruir a Arrow para que cree un DataFrame de pandas utilizando tipos de datos anulables con el siguiente Código de documentación de Apache.
>>> dtype_mapping = { ... pa.int8(): pd.Int8Dtype(), ... pa.int16(): pd.Int16Dtype(), ... pa.int32(): pd.Int32Dtype(), ... pa.int64(): pd.Int64Dtype(), ... pa.uint8(): pd.UInt8Dtype(), ... pa.uint16(): pd.UInt16Dtype(), ... pa.uint32(): pd.UInt32Dtype(), ... pa.uint64(): pd.UInt64Dtype(), ... pa.bool_(): pd.BooleanDtype(), ... pa.float32(): pd.Float32Dtype(), ... pa.float64(): pd.Float64Dtype(), ... pa.string(): pd.StringDtype(), ... } ... df = arrow_table.to_pandas( ... types_mapper=dtype_mapping.get, split_blocks=True, self_destruct=True ... ) ... del arrow_table
Definir una conversión para pa.string() también convierte las cadenas de Arrow a cadenas de NumPy, y no a objetos.
Extensiones de tipos anidados
Pendiente ARROW-179, los tipos de extensión, como ObjectId, que aparecen en documentos anidados no se convierten al tipo de extensión correspondiente de PyMongoArrow, sino que tienen el tipo Arrow bruto, FixedSizeBinaryType(fixed_size_binary[12]).
Estos valores pueden ser consumidos tal cual, o convertidos individualmente al tipo de extensión deseado, como _id = out['nested'][0]['_id'].cast(ObjectIdType()).
Adherencia estricta al tipo
Cuando proporciones un esquema para los datos en PyMongoArrow v1.9 y versiones posteriores, el controlador aplica una adhesión estricta al tipo. Si el valor de un campo tiene una incompatibilidad de tipo con el tipo del esquema para ese campo, el controlador plantea una TypeError. NaN es un tipo válido para todos los campos.
Para suprimir TypeErrors y convertir silenciosamente las incompatibilidades de tipo en NaN, pase el argumento allow_invalid=True a su llamada a la API pymongoarrow. El siguiente ejemplo pasa allow_invalid=True a la llamada API pymongoarrow para convertir las incompatibilidades en los datos de muestra en NaN:
from pymongoarrow.monkey import patch_all from pymongoarrow.api import Schema, find_arrow_all from pyarrow import int32, string from pymongo import MongoClient patch_all() client = MongoClient() coll = client.test.test sample_data = [ {"name": "Alice", "age": 35, "city": "Chicago"}, {"name": {"first": "Bob", "last": "Smith"}, "age": 28, "city": "Boston"}, {"name": "Charlie", "age": "thirty-two", "city": "Seattle"} ] coll.insert_many(sample_data) schema = Schema({ "name": string(), "age": int32(), "city": string() }) result = find_arrow_all(collection, {}, schema=schema, allow_invalid=True)