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

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

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

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

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

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

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

pd.options.future.infer_string = True

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

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

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

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

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

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 групп. Давайте посмотрим на производительность панд 2.0.3 по сравнению с пандами 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 стал намного лучше.

Копирование при записи

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

Мы увидели, что копирование при записи может повысить производительность реальных рабочих процессов более чем на 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. Типы столбцов DataFrames будут оставаться одинаковыми для разных операций. Вам придется явно указать, когда вы хотите изменить свой dtype, что добавляет немного кода, но упрощает работу для будущих разработчиков.

Это изменение влияет на все типы данных, например. установка значения с плавающей запятой в целочисленный столбец также приведет к увеличению.

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

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

pip install -U pandas

Or:

mamba install -c conda-forge pandas=2.1

Это даст вам новый выпуск в вашей среде.

Заключение

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

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