PyArrow 功能# pandas 可以利用PyArrow来扩展功能并提高各种 API 的性能。这包括: 与 NumPy 相比更广泛的数据类型 所有数据类型的缺失数据支持 (NA) 高性能 IO 读卡器集成 促进与基于 Apache Arrow 规范的其他数据帧库(例如,polars、cuDF)的互操作性 要使用此功能,请确保您已安装受支持的最低 PyArrow 版本。 数据结构集成# A Series、Index或 a 的列DataFrame可以直接由 a 支持pyarrow.ChunkedArray ,类似于 NumPy 数组。要从主要的 pandas 数据结构构造这些,您可以传入一个类型的字符串,后跟 [pyarrow], 例如"int64[pyarrow]""到dtype参数中 In [1]: ser = pd.Series([-1.5, 0.2, None], dtype="float32[pyarrow]") In [2]: ser Out[2]: 0 -1.5 1 0.2 2 <NA> dtype: float[pyarrow] In [3]: idx = pd.Index([True, None], dtype="bool[pyarrow]") In [4]: idx Out[4]: Index([True, <NA>], dtype='bool[pyarrow]') In [5]: df = pd.DataFrame([[1, 2], [3, 4]], dtype="uint64[pyarrow]") In [6]: df Out[6]: 0 1 0 1 2 1 3 4 笔记 字符串别名"string[pyarrow]"映射到pd.StringDtype("pyarrow")which 并不等同于指定dtype=pd.ArrowDtype(pa.string())。一般来说,对数据的操作的行为类似,除了pd.StringDtype("pyarrow")可以返回 NumPy 支持的可为空类型,而pd.ArrowDtype(pa.string()) 将返回ArrowDtype。 In [7]: import pyarrow as pa In [8]: data = list("abc") In [9]: ser_sd = pd.Series(data, dtype="string[pyarrow]") In [10]: ser_ad = pd.Series(data, dtype=pd.ArrowDtype(pa.string())) In [11]: ser_ad.dtype == ser_sd.dtype Out[11]: False In [12]: ser_sd.str.contains("a") Out[12]: 0 True 1 False 2 False dtype: boolean In [13]: ser_ad.str.contains("a") Out[13]: 0 True 1 False 2 False dtype: bool[pyarrow] 对于接受参数的 PyArrow 类型,您可以传入带有这些参数的 PyArrow 类型以在参数ArrowDtype中使用dtype。 In [14]: import pyarrow as pa In [15]: list_str_type = pa.list_(pa.string()) In [16]: ser = pd.Series([["hello"], ["there"]], dtype=pd.ArrowDtype(list_str_type)) In [17]: ser Out[17]: 0 ['hello'] 1 ['there'] dtype: list<item: string>[pyarrow] In [18]: from datetime import time In [19]: idx = pd.Index([time(12, 30), None], dtype=pd.ArrowDtype(pa.time64("us"))) In [20]: idx Out[20]: Index([12:30:00, <NA>], dtype='time64[us][pyarrow]') In [21]: from decimal import Decimal In [22]: decimal_type = pd.ArrowDtype(pa.decimal128(3, scale=2)) In [23]: data = [[Decimal("3.19"), None], [None, Decimal("-1.23")]] In [24]: df = pd.DataFrame(data, dtype=decimal_type) In [25]: df Out[25]: 0 1 0 3.19 <NA> 1 <NA> -1.23 如果您已经有pyarrow.Arrayor pyarrow.ChunkedArray,则可以将其传递arrays.ArrowExtensionArray到构造关联的Series, Index orDataFrame对象。 In [26]: pa_array = pa.array( ....: [{"1": "2"}, {"10": "20"}, None], ....: type=pa.map_(pa.string(), pa.string()), ....: ) ....: In [27]: ser = pd.Series(pd.arrays.ArrowExtensionArray(pa_array)) In [28]: ser Out[28]: 0 [('1', '2')] 1 [('10', '20')] 2 <NA> dtype: map<string, string>[pyarrow] pyarrow.ChunkedArray要从Series或检索 pyarrow ,您可以在或 上Index调用 pyarrow 数组构造函数。SeriesIndex In [29]: ser = pd.Series([1, 2, None], dtype="uint8[pyarrow]") In [30]: pa.array(ser) Out[30]: <pyarrow.lib.UInt8Array object at 0x7ff2a2968400> [ 1, 2, null ] In [31]: idx = pd.Index(ser) In [32]: pa.array(idx) Out[32]: <pyarrow.lib.UInt8Array object at 0x7ff2a2968460> [ 1, 2, null ] 要将 a 转换pyarrow.Table为 a DataFrame,您可以使用 调用该 pyarrow.Table.to_pandas()方法types_mapper=pd.ArrowDtype。 In [33]: table = pa.table([pa.array([1, 2, 3], type=pa.int64())], names=["a"]) In [34]: df = table.to_pandas(types_mapper=pd.ArrowDtype) In [35]: df Out[35]: a 0 1 1 2 2 3 In [36]: df.dtypes Out[36]: a int64[pyarrow] dtype: object 运营# PyArrow数据结构集成是通过pandas的接口实现的;因此,如果该接口集成在 pandas API 中,则存在受支持的功能。此外,此功能还可以通过可用的 PyArrow计算函数来加速。这包括:ExtensionArray 数字聚合 数值算术 数字四舍五入 逻辑和比较函数 字符串功能 日期时间功能 以下只是本机 PyArrow 计算函数加速的一些操作示例。 In [37]: import pyarrow as pa In [38]: ser = pd.Series([-1.545, 0.211, None], dtype="float32[pyarrow]") In [39]: ser.mean() Out[39]: -0.6669999808073044 In [40]: ser + ser Out[40]: 0 -3.09 1 0.422 2 <NA> dtype: float[pyarrow] In [41]: ser > (ser + 1) Out[41]: 0 False 1 False 2 <NA> dtype: bool[pyarrow] In [42]: ser.dropna() Out[42]: 0 -1.545 1 0.211 dtype: float[pyarrow] In [43]: ser.isna() Out[43]: 0 False 1 False 2 True dtype: bool In [44]: ser.fillna(0) Out[44]: 0 -1.545 1 0.211 2 0.0 dtype: float[pyarrow] In [45]: ser_str = pd.Series(["a", "b", None], dtype=pd.ArrowDtype(pa.string())) In [46]: ser_str.str.startswith("a") Out[46]: 0 True 1 False 2 <NA> dtype: bool[pyarrow] In [47]: from datetime import datetime In [48]: pa_type = pd.ArrowDtype(pa.timestamp("ns")) In [49]: ser_dt = pd.Series([datetime(2022, 1, 1), None], dtype=pa_type) In [50]: ser_dt.dt.strftime("%Y-%m") Out[50]: 0 2022-01 1 <NA> dtype: string[pyarrow] 输入/输出读取# PyArrow 还提供 IO 读取功能,该功能已集成到多个 pandas IO 读取器中。以下函数提供了一个engine关键字,可以分派到 PyArrow 以加速从 IO 源的读取。 read_csv() read_json() read_orc() read_feather() In [51]: import io In [52]: data = io.StringIO("""a,b,c ....: 1,2.5,True ....: 3,4.5,False ....: """) ....: In [53]: df = pd.read_csv(data, engine="pyarrow") In [54]: df Out[54]: a b c 0 1 2.5 True 1 3 4.5 False 默认情况下,这些函数和所有其他 IO 读取器函数返回 NumPy 支持的数据。这些阅读器可以通过指定参数返回 PyArrow 支持的数据dtype_backend="pyarrow"。读者不需要设置 engine="pyarrow"为一定返回 PyArrow 支持的数据。 In [55]: import io In [56]: data = io.StringIO("""a,b,c,d,e,f,g,h,i ....: 1,2.5,True,a,,,,, ....: 3,4.5,False,b,6,7.5,True,a, ....: """) ....: In [57]: df_pyarrow = pd.read_csv(data, dtype_backend="pyarrow") In [58]: df_pyarrow.dtypes Out[58]: a int64[pyarrow] b double[pyarrow] c bool[pyarrow] d string[pyarrow] e int64[pyarrow] f double[pyarrow] g bool[pyarrow] h string[pyarrow] i null[pyarrow] dtype: object 一些非 IO 读取器函数也可以使用dtype_backend参数返回 PyArrow 支持的数据,包括: to_numeric() DataFrame.convert_dtypes() Series.convert_dtypes()