Что нового в Pandas 2.2
Pandas 2.2 был выпущен 22 января 2024 года. Давайте рассмотрим, что нового появилось в этом выпуске и как он поможет нам улучшить работу с pandas. Выпуск включает в себя множество улучшений, которые облегчат разаработку.
В pandas 2.2 появилось несколько улучшений, которые опираются на экосистему Apache Arrow. Давайте разберемся, что это значит для вас. Мы подробно рассмотрим наиболее важные изменения.
поддержка PyArrow
Команда разработки представили PyArrow с поддержкой DataFrame в pandas 2.0 и с тех пор продолжали улучшать интеграцию, чтобы обеспечить бесшовную интеграцию в pandas API. pandas имеет аксессоры для определенных типов данных, которые позволяют выполнять специализированные операции, например, аксессор string, который предоставляет множество методов для работы со строками. Исторически списки и структуры представлялись как объектные dtype NumPy, что делало работу с ними довольно громоздкой. Теперь бэкенд Arrow dtype позволяет создавать специализированные аксессоры для списков и структур, что значительно упрощает работу с этими объектами.
Давайте рассмотрим пример:
import pyarrow as pa
series = pd.Series(
[
{"project": "pandas", "version": "2.2.0"},
{"project": "numpy", "version": "1.25.2"},
{"project": "pyarrow", "version": "13.0.0"},
],
dtype=pd.ArrowDtype(
pa.struct([
("project", pa.string()),
("version", pa.string()),
])
),
)
Это серия, которая содержит словарь в каждом ряду. Ранее это было возможно только с объектным dtype NumPy, и доступ к элементам из этих рядов требовал итерации по ним. Теперь аксессор struct позволяет получить прямой доступ к определенным атрибутам:
series.struct.field("project")
0 pandas
1 numpy
2 pyarrow
Name: project, dtype: string[pyarrow]
В следующем выпуске появится CategoricalAccessor, основанный на типах Arrow.
Интеграция драйвера Apache ADBC
Исторически сложилось так, что pandas полагался на SqlAlchemy для чтения данных из базы данных Sql. Это работало очень надежно, но очень медленным. Alchemy читает данные построчно, в то время как pandas имеет столбцовую структуру, что делает чтение и перемещение данных в DataFrame медленнее, чем нужно.
Драйвер ADBC из проекта Apache Arrow позволяет читать данные в столбцовой компоновке, что значительно повышает производительность. Он считывает данные и сохраняет их в таблице Arrow, которая используется для преобразования в pandas DataFrame. Вы можете сделать это преобразование нулевым, если установите dtype_backend=”pyarrow” для read_sql.
Давайте рассмотрим пример:
import adbc_driver_postgresql.dbapi as pg_dbapi
df = pd.DataFrame(
[
[1, 2, 3],
[4, 5, 6],
],
columns=['a', 'b', 'c']
)
uri = "postgresql://postgres:postgres@localhost/postgres"
with pg_dbapi.connect(uri) as conn:
df.to_sql("pandas_table", conn, index=False)
# for round-tripping
with pg_dbapi.connect(uri) as conn:
df2 = pd.read_sql("pandas_table", conn)
Драйвер ADBC в настоящее время поддерживает Postgres и Sqlite. Я бы рекомендовал всем перейти на этот драйвер, если вы используете Postgres. Драйвер значительно быстрее и полностью избегает обхода объектов Python, что позволяет надежнее сохранять типы баз данных. Лично я больше всего рад именно этой возможности.
Добавление case_when в API pandas
Переходя от Sql к pandas, пользователям часто не хватает синтаксиса case-when, который обеспечивает простой и чистый способ условного создания новых столбцов. pandas 2.2 добавляет новый метод case_when, который определяется на Series. Он работает аналогично тому, как это делает Sql.
Давайте рассмотрим пример:
df = pd.DataFrame(dict(a=[1, 2, 3], b=[4, 5, 6]))
default=pd.Series('default', index=df.index)
default.case_when(
caselist=[
(df.a == 1, 'first'),
(df.a.gt(1) & df.b.eq(5), 'second'),
],
)
Метод принимает список условий, которые последовательно оцениваются. Затем создается новый объект с теми значениями в строках, где условие оценивается как True. Метод должен значительно облегчить нам создание условных столбцов.
Копирование при записи
Режим Copy-on-Write был первоначально представлен в pandas 1.5.0. Режим включен по умолчанию в версии 3.0, которая, как мы надеемся, появится в следующем выпуске pandas. Это означает, что мы должны привести наш код в состояние, в котором он будет соответствовать правилам Copy-on-Write. pandas 2.2 ввела предупреждения об устаревании для операций, которые изменят поведение.
df = pd.DataFrame({"x": [1, 2, 3]})
df["x"][df["x"] > 1] = 100
Теперь это вызовет предупреждение FutureWarning.
FutureWarning: ChainedAssignmentError: behaviour will change in pandas 3.0!
You are setting values through chained assignment. Currently this works in certain cases, but when
using Copy-on-Write (which will become the default behaviour in pandas 3.0) this will never work to
update the original DataFrame or Series, because the intermediate object on which we are setting
values will behave as a copy. A typical example is when you are setting values in a column of a
DataFrame, like:
df["col"][row_indexer] = value
Use `df.loc[row_indexer, "col"] = values` instead, to perform the assignment in a single step and
ensure this keeps updating the original `df`.
Для Copy-on-Write существует дополнительный режим предупреждения, который будет выдавать предупреждения для всех случаев, изменяющих поведение:
pd.options.mode.copy_on_write = "warn"
Большинство этих предупреждений являются шумом для большинства пользователей pandas, поэтому они скрыты за опцией.
pd.options.mode.copy_on_write = "warn"
df = pd.DataFrame({"a": [1, 2, 3]})
view = df["a"]
view.iloc[0] = 100
Это приведет к появлению длинного предупреждения, объясняющего, что изменится:
FutureWarning: Setting a value on a view: behaviour will change in pandas 3.0.
You are mutating a Series or DataFrame object, and currently this mutation will
also have effect on other Series or DataFrame objects that share data with this
object. In pandas 3.0 (with Copy-on-Write), updating one Series or DataFrame object
will never modify another.
Вкратце это можно описать так: Обновление view никогда не обновит df, независимо от того, какая операция используется. Скорее всего, для большинства это не имеет значения.
Я бы рекомендовал включить режим и кратко проверить предупреждения, но не обращать на них слишком много внимания, если вы уверены, что не рассчитываете на одновременное обновление двух разных объектов.
Обновление до новой версии
Вы можете установить новую версию pandas с помощью:
pip install -U pandas
Или же:
mamba install -c conda-forge pandas=2.2
В результате вы получите новый релиз в своем окружении.
Заключение
Мы рассмотрели несколько улучшений, которые повысят производительность и улучшат пользовательский опыт для некоторых аспектов pandas. Самые интересные новые возможности появятся в pandas 3.0, где Copy-on-Write будет включена по умолчанию.
Спасибо, что прочитали. Не стесняйтесь обращаться к нам, чтобы поделиться своими мыслями и отзывами.