Что нового в Pandas 2.1

Наиболее интересные моменты в новом релизе

Выпуск pandas 2.1 состоялся 30 августа 2023 года. Давайте рассмотрим, что нового появилось в этом выпуске и как это поможет нам улучшить наши рабочие нагрузки на pandas. Он включает в себя множество улучшений.

pandas 2.1 в значительной степени опирается на интеграцию PyArrow, которая стала доступна в pandas 2.0. Большое внимание разработчики уделили поддержке новых функций, которые, как ожидается, станут стандартными в pandas 3.0. Давайте разберемся, что это значит для вас. Мы подробно рассмотрим наиболее важные улучшения.

Я являюсь членом команды разработчиков ядра pandas. Я являюсь инженером по открытым исходным кодам в компании Coiled, где работаю над Dask, в том числе над улучшением интеграции с pandas.

Отказ от использования объектного типа NumPy для строковых столбцов

Одной из основных проблем pandas является неэффективное представление строк. Над этой темой мы работали довольно долго. В pandas 1.3 появился первый строковый dtype с поддержкой PyArrow. Он способен сократить использование памяти примерно на 70% и повысить производительность. Более подробно я рассматривал эту тему в одном из своих предыдущих постов, где приводились сравнения памяти и измерения производительности (tldr: это впечатляет).

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

Включить эту опцию можно с помощью:

pd.options.future.infer_string = True

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

PyArrow имеет отличное от NumPy поведение объектных dtype, что может вызвать затруднения у неопытных разработчиков. Мы реализовали строковый dtype, используемый в данной опции, совместимый с семантикой NumPy. Он будет вести себя точно так же, как и объектные столбцы NumPy. Я призываю всех опробовать эту возможность!

Улучшена поддержка PyArrow

В pandas 2.0 представлен PyArrow с поддержкой DataFrame. Одной из основных целей, которую разработчики ставили перед собой в течение последних нескольких месяцев, было улучшение интеграции PyArrow в pandas. Разработчики стремились сделать переход с NumPy на DataFrame как можно более простым. Одной из областей, на которой сосредоточились, было устранение узких мест в производительности, поскольку раньше это приводило к неожиданным замедлениям.

Давайте рассмотрим пример:

import pandas as pd
import numpy as np

df = pd.DataFrame(
    {
        "foo": np.random.randint(1, 10, (1_000_000, )),
        "bar": np.random.randint(1, 100, (1_000_000,)),
    }, dtype="int64[pyarrow]"
)
grouped = df.groupby("foo")

Наш DataFrame содержит 1 миллион строк и 10 групп. Рассмотрим производительность на pandas 2.0.3 по сравнению с pandas 2.1:

# pandas 2.0.3
10.6 ms ± 72.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

# pandas 2.1.0
1.91 ms ± 3.16 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

Этот пример работает в 5 раз быстрее в новой версии. merge – еще одна часто используемая функция, которая теперь будет работать быстрее. Мы надеемся, что теперь работа с DataFrames, поддерживаемыми PyArrow, будет намного лучше.

Copy-on-Write

Copy-on-Write была первоначально представлена в pandas 1.5.0 и, как ожидается, станет поведением по умолчанию в pandas 3.0. Copy-on-Write уже хорошо работает на pandas 2.0.x. Мы в основном сосредоточились на исправлении известных ошибок и повышении скорости работы. Вот серию статей в блоге, объясняющих, что такое Copy-on-Write и как он работает. В этих статьях очень подробно рассказывается о том, как Copy-on-Write работает внутри системы и чего от него можно ожидать. В том числе производительность и поведение.

Copy-on-Write может повысить производительность реальных рабочих процессов более чем на 50%.

Отказ от апскейлинга в setiten-подобных операциях

Исторически сложилось так, что pandas автоматом изменял dtype одного из ваших столбцов, если вы задавали в нем несовместимое значение. Рассмотрим пример:

ser = pd.Series([1, 2, 3])

0    1
1    2
2    3
dtype: int64

У нас есть серия с целыми числами, в результате чего мы получим целочисленный dtype. Установим во второй ряд букву “a”:

ser.iloc[1] = "a"

0    1
1    a
2    3
dtype: object

Object – это единственный тип, который может хранить целые числа и строки. Для многих пользователей это большая проблема. Объектные столбцы занимают много памяти, вычисления , производительность падает.шумное изменение dtype в DataFrame в прошлом сильно раздражало меня. Теперь это поведение устарело и будет вызывать предупреждение FutureWarning:

FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future 
error of pandas. Value 'a' has dtype incompatible with int64, please explicitly cast to a 
compatible dtype first.
  ser.iloc[1] = "a"

Операции, подобные нашей, вызовут ошибку в pandas 3.0. Типы dtypes столбцов DataFrames будут оставаться неизменными при различных операциях. Вам придется явно указывать, когда вы хотите изменить свой dtype, что добавляет немного кода, но облегчает работу будущим разработчикам.

Это изменение затрагивает все d-типы, например, установка значения float в столбец integer также приведет к повышению значения.

Обновление до новой версии

Установить новую версию pandas можно с помощью:

pip install -U pandas

Или:

mamba install -c conda-forge pandas=2.1

В результате вы получите новый релиз в своей среде.

Заключение

Мы рассмотрели несколько улучшений, которые помогут вам писать более эффективный код. Сюда входит повышение производительности, упрощение входа в столбцы строк с поддержкой PyArrow и дальнейшие улучшения для Copy-on-Write. Мы также рассмотрели исправления, которые сделают поведение pandas более предсказуемым в следующем крупном выпуске.

Спасибо за прочтение. Не стесняйтесь обращаться к нам, чтобы поделиться своими мыслями и отзывами.

+1
1
+1
0
+1
0
+1
0
+1
0

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *