数据类型
PyMongoArrow 支持大多数 BSON 类型。由于 Arrow 和 Polars 提供了列表和 Struct 的一级支持,这包括嵌入式数组和文档。
后续版本将添加对其他类型的支持。
提示
有关 BSON 类型的更多信息,请参阅BSON 规范.
BSON 类型 | 类型标识符 |
---|---|
字符串 | py.str ,pyarrow.string 的实例 |
嵌入式文档 | py.dict ,pyarrow.struct 的实例 |
嵌入式数组 | pyarrow.list_ 的实例 |
ObjectId | py.bytes ,bson.ObjectId ,pymongoarrow.types.ObjectIdType 的实例,pymongoarrow.pandas_types.PandasObjectId 的实例 |
十进制128 | bson.Decimal128 ,pymongoarrow.types.Decimal128Type 的一个实例,pymongoarrow.pandas_types.PandasDecimal128 的一个实例 |
布尔值 | ~pyarrow.bool_ 的一个实例,~py.bool |
64位二进制浮点数 | py.float ,pyarrow.float64 的一个实例 |
32位整数 | pyarrow.int32 的一个实例 |
64位整数 | ~py.int ,bson.int64.Int64 ,pyarrow.int64 的一个实例 |
UTC日期时间 | ~pyarrow.timestamp 的一个实例,具有ms 分辨率,py.datetime.datetime |
二进制数据 | bson.Binary ,pymongoarrow.types.BinaryType 的一个实例,pymongoarrow.pandas_types.PandasBinary 的一个实例。 |
JavaScript代码 | bson.Code ,pymongoarrow.types.CodeType 的一个实例,pymongoarrow.pandas_types.PandasCode 的一个实例 |
注意
PyMongoArrow仅在小端系统中支持Decimal128
。在大端系统中,它使用null
代替。
在pymongoarrow.api.Schema
声明期间使用类型标识符来指定字段的数据类型。例如,如果您的数据有类型为32位整数和UTC日期时间的字段f1
和f2
,以及一个类型为ObjectId
的_id
,您可以如下定义您的模式:
schema = Schema({ '_id': ObjectId, 'f1': pyarrow.int32(), 'f2': pyarrow.timestamp('ms') })
模式中不支持的数据类型会导致一个ValueError
,该错误标识字段及其数据类型。
嵌入式数组考虑事项
用于嵌入式数组的模式必须使用pyarrow.list_()
类型来指定数组元素的类型。例如,
from pyarrow import list_, float64 schema = Schema({'_id': ObjectId, 'location': {'coordinates': list_(float64())} })
扩展类型
PyMongoArrow实现了ObjectId、Decimal128、Binary数据以及JavaScript代码类型作为PyArrow和Pandas的扩展类型。对于箭头表,这些类型的值具有适当的pymongoarrow扩展类型,如pymongoarrow.types.ObjectIdType。您可以使用.as_py()方法或通过在表上调用.to_pylist()来获取适当的bson Python对象。
from pymongo import MongoClient from bson import ObjectId from pymongoarrow.api import find_arrow_all client = MongoClient() coll = client.test.test"_id": ObjectId(), "foo": 100}, {"_id": ObjectId(), "foo": 200}]) coll.insert_many([{<pymongo.results.InsertManyResult at 0x1080a72b0> table = find_arrow_all(coll, {}) tablepyarrow.Table _id: extension<arrow.py_extension_type<ObjectIdType>> foo: int32 ---- _id: [[64408B0D5AC9E208AF220142,64408B0D5AC9E208AF220143]] foo: [[100,200]] "_id"][0] table[<pyarrow.ObjectIdScalar: ObjectId('64408b0d5ac9e208af220142')> "_id"][0].as_py() table[ObjectId('64408b0d5ac9e208af220142') table.to_pylist()[{'_id': ObjectId('64408b0d5ac9e208af220142'), 'foo': 100}, {'_id': ObjectId('64408b0d5ac9e208af220143'), 'foo': 200}]
在转换为Pandas时,扩展类型列具有适当的pymongoarrow扩展类型,例如pymongoarrow.pandas_types.PandasDecimal128。DataFrame中元素的价值是适当的bson类型。
from pymongo import MongoClient from bson import Decimal128 from pymongoarrow.api import find_pandas_all client = MongoClient() coll = client.test.test"foo": Decimal128("0.1")}, {"foo": Decimal128("0.1")}]) coll.insert_many([{<pymongo.results.InsertManyResult at 0x1080a72b0> df = find_pandas_all(coll, {}) df _id foo 0 64408bf65ac9e208af220144 0.1 1 64408bf65ac9e208af220145 0.1 "foo"].dtype df[<pymongoarrow.pandas_types.PandasDecimal128 at 0x11fe0ae90> "foo"][0] df[Decimal128('0.1') "_id"][0] df[ObjectId('64408bf65ac9e208af220144')
Polars不支持扩展类型。
空值和转换为Pandas DataFrames
在Arrow和Polars中,所有数组都是可空的。Pandas有实验性的可空数据类型,如Int64。您可以使用以下Apache文档代码指令Arrow创建使用可空dtypes的pandas DataFrame: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
定义pa.string()的转换也会将Arrow字符串转换为NumPy字符串,而不是对象。
嵌套扩展类型
待处理 ARROW-179,例如ObjectId
,这些类型在嵌套文档中出现的扩展类型不会被转换为相应的 PyMongoArrow 扩展类型,而是保留原始 Arrow 类型,即FixedSizeBinaryType(fixed_size_binary[12])
。
这些值可以直接使用,也可以单独转换为所需的扩展类型,例如_id = out['nested'][0]['_id'].cast(ObjectIdType())
。