Что нового в версии 1.5.0 (19 сентября 2022)#

Это изменения в pandas 1.5.0. См. Примечания к выпуску для полного списка изменений, включая другие версии pandas.

Улучшения#

pandas-stubs#

The pandas-stubs библиотека теперь поддерживается командой разработчиков pandas, предоставляя заглушки типов для API pandas. Пожалуйста, посетите pandas-dev/pandas-stubs для получения дополнительной информации.

Мы благодарим VirtusLab и Microsoft за их первоначальный, значительный вклад в pandas-stubs

Расширение Native PyArrow-backed ExtensionArray#

С Pyarrow установлен, пользователи теперь могут создавать объекты pandas которые поддерживаются pyarrow.ChunkedArray и pyarrow.DataType.

The dtype аргумент может принимать строку тип данных pyarrow с pyarrow в квадратных скобках, например "int64[pyarrow]" или, для типов данных pyarrow, принимающих параметры, ArrowDtype инициализированный с pyarrow.DataType.

In [1]: import pyarrow as pa

In [2]: ser_float = pd.Series([1.0, 2.0, None], dtype="float32[pyarrow]")

In [3]: ser_float
Out[3]: 
0     1.0
1     2.0
2    
dtype: float[pyarrow]

In [4]: list_of_int_type = pd.ArrowDtype(pa.list_(pa.int64()))

In [5]: ser_list = pd.Series([[1, 2], [3, None]], dtype=list_of_int_type)

In [6]: ser_list
Out[6]: 
0      [1. 2.]
1    [ 3. nan]
dtype: list[pyarrow]

In [7]: ser_list.take([1, 0])
Out[7]: 
1    [ 3. nan]
0      [1. 2.]
dtype: list[pyarrow]

In [8]: ser_float * 5
Out[8]: 
0     5.0
1    10.0
2    
dtype: float[pyarrow]

In [9]: ser_float.mean()
Out[9]: 1.5

In [10]: ser_float.dropna()
Out[10]: 
0    1.0
1    2.0
dtype: float[pyarrow]

Большинство операций поддерживаются и были реализованы с использованием pyarrow compute функций. Мы рекомендуем установить последнюю версию PyArrow для доступа к недавно реализованным вычислительным функциям.

Предупреждение

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

Реализация протокола обмена DataFrame#

Pandas теперь реализует спецификацию API обмена DataFrame. Подробности об API см. на https://data-apis.org/dataframe-protocol/latest/index.html

Протокол состоит из двух частей:

  • Новый метод DataFrame.__dataframe__() который создает объект обмена. Он эффективно «экспортирует» датафрейм pandas как объект обмена, так что любая другая библиотека, реализующая протокол, может «импортировать» этот датафрейм, не зная ничего о производителе, кроме того, что он создает объект обмена.

  • Новая функция pandas.api.interchange.from_dataframe() который может принимать произвольный объект обмена из любой совместимой библиотеки и создавать из него pandas DataFrame.

Styler#

Наиболее заметным нововведением является новый метод Styler.concat() который позволяет добавлять настраиваемые строки нижнего колонтитула для визуализации дополнительных вычислений над данными, например, итогов и подсчетов и т.д. (GH 43875, GH 46186)

Кроме того, существует альтернативный метод вывода Styler.to_string(), что позволяет использовать методы форматирования Styler для создания, например, CSV (GH 44502).

Новая функция Styler.relabel_index() также доступен для полной настройки отображения заголовков индекса или столбцов (GH 47864)

Незначительные улучшения функций:

  • Добавление возможности отрисовки border и border-{side} CSS свойства в Excel (GH 42276)

  • Согласованность ключевых аргументов: Styler.highlight_null() теперь принимает color и объявляет устаревшим null_color хотя это остается обратно совместимым (GH 45907)

Управление индексом с group_keys в DataFrame.resample()#

Аргумент group_keys был добавлен к методу DataFrame.resample(). Как и в случае с DataFrame.groupby(), этот аргумент управляет тем, добавляется ли каждая группа в индекс при ресемплинге, когда Resampler.apply() используется.

Предупреждение

Не указывая group_keys аргумент сохранит предыдущее поведение и выдаст предупреждение, если результат изменится при указании group_keys=False. В будущей версии pandas, если не указать group_keys по умолчанию будет использовать то же поведение, что и group_keys=False.

In [11]: df = pd.DataFrame(
   ....:     {'a': range(6)},
   ....:     index=pd.date_range("2021-01-01", periods=6, freq="8H")
   ....: )
   ....:

In [12]: df.resample("D", group_keys=True).apply(lambda x: x)
Out[12]:
                                a
2021-01-01 2021-01-01 00:00:00  0
           2021-01-01 08:00:00  1
           2021-01-01 16:00:00  2
2021-01-02 2021-01-02 00:00:00  3
           2021-01-02 08:00:00  4
           2021-01-02 16:00:00  5

In [13]: df.resample("D", group_keys=False).apply(lambda x: x)
Out[13]:
                     a
2021-01-01 00:00:00  0
2021-01-01 08:00:00  1
2021-01-01 16:00:00  2
2021-01-02 00:00:00  3
2021-01-02 08:00:00  4
2021-01-02 16:00:00  5

Ранее результирующий индекс зависел от значений, возвращаемых apply, как показано в следующем примере.

In [1]: # pandas 1.3
In [2]: df.resample("D").apply(lambda x: x)
Out[2]:
                     a
2021-01-01 00:00:00  0
2021-01-01 08:00:00  1
2021-01-01 16:00:00  2
2021-01-02 00:00:00  3
2021-01-02 08:00:00  4
2021-01-02 16:00:00  5

In [3]: df.resample("D").apply(lambda x: x.reset_index())
Out[3]:
                           index  a
2021-01-01 0 2021-01-01 00:00:00  0
           1 2021-01-01 08:00:00  1
           2 2021-01-01 16:00:00  2
2021-01-02 0 2021-01-02 00:00:00  3
           1 2021-01-02 08:00:00  4
           2 2021-01-02 16:00:00  5

from_dummies#

Добавлена новая функция from_dummies() для преобразования фиктивно закодированного DataFrame в категориальный DataFrame.

In [11]: import pandas as pd

In [12]: df = pd.DataFrame({"col1_a": [1, 0, 1], "col1_b": [0, 1, 0],
   ....:                    "col2_a": [0, 1, 0], "col2_b": [1, 0, 0],
   ....:                    "col2_c": [0, 0, 1]})
   ....: 

In [13]: pd.from_dummies(df, sep="_")
Out[13]: 
  col1 col2
0    a    b
1    b    a
2    a    c

Запись в файлы ORC#

Новый метод DataFrame.to_orc() позволяет записывать в файлы ORC (GH 43864).

Эта функциональность зависит от pyarrow библиотеки. Для получения дополнительных сведений см. документация по вводу-выводу по ORC.

Предупреждение

  • Это настоятельно рекомендуется для установки pyarrow с помощью conda из-за некоторых проблем, вызванных pyarrow.

  • to_orc() требует pyarrow>=7.0.0.

  • to_orc() еще не поддерживается в Windows, вы можете найти допустимые среды на установить дополнительные зависимости.

  • Для поддерживаемых типов данных обратитесь к поддерживаемые функции ORC в Arrow.

  • В настоящее время часовые пояса в столбцах datetime не сохраняются при преобразовании датафрейма в файлы ORC.

df = pd.DataFrame(data={"col1": [1, 2], "col2": [3, 4]})
df.to_orc("./out.orc")

Чтение напрямую из TAR-архивов#

Методы ввода-вывода, такие как read_csv() или DataFrame.to_json() теперь позволяет читать и записывать напрямую в архивы TAR (GH 44787).

df = pd.read_csv("./movement.tar.gz")
# ...
df.to_csv("./out.tar.gz")

Это поддерживает .tar, .tar.gz, .tar.bz и .tar.xz2 архивах. Используемый метод сжатия определяется по имени файла. Если метод сжатия не может быть определен, используйте compression аргумент:

df = pd.read_csv(some_file_obj, compression={"method": "tar", "mode": "r:gz"}) # noqa F821

(mode будучи одним из tarfile.openрежимы: https://docs.python.org/3/library/tarfile.html#tarfile.open)

read_xml теперь поддерживает dtype, converters, и parse_dates#

Аналогично другим методам ввода-вывода, pandas.read_xml() теперь поддерживает назначение конкретных типов данных столбцам, применение методов преобразования и парсинг дат (GH 43567).

In [14]: from io import StringIO

In [15]: xml_dates = """
   ....: 
   ....:   
   ....:     square
   ....:     00360
   ....:     4.0
   ....:     2020-01-01
   ....:    
   ....:   
   ....:     circle
   ....:     00360
   ....:     
   ....:     2021-01-01
   ....:   
   ....:   
   ....:     triangle
   ....:     00180
   ....:     3.0
   ....:     2022-01-01
   ....:   
   ....: """
   ....: 

In [16]: df = pd.read_xml(
   ....:     StringIO(xml_dates),
   ....:     dtype={'sides': 'Int64'},
   ....:     converters={'degrees': str},
   ....:     parse_dates=['date']
   ....: )
   ....: 

In [17]: df
Out[17]: 
      shape degrees  sides       date
0    square   00360      4 2020-01-01
1    circle   00360    2021-01-01
2  triangle   00180      3 2022-01-01

In [18]: df.dtypes
Out[18]: 
shape              object
degrees            object
sides               Int64
date       datetime64[ns]
dtype: object

read_xml теперь поддерживает большие XML с использованием iterparse#

Для очень больших XML-файлов, размер которых может составлять от сотен мегабайт до гигабайт, pandas.read_xml() теперь поддерживает разбор таких объемных файлов с использованием lxml’s iterparse и iterparse из etree которые являются эффективными по памяти методами для итерации по XML-деревьям и извлечения конкретных элементов и атрибутов без хранения всего дерева в памяти (GH 45442).

In [1]: df = pd.read_xml(
...      "/path/to/downloaded/enwikisource-latest-pages-articles.xml",
...      iterparse = {"page": ["title", "ns", "id"]})
...  )
df
Out[2]:
                                                     title   ns        id
0                                       Gettysburg Address    0     21450
1                                                Main Page    0     42950
2                            Declaration by United Nations    0      8435
3             Constitution of the United States of America    0      8435
4                     Declaration of Independence (Israel)    0     17858
...                                                    ...  ...       ...
3578760               Page:Black cat 1897 07 v2 n10.pdf/17  104    219649
3578761               Page:Black cat 1897 07 v2 n10.pdf/43  104    219649
3578762               Page:Black cat 1897 07 v2 n10.pdf/44  104    219649
3578763      The History of Tom Jones, a Foundling/Book IX    0  12084291
3578764  Page:Shakespeare of Stratford (1926) Yale.djvu/91  104     21450

[3578765 rows x 3 columns]

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

Новая функция copy_on_write был добавлен (GH 46958). Копирование при записи гарантирует, что любой DataFrame или Series, полученный из другого любым способом, всегда ведет себя как копия. Копирование при записи запрещает обновление любого другого объекта, кроме объекта, к которому был применен метод.

Копирование при записи можно включить через:

pd.set_option("mode.copy_on_write", True)
pd.options.mode.copy_on_write = True

Кроме того, копирование при записи можно включить локально через:

with pd.option_context("mode.copy_on_write", True):
    ...

Без копирования при записи, родительский DataFrame обновляется при обновлении дочернего элемента DataFrame который был получен из этого DataFrame.

In [19]: df = pd.DataFrame({"foo": [1, 2, 3], "bar": 1})

In [20]: view = df["foo"]

In [21]: view.iloc[0]
Out[21]: 1

In [22]: df
Out[22]: 
   foo  bar
0    1    1
1    2    1
2    3    1

При включенной копии при записи df больше не будет обновляться:

In [23]: with pd.option_context("mode.copy_on_write", True):
   ....:     df = pd.DataFrame({"foo": [1, 2, 3], "bar": 1})
   ....:     view = df["foo"]
   ....:     view.iloc[0]
   ....:     df
   ....: 

Более подробное объяснение можно найти здесь.

Другие улучшения#

Значительные исправления ошибок#

Это исправления ошибок, которые могут привести к заметным изменениям в поведении.

Используя dropna=True с groupby преобразует#

Преобразование — это операция, результат которой имеет тот же размер, что и её входные данные. Когда результат является DataFrame или Seriesтакже требуется, чтобы индекс результата соответствовал индексу входных данных. В pandas 1.4, используя DataFrameGroupBy.transform() или SeriesGroupBy.transform() с нулевыми значениями в группах и dropna=True давал некорректные результаты. Как показано в примерах ниже, некорректные результаты либо содержали неверные значения, либо результат не имел того же индекса, что и входные данные.

In [24]: df = pd.DataFrame({'a': [1, 1, np.nan], 'b': [2, 3, 4]})

Старое поведение:

In [3]: # Value in the last row should be np.nan
        df.groupby('a', dropna=True).transform('sum')
Out[3]:
   b
0  5
1  5
2  5

In [3]: # Should have one additional row with the value np.nan
        df.groupby('a', dropna=True).transform(lambda x: x.sum())
Out[3]:
   b
0  5
1  5

In [3]: # The value in the last row is np.nan interpreted as an integer
        df.groupby('a', dropna=True).transform('ffill')
Out[3]:
                     b
0                    2
1                    3
2 -9223372036854775808

In [3]: # Should have one additional row with the value np.nan
        df.groupby('a', dropna=True).transform(lambda x: x)
Out[3]:
   b
0  2
1  3

Новое поведение:

In [25]: df.groupby('a', dropna=True).transform('sum')
Out[25]: 
     b
0  5.0
1  5.0
2  NaN

In [26]: df.groupby('a', dropna=True).transform(lambda x: x.sum())
Out[26]: 
     b
0  5.0
1  5.0
2  NaN

In [27]: df.groupby('a', dropna=True).transform('ffill')
Out[27]: 
     b
0  2.0
1  3.0
2  NaN

In [28]: df.groupby('a', dropna=True).transform(lambda x: x)
Out[28]: 
     b
0  2.0
1  3.0
2  NaN

Сериализация tz-naive Timestamps с помощью to_json() с iso_dates=True#

DataFrame.to_json(), Series.to_json(), и Index.to_json() неправильно локализовал DatetimeArrays/DatetimeIndexes с tz-naive Timestamps в UTC. (GH 38760)

Обратите внимание, что этот патч не исправляет локализацию tz-aware Timestamps в UTC при сериализации. (Связанная проблема GH 12997)

Старое поведение

In [32]: index = pd.date_range(
   ....:     start='2020-12-28 00:00:00',
   ....:     end='2020-12-28 02:00:00',
   ....:     freq='1H',
   ....: )
   ....:

In [33]: a = pd.Series(
   ....:     data=range(3),
   ....:     index=index,
   ....: )
   ....:

In [4]: from io import StringIO

In [5]: a.to_json(date_format='iso')
Out[5]: '{"2020-12-28T00:00:00.000Z":0,"2020-12-28T01:00:00.000Z":1,"2020-12-28T02:00:00.000Z":2}'

In [6]: pd.read_json(StringIO(a.to_json(date_format='iso')), typ="series").index == a.index
Out[6]: array([False, False, False])

Новое поведение

In [34]: from io import StringIO

In [35]: a.to_json(date_format='iso')
Out[35]: '{"2020-12-28T00:00:00.000Z":0,"2020-12-28T01:00:00.000Z":1,"2020-12-28T02:00:00.000Z":2}'

# Roundtripping now works
In [36]: pd.read_json(StringIO(a.to_json(date_format='iso')), typ="series").index == a.index
Out[36]: array([ True,  True,  True])

DataFrameGroupBy.value_counts с негруппируемыми категориальными столбцами и observed=True#

Вызов DataFrameGroupBy.value_counts() с observed=True неправильно удалял ненаблюдаемые категории негруппирующих столбцов (GH 46357).

In [6]: df = pd.DataFrame(["a", "b", "c"], dtype="category").iloc[0:2]
In [7]: df
Out[7]:
   0
0  a
1  b

Старое поведение

In [8]: df.groupby(level=0, observed=True).value_counts()
Out[8]:
0  a    1
1  b    1
dtype: int64

Новое поведение

In [9]: df.groupby(level=0, observed=True).value_counts()
Out[9]:
0  a    1
1  a    0
   b    1
0  b    0
   c    0
1  c    0
dtype: int64

Обратно несовместимые изменения API#

Повышенные минимальные версии для зависимостей#

Некоторые минимальные поддерживаемые версии зависимостей были обновлены. Если установлены, теперь требуются:

Пакет

Минимальная версия

Обязательно

Изменено

numpy

1.20.3

X

X

mypy (dev)

0.971

X

beautifulsoup4

4.9.3

X

blosc

1.21.0

X

bottleneck

1.3.2

X

fsspec

2021.07.0

X

гипотеза

6.13.0

X

gcsfs

2021.07.0

X

jinja2

3.0.0

X

lxml

4.6.3

X

numba

0.53.1

X

numexpr

2.7.3

X

openpyxl

3.0.7

X

pandas-gbq

0.15.0

X

psycopg2

2.8.6

X

pymysql

1.0.2

X

pyreadstat

1.1.2

X

pyxlsb

1.0.8

X

s3fs

2021.08.0

X

scipy

1.7.1

X

sqlalchemy

1.4.16

X

tabulate

0.8.9

X

xarray

0.19.0

X

xlsxwriter

1.4.3

X

Для дополнительные библиотеки общая рекомендация — использовать последнюю версию. Следующая таблица перечисляет минимальную версию для каждой библиотеки, которая в настоящее время тестируется в ходе разработки pandas. Опциональные библиотеки ниже минимальной тестируемой версии могут всё ещё работать, но не считаются поддерживаемыми.

Пакет

Минимальная версия

Изменено

beautifulsoup4

4.9.3

X

blosc

1.21.0

X

bottleneck

1.3.2

X

brotlipy

0.7.0

fastparquet

0.4.0

fsspec

2021.08.0

X

html5lib

1.1

гипотеза

6.13.0

X

gcsfs

2021.08.0

X

jinja2

3.0.0

X

lxml

4.6.3

X

matplotlib

3.3.2

numba

0.53.1

X

numexpr

2.7.3

X

odfpy

1.4.1

openpyxl

3.0.7

X

pandas-gbq

0.15.0

X

psycopg2

2.8.6

X

pyarrow

1.0.1

pymysql

1.0.2

X

pyreadstat

1.1.2

X

pytables

3.6.1

python-snappy

0.6.0

pyxlsb

1.0.8

X

s3fs

2021.08.0

X

scipy

1.7.1

X

sqlalchemy

1.4.16

X

tabulate

0.8.9

X

tzdata

2022a

xarray

0.19.0

X

xlrd

2.0.1

xlsxwriter

1.4.3

X

xlwt

1.3.0

zstandard

0.15.2

См. Зависимости и Необязательные зависимости подробнее.

Другие изменения API#

  • Методы ввода-вывода BigQuery read_gbq() и DataFrame.to_gbq() по умолчанию auth_local_webserver = True. Google устарел auth_local_webserver = False «внеполосный» (копирование-вставка) поток. auth_local_webserver = False опция планируется к прекращению работы в октябре 2022 года. (GH 46312)

  • read_json() теперь вызывает FileNotFoundError (ранее ValueError) когда входные данные являются строкой, заканчивающейся на .json, .json.gz, .json.bz2, и т.д., но такого файла не существует. (GH 29102)

  • Операции с Timestamp или Timedelta что ранее вызывало OverflowError вместо этого вызывать OutOfBoundsDatetime или OutOfBoundsTimedelta где это уместно (GH 47268)

  • Когда read_sas() ранее возвращалось None, теперь возвращает пустой DataFrame (GH 47410)

  • DataFrame конструктор вызывает исключение, если index или columns аргументы являются множествами (GH 47215)

Устаревшие функции#

Предупреждение

В следующем крупном релизе версии 2.0 рассматриваются несколько значительных изменений API без формального устаревания, таких как сделать стандартную библиотеку zoneinfo реализацию часового пояса по умолчанию вместо pytz, имея Index поддерживать все типы данных вместо наличия нескольких подклассов (CategoricalIndex, Int64Index, и т.д.), и многое другое. Предлагаемые изменения регистрируются в этот issue на GitHub, и любые отзывы или замечания приветствуются.

Срез на основе меток целыми числами для Series с Int64Index или RangeIndex#

В будущей версии целочисленное срезы на Series с Int64Index или RangeIndex будет рассматриваться как на основе меток, не позиционные. Это сделает поведение согласованным с другими Series.__getitem__() и Series.__setitem__() поведения (GH 45162).

Например:

In [29]: ser = pd.Series([1, 2, 3, 4, 5], index=[2, 3, 5, 7, 11])

В старом поведении, ser[2:4] обрабатывает срез как позиционный:

Старое поведение:

In [3]: ser[2:4]
Out[3]:
5    3
7    4
dtype: int64

В будущей версии это будет рассматриваться как основанное на метках:

Будущее поведение:

In [4]: ser.loc[2:4]
Out[4]:
2    1
3    2
dtype: int64

Чтобы сохранить старое поведение, используйте series.iloc[i:j]. Чтобы получить будущее поведение, используйте series.loc[i:j].

Срезы на DataFrame не будут затронуты.

ExcelWriter атрибуты#

Все атрибуты ExcelWriter ранее документировались как не публичные. Однако некоторые сторонние движки Excel документировали доступ к ExcelWriter.book или ExcelWriter.sheets, и пользователи использовали эти и возможно другие атрибуты. Ранее эти атрибуты не были безопасны для использования; например, изменения в ExcelWriter.book не будет обновлять ExcelWriter.sheets и наоборот. Для поддержки этого pandas сделал некоторые атрибуты публичными и улучшил их реализации, чтобы их можно было безопасно использовать. (GH 45572)

Следующие атрибуты теперь являются публичными и считаются безопасными для доступа.

  • book

  • check_extension

  • close

  • date_format

  • datetime_format

  • engine

  • if_sheet_exists

  • sheets

  • supported_extensions

Следующие атрибуты устарели. Теперь они вызывают FutureWarning при доступе и будет удалён в будущей версии. Пользователи должны знать, что их использование считается небезопасным и может привести к неожиданным результатам.

  • cur_sheet

  • handles

  • path

  • save

  • write_cells

См. документацию ExcelWriter для дополнительных деталей.

Используя group_keys с преобразователями в DataFrameGroupBy.apply() и SeriesGroupBy.apply()#

В предыдущих версиях pandas, если определялось, что переданная функция DataFrameGroupBy.apply() или SeriesGroupBy.apply() был трансформером (т.е. результирующий индекс был равен входному индексу), group_keys аргумент DataFrame.groupby() и Series.groupby() игнорировался, и ключи группировки никогда не добавлялись в индекс результата. В будущем ключи группировки будут добавляться в индекс при указании пользователем group_keys=True.

Поскольку group_keys=True является значением по умолчанию для DataFrame.groupby() и Series.groupby(), не указывая group_keys с трансформером вызовет FutureWarning. Это можно отключить и сохранить предыдущее поведение, указав group_keys=False.

Операция на месте при установке значений с loc и iloc#

В большинстве случаев установка значений с помощью DataFrame.iloc() пытается установить значения на месте, прибегая к вставке нового массива только при необходимости. Существуют некоторые случаи, когда это правило не соблюдается, например, при установке целого столбца из массива с другим dtype:

In [30]: df = pd.DataFrame({'price': [11.1, 12.2]}, index=['book1', 'book2'])

In [31]: original_prices = df['price']

In [32]: new_prices = np.array([98, 99])

Старое поведение:

In [3]: df.iloc[:, 0] = new_prices
In [4]: df.iloc[:, 0]
Out[4]:
book1    98
book2    99
Name: price, dtype: int64
In [5]: original_prices
Out[5]:
book1    11.1
book2    12.2
Name: price, float: 64

Это поведение устарело. В будущей версии установка всего столбца с помощью iloc будет пытаться работать на месте.

Будущее поведение:

In [3]: df.iloc[:, 0] = new_prices
In [4]: df.iloc[:, 0]
Out[4]:
book1    98.0
book2    99.0
Name: price, dtype: float64
In [5]: original_prices
Out[5]:
book1    98.0
book2    99.0
Name: price, dtype: float64

Чтобы получить старое поведение, используйте DataFrame.__setitem__() напрямую:

In [3]: df[df.columns[0]] = new_prices
In [4]: df.iloc[:, 0]
Out[4]
book1    98
book2    99
Name: price, dtype: int64
In [5]: original_prices
Out[5]:
book1    11.1
book2    12.2
Name: price, dtype: float64

Чтобы получить старое поведение, когда df.columns не является уникальным и вы хотите изменить один столбец по индексу, вы можете использовать DataFrame.isetitem(), который был добавлен в pandas 1.5:

In [3]: df_with_duplicated_cols = pd.concat([df, df], axis='columns')
In [3]: df_with_duplicated_cols.isetitem(0, new_prices)
In [4]: df_with_duplicated_cols.iloc[:, 0]
Out[4]:
book1    98
book2    99
Name: price, dtype: int64
In [5]: original_prices
Out[5]:
book1    11.1
book2    12.2
Name: 0, dtype: float64

numeric_only значение по умолчанию#

По DataFrame, DataFrameGroupBy, и Resampler операции, такие как min, sum, и idxmax, значение по умолчанию параметра numeric_only аргумент, если он вообще существует, был непоследовательным. Кроме того, операции со значением по умолчанию None может привести к неожиданным результатам. (GH 46560)

In [1]: df = pd.DataFrame({"a": [1, 2], "b": ["x", "y"]})

In [2]: # Reading the next line without knowing the contents of df, one would
        # expect the result to contain the products for both columns a and b.
        df[["a", "b"]].prod()
Out[2]:
a    2
dtype: int64

Чтобы избежать этого поведения, указание значения numeric_only=None был устаревшим и будет удален в будущей версии pandas. В будущем все операции с numeric_only аргумент по умолчанию будет False. Пользователи должны либо вызывать операцию только со столбцами, с которыми можно работать, либо указывать numeric_only=True работать только со столбцами Boolean, integer и float.

Для поддержки перехода к новому поведению следующие методы получили numeric_only аргумент.

Другие устаревшие функции#

  • Устаревший ключевое слово line_terminator в DataFrame.to_csv() и Series.to_csv(), используйте lineterminator вместо этого; это сделано для согласованности с read_csv() и стандартный модуль 'csv' (GH 9568)

  • Устаревшее поведение SparseArray.astype(), Series.astype(), и DataFrame.astype() с SparseDtype при передаче неразреженного dtype. В будущей версии это будет преобразовано в неразреженный тип данных вместо оборачивания в SparseDtype (GH 34457)

  • Устаревшее поведение DatetimeIndex.intersection() и DatetimeIndex.symmetric_difference() (union поведение уже было устаревшим в версии 1.3.0) со смешанными часовыми поясами; в будущей версии оба будут приведены к UTC вместо типа object (GH 39328, GH 45357)

  • Устаревший DataFrame.iteritems(), Series.iteritems(), HDFStore.iteritems() в пользу DataFrame.items(), Series.items(), HDFStore.items() (GH 45321)

  • Устаревший Series.is_monotonic() и Index.is_monotonic() в пользу Series.is_monotonic_increasing() и Index.is_monotonic_increasing() (GH 45422, GH 21335)

  • Устаревшее поведение DatetimeIndex.astype(), TimedeltaIndex.astype(), PeriodIndex.astype() при преобразовании в целочисленный тип данных, отличный от int64. В будущей версии они будут преобразовываться точно в указанный dtype (вместо того, чтобы всегда int64) и вызовет исключение, если преобразование переполняется (GH 45034)

  • Устарел __array_wrap__ метод DataFrame и Series, полагаться на стандартные numpy ufuncs вместо (GH 45451)

  • Устарело: обработка данных с типом float как настенных часов при передаче с часовым поясом в Series или DatetimeIndex (GH 45573)

  • Устаревшее поведение Series.fillna() и DataFrame.fillna() с timedelta64[ns] dtype и несовместимое значение заполнения; в будущей версии это будет приведено к общему dtype (обычно object) вместо вызова исключения, соответствуя поведению других dtypes (GH 45746)

  • Устарел warn параметр в infer_freq() (GH 45947)

  • Устарело разрешение неключевых аргументов в ExtensionArray.argsort() (GH 46134)

  • Устаревшая обработка всех булевых object-столбцы типа dtype как булево-подобные в DataFrame.any() и DataFrame.all() с bool_only=True, явно приведение к bool вместо (GH 46188)

  • Устаревшее поведение метода DataFrame.quantile(), атрибут numeric_only по умолчанию будет False. Включение столбцов datetime/timedelta в результат (GH 7308).

  • Устаревший Timedelta.freq и Timedelta.is_populated (GH 46430)

  • Устаревший Timedelta.delta (GH 46476)

  • Устаревшая передача аргументов как позиционных в DataFrame.any() и Series.any() (GH 44802)

  • Устаревшая передача позиционных аргументов в DataFrame.pivot() и pivot() кроме data (GH 30228)

  • Устаревшие методы DataFrame.mad(), Series.mad(), и соответствующие методы groupby (GH 11787)

  • Устаревшие позиционные аргументы для Index.join() за исключением other, используйте аргументы только по ключевым словам вместо позиционных аргументов (GH 46518)

  • Устаревшие позиционные аргументы для StringMethods.rsplit() и StringMethods.split() за исключением pat, используйте аргументы только по ключевым словам вместо позиционных аргументов (GH 47423)

  • Устаревшее индексирование на временной зоне без учета часового пояса DatetimeIndex используя строку, представляющую дату-время с учетом часового пояса (GH 46903, GH 36148)

  • Устарело разрешение unit="M" или unit="Y" в Timestamp конструктор с неокругленным значением с плавающей точкой (GH 47267)

  • Устарел display.column_space глобальная опция конфигурации (GH 7576)

  • Аргумент устарел na_sentinel в factorize(), Index.factorize(), и ExtensionArray.factorize(); передать use_na_sentinel=True вместо этого, чтобы использовать маркер -1 для значений NaN и use_na_sentinel=False вместо na_sentinel=None для кодирования значений NaN (GH 46910)

  • Устаревший DataFrameGroupBy.transform() не выравнивание результата, когда UDF возвращал DataFrame (GH 45648)

  • Уточненное предупреждение от to_datetime() когда разделенные даты не могут быть разобраны в соответствии с указанным dayfirst аргумент (GH 46210)

  • Выдавать предупреждение из to_datetime() когда разделенные даты не могут быть разобраны в соответствии с указанным dayfirst аргумент даже для дат, где ведущий ноль опущен (например, 31/1/2001) (GH 47880)

  • Устаревший Series и Resampler редукторы (например, min, max, sum, mean) вызывая NotImplementedError когда тип данных не является числовым и numeric_only=True предоставлен; это вызовет TypeError в будущей версии (GH 47500)

  • Устаревший Series.rank() возвращает пустой результат, когда dtype не является числовым и numeric_only=True предоставлен; это вызовет TypeError в будущей версии (GH 47500)

  • Устаревший аргумент errors для Series.mask(), Series.where(), DataFrame.mask(), и DataFrame.where() как errors не влиял на эти методы (GH 47728)

  • Устаревшие аргументы *args и **kwargs в Rolling, Expanding, и ExponentialMovingWindow операции. (GH 47836)

  • Устарел inplace ключевое слово в Categorical.set_ordered(), Categorical.as_ordered(), и Categorical.as_unordered() (GH 37643)

  • Устаревшая установка категорий категориальной переменной с помощью cat.categories = ['a', 'b', 'c'], используйте Categorical.rename_categories() вместо (GH 37643)

  • Устаревшие неиспользуемые аргументы encoding и verbose в Series.to_excel() и DataFrame.to_excel() (GH 47912)

  • Устарел inplace ключевое слово в DataFrame.set_axis() и Series.set_axis(), используйте obj = obj.set_axis(..., copy=False) вместо (GH 48130)

  • Устарело создание одного элемента при итерации по DataFrameGroupBy или SeriesGroupBy который был сгруппирован по списку длины 1; Будет возвращён кортеж длины один вместо (GH 42795)

  • Исправлено предупреждающее сообщение об устаревании MultiIndex.lesort_depth() как публичный метод, как упоминалось ранее MultiIndex.is_lexsorted() вместо (GH 38701)

  • Устарел sort_columns аргумент в DataFrame.plot() и Series.plot() (GH 47563).

  • Устаревшие позиционные аргументы для всех, кроме первого аргумента DataFrame.to_stata() и read_stata(), используйте ключевые аргументы вместо (GH 48128).

  • Устарел mangle_dupe_cols аргумент в read_csv(), read_fwf(), read_table() и read_excel(). Аргумент никогда не был реализован, и вместо него будет добавлен новый аргумент, в котором можно указать шаблон переименования (GH 47718)

  • Устарело разрешение dtype='datetime64' или dtype=np.datetime64 в Series.astype(), используйте "datetime64[ns]" вместо (GH 47844)

Улучшения производительности#

  • Улучшение производительности в DataFrame.corrwith() для построчного (axis=0) коэффициента корреляции Пирсона и Спирмена, когда other является Series (GH 46174)

  • Улучшение производительности в DataFrameGroupBy.transform() и SeriesGroupBy.transform() для некоторых пользовательских функций DataFrame -> Series (GH 45387)

  • Улучшение производительности в DataFrame.duplicated() когда подмножество состоит только из одного столбца (GH 45236)

  • Улучшение производительности в DataFrameGroupBy.diff() и SeriesGroupBy.diff() (GH 16706)

  • Улучшение производительности в DataFrameGroupBy.transform() и SeriesGroupBy.transform() при трансляции значений для пользовательских функций (GH 45708)

  • Улучшение производительности в DataFrameGroupBy.transform() и SeriesGroupBy.transform() для пользовательских функций, когда существует только одна группа (GH 44977)

  • Улучшение производительности в DataFrameGroupBy.apply() и SeriesGroupBy.apply() при группировке по неуникальному несортированному индексу (GH 46527)

  • Улучшение производительности в DataFrame.loc() и Series.loc() для индексации на основе кортежа в MultiIndex (GH 45681, GH 46040, GH 46330)

  • Улучшение производительности в DataFrameGroupBy.var() и SeriesGroupBy.var() с ddof отличное от единицы (GH 48152)

  • Улучшение производительности в DataFrame.to_records() когда индекс является MultiIndex (GH 47263)

  • Улучшение производительности в MultiIndex.values когда MultiIndex содержит уровни типа DatetimeIndex, TimedeltaIndex или ExtensionDtypes (GH 46288)

  • Улучшение производительности в merge() когда левый и/или правый пусты (GH 45838)

  • Улучшение производительности в DataFrame.join() когда левый и/или правый пусты (GH 46015)

  • Улучшение производительности в DataFrame.reindex() и Series.reindex() когда цель — это MultiIndex (GH 46235)

  • Улучшение производительности при установке значений в строковом массиве на основе pyarrow (GH 46400)

  • Улучшение производительности в factorize() (GH 46109)

  • Улучшение производительности в DataFrame и Series конструкторы для скаляров типа расширения (GH 45854)

  • Улучшение производительности в read_excel() когда nrows аргумент предоставлен (GH 32727)

  • Улучшение производительности в Styler.to_excel() при применении повторяющихся CSS форматов (GH 47371)

  • Улучшение производительности в MultiIndex.is_monotonic_increasing() (GH 47458)

  • Улучшение производительности в BusinessHour str и repr (GH 44764)

  • Улучшение производительности при форматировании строк массивов datetime, когда один из форматов strftime по умолчанию "%Y-%m-%d %H:%M:%S" или "%Y-%m-%d %H:%M:%S.%f" используется. (GH 44764)

  • Улучшение производительности в Series.to_sql() и DataFrame.to_sql() (SQLiteTable) при обработке массивов времени. (GH 44764)

  • Улучшение производительности для read_sas() (GH 47404)

  • Улучшение производительности в argmax и argmin для arrays.SparseArray (GH 34197)

Исправления ошибок#

Категориальный#

  • Ошибка в Categorical.view() не принимает целочисленные типы данных (GH 25464)

  • Ошибка в CategoricalIndex.union() когда категории индекса имеют целочисленный тип данных и индекс содержит NaN значения некорректно вызывают исключение вместо приведения к float64 (GH 45362)

  • Ошибка в concat() при объединении двух (или более) неупорядоченных CategoricalIndex переменных, чьи категории являются перестановками, приводит к некорректным значениям индекса (GH 24845)

Datetimelike#

  • Ошибка в DataFrame.quantile() с datetime-подобными типами данных и без строк, неправильно возвращающими float64 dtype вместо сохранения datetime-like dtype (GH 41544)

  • Ошибка в to_datetime() с последовательностями np.str_ объектов некорректно вызывает исключение (GH 32264)

  • Ошибка в Timestamp конструкция при передаче компонентов даты и времени как позиционных аргументов и tzinfo в качестве ключевого аргумента, ошибочно вызывая (GH 31929)

  • Ошибка в Index.astype() при приведении типа из object dtype к timedelta64[ns] неправильное приведение типа dtype np.datetime64("NaT") значения в np.timedelta64("NaT") вместо вызова исключения (GH 45722)

  • Ошибка в SeriesGroupBy.value_counts() индекс при передаче категориального столбца (GH 44324)

  • Ошибка в DatetimeIndex.tz_localize() локализация в UTC не создает копию исходных данных (GH 46460)

  • Ошибка в DatetimeIndex.resolution() неправильно возвращает "день" вместо "наносекунда" для индексов с наносекундным разрешением (GH 46903)

  • Ошибка в Timestamp с целочисленным или значением с плавающей точкой и unit="Y" или unit="M" давая слегка неверные результаты (GH 47266)

  • Ошибка в DatetimeArray конструкция при передаче другого DatetimeArray и freq=None некорректное определение частоты из заданного массива (GH 47296)

  • Ошибка в to_datetime() где OutOfBoundsDatetime будет выброшено, даже если errors=coerce если было более 50 строк (GH 45319)

  • Ошибка при добавлении DateOffset в Series не добавлял бы nanoseconds поле (GH 47856)

Timedelta#

  • Ошибка в astype_nansafe() astype("timedelta64[ns]") завершается ошибкой, когда включено np.nan (GH 45798)

  • Ошибка при построении Timedelta с np.timedelta64 объект и unit иногда молчаливо переполняется и возвращает некорректные результаты вместо вызова OutOfBoundsTimedelta (GH 46827)

  • Ошибка при построении Timedelta из большого целого числа или числа с плавающей точкой с unit="W" тихо переполняясь и возвращая некорректные результаты вместо вызова OutOfBoundsTimedelta (GH 47268)

Часовые пояса#

  • Ошибка в Timestamp конструктор вызывает исключение при передаче ZoneInfo tzinfo object (GH 46425)

Числовой#

  • Ошибка в операциях с массиво-подобными объектами с dtype="boolean" и NA неправильное изменение массива на месте (GH 45421)

  • Ошибка в арифметических операциях с обнуляемыми типами без NA значения, не соответствующие той же операции с типами, не допускающими null (GH 48223)

  • Ошибка в floordiv при делении на IntegerDtype 0 вернёт 0 вместо inf (GH 48223)

  • Ошибка в делении, pow и mod операции над массиво-подобными объектами с dtype="boolean" не являющиеся похожими на свои np.bool_ аналоги (GH 46063)

  • Ошибка при умножении Series с IntegerDtype или FloatingDtype массивоподобным объектом с timedelta64[ns] dtype некорректно вызывает (GH 45622)

  • Ошибка в mean() где опциональная зависимость bottleneck вызывает потерю точности, линейную по длине массива. bottleneck был отключен для mean() улучшая потери до логарифмически-линейных, но может привести к снижению производительности. (GH 42878)

Преобразование#

  • Ошибка в DataFrame.astype() не сохраняя подклассы (GH 40810)

  • Ошибка при построении Series из списка, содержащего числа с плавающей точкой, или ndarray-подобного объекта с типом данных float (например, dask.Array) и целочисленный dtype вызывает исключение вместо приведения, как мы бы сделали с np.ndarray (GH 40110)

  • Ошибка в Float64Index.astype() к беззнаковому целочисленному типу данных, некорректно приводя к np.int64 тип данных (GH 45309)

  • Ошибка в Series.astype() и DataFrame.astype() при преобразовании из типа данных с плавающей запятой в беззнаковый целочисленный тип данных не удавалось вызвать ошибку при наличии отрицательных значений (GH 45151)

  • Ошибка в array() с FloatingDtype и значения, содержащие строки, преобразуемые в float, некорректно вызывают (GH 45424)

  • Ошибка при сравнении строковых и datetime64ns объектов, вызывающая OverflowError исключение. (GH 45506)

  • Ошибка в метаклассе общих абстрактных типов данных, вызывающая DataFrame.apply() и Series.apply() вызывать для встроенной функции type (GH 46684)

  • Ошибка в DataFrame.to_records() возвращая несогласованные типы numpy, если индекс был MultiIndex (GH 47263)

  • Ошибка в DataFrame.to_dict() для orient="list" или orient="index" не возвращал нативные типы (GH 46751)

  • Ошибка в DataFrame.apply() который возвращает DataFrame вместо Series при применении к пустому DataFrame и axis=1 (GH 39111)

  • Ошибка при определении dtype из итерируемого объекта, который является не NumPy ndarray состоящий из всех скаляров NumPy беззнаковых целых чисел не приводил к беззнаковому целочисленному типу данных (GH 47294)

  • Ошибка в DataFrame.eval() когда объекты pandas (например, 'Timestamp') были именами столбцов (GH 44603)

Строки#

  • Ошибка в str.startswith() и str.endswith() при использовании других рядов в качестве параметра _pat_. Теперь вызывает TypeError (GH 3485)

  • Ошибка в Series.str.zfill() когда строки содержат ведущие знаки, заполнение '0' перед знаком, а не после, как str.zfill из стандартной библиотеки (GH 20868)

Interval#

  • Ошибка в IntervalArray.__setitem__() при установке np.nan в массив с целочисленной поддержкой, вызывая ValueError вместо TypeError (GH 45484)

  • Ошибка в IntervalDtype при использовании datetime64[ns, tz] в качестве строки типа данных (GH 46999)

Индексирование#

  • Ошибка в DataFrame.iloc() где индексация одной строки на DataFrame с одним столбцом ExtensionDtype давал копию вместо представления на исходных данных (GH 45241)

  • Ошибка в DataFrame.__getitem__() возвращение копии, когда DataFrame имеет дублированные столбцы, даже если выбран уникальный столбец (GH 45316, GH 41062)

  • Ошибка в Series.align() не создает MultiIndex с объединением уровней, когда пересечения обоих MultiIndex идентичны (GH 45224)

  • Ошибка при установке значения NA (None или np.nan) в Series с целочисленной основой IntervalDtype неправильное приведение к типу object вместо float-based IntervalDtype (GH 45568)

  • Ошибка при установке значений в ExtensionDtype столбец с df.iloc[:, i] = values с values имеющий тот же dtype, что и df.iloc[:, i] неправильная вставка нового массива вместо установки на месте (GH 33457)

  • Ошибка в Series.__setitem__() с нецелым Index при использовании целочисленного ключа для установки значения, которое не может быть установлено на месте, где ValueError было вызвано вместо приведения к общему dtype (GH 45070)

  • Ошибка в DataFrame.loc() не преобразуя типы None to NA при установке значения в виде списка в DataFrame (GH 47987)

  • Ошибка в Series.__setitem__() при установке несовместимых значений в PeriodDtype или IntervalDtype Series вызывающая исключение при индексировании с булевой маской, но приводящая при индексировании с другими эквивалентными индексаторами; теперь они последовательно приводят, вместе с Series.mask() и Series.where() (GH 45768)

  • Ошибка в DataFrame.where() с несколькими столбцами с datetime-подобными типами данных, неспособными понизить результаты, согласованными с другими типами данных (GH 45837)

  • Ошибка в isin() повышение типа до float64 с беззнаковым целочисленным dtype и list-like аргументом без указания dtype (GH 46485)

  • Ошибка в Series.loc.__setitem__() и Series.loc.__getitem__() не вызывает исключение при использовании нескольких ключей без использования MultiIndex (GH 13831)

  • Ошибка в Index.reindex() вызов AssertionError когда level был указан, но не MultiIndex был задан; уровень теперь игнорируется (GH 35132)

  • Ошибка при установке значения, слишком большого для Series dtype не удается привести к общему типу (GH 26049, GH 32878)

  • Ошибка в loc.__setitem__() обработка range ключи как позиционные вместо основанных на метках (GH 45479)

  • Ошибка в DataFrame.__setitem__() приведение типов расширенных массивов к object при установке с помощью скалярного ключа и DataFrame в качестве значения (GH 46896)

  • Ошибка в Series.__setitem__() при установке скаляра в nullable pandas dtype не вызывалось TypeError если скалярное значение не может быть преобразовано (без потерь) в nullable-тип (GH 45404)

  • Ошибка в Series.__setitem__() при установке boolean значения типа данных, содержащие NA неправильно вызывает исключение вместо приведения к boolean тип данных (GH 45462)

  • Ошибка в Series.loc() вызов исключения с булевым индексатором, содержащим NA когда Index не совпадал (GH 46551)

  • Ошибка в Series.__setitem__() где установка NA в числовой dtype Series некорректно повышал тип до object-dtype вместо обработки значения как np.nan (GH 44199)

  • Ошибка в DataFrame.loc() при установке значений в столбец и правая сторона является словарём (GH 47216)

  • Ошибка в Series.__setitem__() с datetime64[ns] dtype, полностьюFalse булева маска и несовместимое значение, неправильно приводящееся к object вместо сохранения datetime64[ns] тип данных (GH 45967)

  • Ошибка в Index.__getitem__() вызов ValueError когда индексатор имеет булевый тип данных с NA (GH 45806)

  • Ошибка в Series.__setitem__() потеря точности при увеличении Series со скаляром (GH 32346)

  • Ошибка в Series.mask() с inplace=True или установка значений с булевой маской для типов данных с малыми целыми числами некорректно вызывает ошибку (GH 45750)

  • Ошибка в DataFrame.mask() с inplace=True и ExtensionDtype столбцы неправильно вызывают (GH 45577)

  • Ошибка при получении столбца из DataFrame с индексом строк типа object с datetime-подобными значениями: результирующий Series теперь сохраняет точный индекс типа object из родительского DataFrame (GH 42950)

  • Ошибка в DataFrame.__getattribute__() вызов AttributeError если столбцы имеют "string" тип данных (GH 46185)

  • Ошибка в DataFrame.compare() возвращая все NaN столбец при сравнении типа данных расширенного массива и типа данных numpy (GH 44014)

  • Ошибка в DataFrame.where() установка неправильных значений с "boolean" маска для типа данных numpy (GH 44014)

  • Ошибка при индексации на DatetimeIndex с np.str_ ключ неправильно вызывает (GH 45580)

  • Ошибка в CategoricalIndex.get_indexer() когда индекс содержит NaN значений, в результате чего элементы, которые есть в target, но отсутствуют в индексе, будут сопоставлены с индексом элемента NaN, а не с -1 (GH 45361)

  • Ошибка при установке больших целочисленных значений в Series с float32 или float16 тип данных неправильно изменял эти значения вместо приведения к float64 тип данных (GH 45844)

  • Ошибка в Series.asof() и DataFrame.asof() неправильное преобразование результатов bool-dtype в float64 тип данных (GH 16063)

  • Ошибка в NDFrame.xs(), DataFrame.iterrows(), DataFrame.loc() и DataFrame.iloc() не всегда распространяются метаданные (GH 28283)

  • Ошибка в DataFrame.sum() min_count изменяет тип данных, если входные данные содержат NaN (GH 46947)

  • Ошибка в IntervalTree которые приводят к бесконечной рекурсии. (GH 46658)

  • Ошибка в PeriodIndex вызов AttributeError при индексировании по NA, а не помещая NaT на его место. (GH 46673)

  • Ошибка в DataFrame.at() позволило бы изменять несколько столбцов (GH 48296)

Отсутствует#

  • Ошибка в Series.fillna() и DataFrame.fillna() с downcast ключевое слово не учитывается в некоторых случаях, когда отсутствуют значения NA (GH 45423)

  • Ошибка в Series.fillna() и DataFrame.fillna() с IntervalDtype и несовместимое значение вызывает исключение вместо приведения к общему (обычно object) типу данных (GH 45796)

  • Ошибка в Series.map() не учитывая na_action аргумент, если mapper является dict или Series (GH 47527)

  • Ошибка в DataFrame.interpolate() со столбцом object-dtype, не возвращающим копию при inplace=False (GH 45791)

  • Ошибка в DataFrame.dropna() позволяет установить оба how и thresh несовместимые аргументы (GH 46575)

  • Ошибка в DataFrame.fillna() игнорируется axis когда DataFrame является единым блоком (GH 47713)

MultiIndex#

  • Ошибка в DataFrame.loc() возвращает пустой результат при срезе MultiIndex с отрицательным размером шага и ненулевыми значениями начала/остановки (GH 46156)

  • Ошибка в DataFrame.loc() вызов исключения при срезе MultiIndex с отрицательным шагом, отличным от -1 (GH 46156)

  • Ошибка в DataFrame.loc() вызов исключения при срезе MultiIndex с отрицательным шагом и срезом уровня индекса с нецелочисленной меткой (GH 46156)

  • Ошибка в Series.to_numpy() где многоиндексные Series не могли быть преобразованы в массивы numpy, когда na_value был предоставлен (GH 45774)

  • Ошибка в MultiIndex.equals не коммутативно, когда только одна сторона имеет тип данных extension array (GH 46026)

  • Ошибка в MultiIndex.from_tuples() нельзя создать Index из пустых кортежей (GH 45608)

I/O#