Spec-Zone.ru › pandas 2

Функциональность PyArrow

pandas может использовать PyArrow, чтобы расширить функциональность и улучшить производительность различных API. Это включает:

  • Более широкий набор типов данных по сравнению с NumPy

  • Поддержка пропущенных данных (NA) для всех типов данных

  • Интеграция высокопроизводительных читателей IO

  • Упрощение взаимодействия с другими библиотеками фреймворков данных, основанных на спецификации Apache Arrow (например, polars, cuDF)

Для использования этой функциональности, пожалуйста, убедитесь, что вы установили минимально поддерживаемую версию PyArrow.

Интеграция структур данных

Series, Index или столбцы DataFrame могут напрямую опираться на 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"), который не эквивалентен указанию 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.Array или pyarrow.ChunkedArray, вы можете передать его в arrays.ArrowExtensionArray, чтобы создать связанный Series, Index или DataFrame объект.

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 pyarrow.ChunkedArray из Series или Index вы можете вызвать конструктор массива pyarrow для Series или Index.

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
]

Для преобразования pyarrow.Table в 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 реализована через интерфейс ExtensionArray pandas; поэтому поддерживаемая функциональность существует там, где этот интерфейс интегрирован в API pandas. Кроме того, эта функциональность ускорена с помощью функций вычисления PyArrow в случае их доступности. Это включает:

  • Числовые агрегации

  • Числовые арифметические операции

  • Округление числовых значений

  • Логические и сравнительные функции

  • Функциональность строк

  • Функциональность дат и времени

Ниже приведены лишь некоторые примеры операций, ускоренных нативными функциями вычисления 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]

Чтение I/O

PyArrow также предоставляет функциональность чтения I/O, интегрированную в несколько читателей I/O pandas. Следующие функции предоставляют ключевое слово engine, которое может быть перенаправлено на PyArrow для ускорения чтения из источника I/O.

  • 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

По умолчанию эти функции и все другие функции читателей I/O возвращают данные, основанные на 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

Несколько функций, не относящихся к чтению I/O, также могут использовать аргумент dtype_backend для возврата данных, основанных на PyArrow, включая:

  • to_numeric()

  • DataFrame.convert_dtypes()

  • Series.convert_dtypes()

© 2008–2022, AQR Capital Management, LLC, Lambda Foundry, Inc. and PyData Development Team
Licensed under the 3-clause BSD License.
https://pandas.pydata.org/pandas-docs/version/2.2.2/user_guide/pyarrow.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API