Версия 0.21.0 (27 октября 2017)#

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

Основные моменты включают:

  • Интеграция с Apache Parquet, включая новый верхнеуровневый read_parquet() функция и DataFrame.to_parquet() метод, см. здесь.

  • Новые пользовательские pandas.api.types.CategoricalDtype для указания категориальных данных независимо от данных, см. здесь.

  • Поведение sum и prod для полностью NaN Series/DataFrames теперь согласован и больше не зависит от того, является ли bottleneck установлен, и sum и prod на пустых Series теперь возвращают NaN вместо 0, см. здесь.

  • Исправления совместимости для pypy, см. здесь.

  • Дополнения к drop, reindex и rename API, чтобы сделать их более согласованными, см. здесь.

  • Добавление новых методов DataFrame.infer_objects (см. здесь) и GroupBy.pipe (см. здесь).

  • Индексирование списком меток, где одна или несколько меток отсутствуют, устарело и вызовет KeyError в будущей версии, см. здесь.

Проверьте Изменения API и устаревшие возможности перед обновлением.

Новые возможности#

Интеграция с форматом файлов Apache Parquet#

Интеграция с Apache Parquet, включая новый верхнеуровневый read_parquet() и DataFrame.to_parquet() метод, см. здесь (GH 15838, GH 17438).

Apache Parquet предоставляет кросс-языковой бинарный формат файла для эффективного чтения и записи фреймов данных. Parquet предназначен для точной сериализации и десериализации DataFrame s, поддерживая все типы данных pandas, включая расширенные типы данных, такие как datetime с часовыми поясами.

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

Метод infer_objects преобразование типа#

The DataFrame.infer_objects() и Series.infer_objects() методы были добавлены для выполнения вывода типа данных в столбцах типа object, заменяя часть функциональности устаревшего convert_objects метод. См. документацию здесь для получения дополнительных сведений. (GH 11221)

Этот метод выполняет только мягкие преобразования для столбцов типа object, преобразуя объекты Python в нативные типы, но не выполняет принудительных преобразований. Например:

In [1]: df = pd.DataFrame({'A': [1, 2, 3],
   ...:                    'B': np.array([1, 2, 3], dtype='object'),
   ...:                    'C': ['1', '2', '3']})
   ...: 

In [2]: df.dtypes
Out[2]: 
A     int64
B    object
C    object
Length: 3, dtype: object

In [3]: df.infer_objects().dtypes
Out[3]: 
A     int64
B     int64
C    object
Length: 3, dtype: object

Обратите внимание, что столбец 'C' не был преобразован - только скалярные числовые типы будут преобразованы в новый тип. Другие типы преобразований должны выполняться с использованием to_numeric() функция (или to_datetime(), to_timedelta()).

In [4]: df = df.infer_objects()

In [5]: df['C'] = pd.to_numeric(df['C'], errors='coerce')

In [6]: df.dtypes
Out[6]: 
A    int64
B    int64
C    int64
Length: 3, dtype: object

Улучшенные предупреждения при попытке создания столбцов#

Новые пользователи часто испытывают затруднения с взаимосвязью между операциями над столбцами и доступом к атрибутам на DataFrame экземпляры (GH 7175). Один конкретный пример этой путаницы — попытка создать новый столбец, устанавливая атрибут на DataFrame:

In [1]: df = pd.DataFrame({'one': [1., 2., 3.]})
In [2]: df.two = [4, 5, 6]

Это не вызывает явных исключений, но также не создает новый столбец:

In [3]: df
Out[3]:
    one
0  1.0
1  2.0
2  3.0

Установка спискообразной структуры данных в новый атрибут теперь вызывает UserWarning о возможности неожиданного поведения. См. Доступ к атрибутам.

Метод drop теперь также принимает ключевые слова index/columns#

The drop() метод получил index/columns ключевые слова как альтернатива указанию axis. Это аналогично поведению reindex (GH 12392).

Например:

In [7]: df = pd.DataFrame(np.arange(8).reshape(2, 4),
   ...:                   columns=['A', 'B', 'C', 'D'])
   ...: 

In [8]: df
Out[8]: 
   A  B  C  D
0  0  1  2  3
1  4  5  6  7

[2 rows x 4 columns]

In [9]: df.drop(['B', 'C'], axis=1)
Out[9]: 
   A  D
0  0  3
1  4  7

[2 rows x 2 columns]

# the following is now equivalent
In [10]: df.drop(columns=['B', 'C'])
Out[10]: 
   A  D
0  0  3
1  4  7

[2 rows x 2 columns]

Методы rename, reindex объекты возвращаются#

The DataFrame.rename() и DataFrame.reindex() методы получили параметр axis ключевое слово для указания оси для операции (GH 12392).

Вот rename:

In [11]: df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]})

In [12]: df.rename(str.lower, axis='columns')
Out[12]: 
   a  b
0  1  4
1  2  5
2  3  6

[3 rows x 2 columns]

In [13]: df.rename(id, axis='index')
Out[13]: 
                 A  B
140206724563152  1  4
140206724563184  2  5
140206724563216  3  6

[3 rows x 2 columns]

И reindex:

In [14]: df.reindex(['A', 'B', 'C'], axis='columns')
Out[14]: 
   A  B   C
0  1  4 NaN
1  2  5 NaN
2  3  6 NaN

[3 rows x 3 columns]

In [15]: df.reindex([0, 1, 3], axis='index')
Out[15]: 
     A    B
0  1.0  4.0
1  2.0  5.0
3  NaN  NaN

[3 rows x 2 columns]

Стиль “index, columns” продолжает работать как раньше.

In [16]: df.rename(index=id, columns=str.lower)
Out[16]: 
                 a  b
140206724563152  1  4
140206724563184  2  5
140206724563216  3  6

[3 rows x 2 columns]

In [17]: df.reindex(index=[0, 1, 3], columns=['A', 'B', 'C'])
Out[17]: 
     A    B   C
0  1.0  4.0 NaN
1  2.0  5.0 NaN
3  NaN  NaN NaN

[3 rows x 3 columns]

Мы высоко рекомендуется использовать именованные аргументы, чтобы избежать путаницы при использовании любого стиля.

CategoricalDtype для указания категориальных переменных#

pandas.api.types.CategoricalDtype был добавлен в публичный API и расширен для включения categories и ordered атрибуты. A CategoricalDtype может использоваться для указания набора категорий и упорядоченности массива, независимо от данных. Это может быть полезно, например, при преобразовании строковых данных в Categorical (GH 14711, GH 15078, GH 16015, GH 17643):

In [18]: from pandas.api.types import CategoricalDtype

In [19]: s = pd.Series(['a', 'b', 'c', 'a'])  # strings

In [20]: dtype = CategoricalDtype(categories=['a', 'b', 'c', 'd'], ordered=True)

In [21]: s.astype(dtype)
Out[21]: 
0    a
1    b
2    c
3    a
Length: 4, dtype: category
Categories (4, object): ['a' < 'b' < 'c' < 'd']

Одно место, которое заслуживает особого упоминания, это read_csv(). Ранее, с dtype={'col': 'category'}, возвращаемые значения и категории всегда будут строками.

In [22]: data = 'A,B\na,1\nb,2\nc,3'

In [23]: pd.read_csv(StringIO(data), dtype={'B': 'category'}).B.cat.categories
Out[23]: Index(['1', '2', '3'], dtype='object')

Обратите внимание на тип данных "object".

С помощью CategoricalDtype всех числовых, дата-временных или временных интервалов, мы можем автоматически преобразовать к правильному типу

In [24]: dtype = {'B': CategoricalDtype([1, 2, 3])}

In [25]: pd.read_csv(StringIO(data), dtype=dtype).B.cat.categories
Out[25]: Index([1, 2, 3], dtype='int64')

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

The .dtype свойства Categorical, CategoricalIndex или Series с категориальным типом теперь возвращает экземпляр CategoricalDtype. Хотя представление изменилось, str(CategoricalDtype()) всё ещё строка 'category'. Мы воспользуемся этим моментом, чтобы напомнить пользователям, что предпочтительный способ обнаружения категориальных данных — использовать pandas.api.types.is_categorical_dtype(), а не str(dtype) == 'category'.

См. CategoricalDtype docs подробнее.

GroupBy объекты теперь имеют pipe метод#

GroupBy объекты теперь имеют pipe метод, аналогичный методу на DataFrame и Series, которые позволяют функциям принимать GroupBy должен быть составлен в чистом, читаемом синтаксисе. (GH 17871)

Для конкретного примера по объединению .groupby и .pipe , представьте DataFrame с колонками для магазинов, продуктов, выручки и проданного количества. Мы хотели бы выполнить групповой расчет цены (т.е. выручка/количество) на магазин и на продукт. Мы могли бы сделать это в несколько шагов, но выражение через конвейер может сделать код более читаемым.

Сначала мы устанавливаем данные:

In [26]: import numpy as np

In [27]: n = 1000

In [28]: df = pd.DataFrame({'Store': np.random.choice(['Store_1', 'Store_2'], n),
   ....:                    'Product': np.random.choice(['Product_1',
   ....:                                                 'Product_2',
   ....:                                                 'Product_3'
   ....:                                                 ], n),
   ....:                    'Revenue': (np.random.random(n) * 50 + 10).round(2),
   ....:                    'Quantity': np.random.randint(1, 10, size=n)})
   ....: 

In [29]: df.head(2)
Out[29]: 
     Store    Product  Revenue  Quantity
0  Store_2  Product_2    32.09         7
1  Store_1  Product_3    14.20         1

[2 rows x 4 columns]

Теперь, чтобы найти цены по магазину/продукту, мы можем просто сделать:

In [30]: (df.groupby(['Store', 'Product'])
   ....:    .pipe(lambda grp: grp.Revenue.sum() / grp.Quantity.sum())
   ....:    .unstack().round(2))
   ....: 
Out[30]: 
Product  Product_1  Product_2  Product_3
Store                                   
Store_1       6.73       6.72       7.14
Store_2       7.59       6.98       7.23

[2 rows x 3 columns]

См. документация подробнее.

Categorical.rename_categories принимает словарь#

rename_categories() теперь принимает аргумент типа dict для new_categories. Предыдущие категории ищутся в ключах словаря и заменяются, если найдены. Поведение отсутствующих и лишних ключей такое же, как в DataFrame.rename().

In [31]: c = pd.Categorical(['a', 'a', 'b'])

In [32]: c.rename_categories({"a": "eh", "b": "bee"})
Out[32]: 
['eh', 'eh', 'bee']
Categories (2, object): ['eh', 'bee']

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

Чтобы помочь с обновлением pandas, rename_categories обрабатывает Series как list-like. Обычно Series считаются dict-like (например, в .rename, .map). В будущей версии pandas rename_categories изменится, чтобы рассматривать их как словареподобные. Следуйте рекомендациям предупреждения для написания устойчивого к будущим изменениям кода.

In [33]: c.rename_categories(pd.Series([0, 1], index=['a', 'c']))
FutureWarning: Treating Series 'new_categories' as a list-like and using the values.
In a future version, 'rename_categories' will treat Series like a dictionary.
For dict-like, use 'new_categories.to_dict()'
For list-like, use 'new_categories.values'.
Out[33]:
[0, 0, 1]
Categories (2, int64): [0, 1]

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

Новые функции или методы#

  • Resampler.nearest() добавлена для поддержки апсемплинга методом ближайших соседей (GH 17496).

  • Index добавлена поддержка для to_frame метод (GH 15230).

Новые ключевые слова#

  • Добавлен skipna параметр для infer_dtype() для поддержки вывода типов при наличии пропущенных значений (GH 17059).

  • Series.to_dict() и DataFrame.to_dict() теперь поддерживают into ключевое слово, которое позволяет указать collections.Mapping подкласс, который вы хотите получить. По умолчанию dict, что обратно совместимо. (GH 16122)

  • Series.set_axis() и DataFrame.set_axis() теперь поддерживают inplace параметр. (GH 14636)

  • Series.to_pickle() и DataFrame.to_pickle() получили protocol параметр (GH 16252). По умолчанию этот параметр установлен в HIGHEST_PROTOCOL

  • read_feather() получил nthreads параметр для многопоточных операций (GH 16359)

  • DataFrame.clip() и Series.clip() получили inplace аргумент. (GH 15388)

  • crosstab() получил margins_name параметр для определения имени строки / столбца, который будет содержать итоги, когда margins=True. (GH 15972)

  • read_json() теперь принимает chunksize параметр, который можно использовать, когда lines=True. Если chunksize Выполнить слияние по ключевому расстоянию. chunksize строк с каждой итерацией. (GH 17048)

  • read_json() и to_json() теперь принимает compression аргумент, который позволяет им прозрачно обрабатывать сжатые файлы. (GH 17798)

Различные улучшения#

  • Улучшено время импорта pandas примерно в 2.25 раза. (GH 16764)

  • Поддержка PEP 519 – Добавление протокола файловой системы пути для большинства читателей (например, read_csv()) и писатели (например, DataFrame.to_csv()) (GH 13823).

  • Добавлен __fspath__ метод для pd.HDFStore, pd.ExcelFile, и pd.ExcelWriter для правильной работы с протоколом пути файловой системы (GH 13823).

  • The validate аргумент для merge() теперь проверяет, является ли слияние один-к-одному, один-ко-многим, многие-к-одному или многие-ко-многим. Если слияние не соответствует указанному типу, вызывается исключение типа MergeError будет вызвано. Подробнее см. здесь (GH 16270)

  • Добавлена поддержка для PEP 518 (pyproject.toml) в систему сборки (GH 16745)

  • RangeIndex.append() теперь возвращает RangeIndex объект, когда это возможно (GH 16212)

  • Series.rename_axis() и DataFrame.rename_axis() с inplace=True теперь возвращает None при переименовании оси на месте. (GH 15704)

  • api.types.infer_dtype() теперь определяет десятичные знаки. (GH 15690)

  • DataFrame.select_dtypes() теперь принимает скалярные значения для include/exclude, а также значения в виде списка. (GH 16855)

  • date_range() теперь принимает 'YS' в дополнение к 'AS' как псевдоним для начала года. (GH 9313)

  • date_range() теперь принимает 'Y' в дополнение к 'A' как псевдоним конца года. (GH 9313)

  • DataFrame.add_prefix() и DataFrame.add_suffix() теперь принимают строки, содержащие символ '%'. (GH 17151)

  • Методы чтения/записи, определяющие сжатие (read_csv(), read_table(), read_pickle(), и to_pickle()) теперь может выводить из объектов, подобных пути, таких как pathlib.Path. (GH 17206)

  • read_sas() теперь распознает гораздо больше наиболее часто используемых форматов дат (datetime) в файлах SAS7BDAT. (GH 15871)

  • DataFrame.items() и Series.items() теперь присутствуют как в Python 2, так и в 3 и являются ленивыми во всех случаях. (GH 13918, GH 17213)

  • pandas.io.formats.style.Styler.where() был реализован для удобства pandas.io.formats.style.Styler.applymap(). (GH 17474)

  • MultiIndex.is_monotonic_decreasing() была реализована. Ранее возвращалось False во всех случаях. (GH 16554)

  • read_excel() вызывает ImportError с лучшим сообщением, если xlrd не установлен. (GH 17613)

  • DataFrame.assign() сохранит исходный порядок **kwargs для пользователей Python 3.6+ вместо сортировки имён столбцов. (GH 14207)

  • Series.reindex(), DataFrame.reindex(), Index.get_indexer() теперь поддерживают аргумент в виде списка для tolerance. (GH 17367)

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

Минимальные версии зависимостей увеличены#

Мы обновили минимальные поддерживаемые версии зависимостей (GH 15206, GH 15543, GH 15214). Если установлено, теперь требуется:

Пакет

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

Обязательно

Numpy

1.9.0

X

Matplotlib

1.4.3

Scipy

0.14.0

Bottleneck

1.0.0

Кроме того, поддержка Python 3.4 была прекращена (GH 15251).

Сумма/произведение всех-NaN или пустых Series/DataFrames теперь последовательно возвращает NaN#

Примечание

Описанные здесь изменения были частично отменены. См. v0.22.0 Whatsnew подробнее.

Поведение sum и prod на полностью NaN Series/DataFrames больше не зависит от того, bottleneck установлен, и возвращаемое значение sum и prod на пустой Series изменилось (GH 9422, GH 15507).

Вызов sum или prod на пустом или полностьюNaN Series, или столбцы DataFrame, приведет к NaN. См. документация.

In [33]: s = pd.Series([np.nan])

Ранее БЕЗ bottleneck установлено:

In [2]: s.sum()
Out[2]: np.nan

Ранее WITH bottleneck:

In [2]: s.sum()
Out[2]: 0.0

Новое поведение, независимо от установки bottleneck:

In [34]: s.sum()
Out[34]: 0.0

Обратите внимание, что это также изменяет сумму пустого Series. Ранее это всегда возвращало 0 независимо от bottleneck установка:

In [1]: pd.Series([]).sum()
Out[1]: 0

но для согласованности со случаем всех значений NaN это было изменено на возврат 0:

In [2]: pd.Series([]).sum()
Out[2]: 0

Индексирование списком с отсутствующими метками устарело#

Ранее выбор по списку меток, где одна или несколько меток отсутствовали, всегда завершался успешно, возвращая NaN для отсутствующих меток. Теперь будет показано FutureWarning. В будущем это вызовет KeyError (GH 15747). Это предупреждение сработает на DataFrame или Series для использования .loc[] или [[]] при передаче списка меток с хотя бы одной отсутствующей меткой.

In [35]: s = pd.Series([1, 2, 3])

In [36]: s
Out[36]: 
0    1
1    2
2    3
Length: 3, dtype: int64

Предыдущее поведение

In [4]: s.loc[[1, 2, 3]]
Out[4]:
1    2.0
2    3.0
3    NaN
dtype: float64

Текущее поведение

In [4]: s.loc[[1, 2, 3]]
Passing list-likes to .loc or [] with any missing label will raise
KeyError in the future, you can use .reindex() as an alternative.

See the documentation here:
https://pandas.pydata.org/pandas-docs/stable/indexing.html#deprecate-loc-reindex-listlike

Out[4]:
1    2.0
2    3.0
3    NaN
dtype: float64

Идиоматический способ выбора потенциально не найденных элементов — через .reindex()

In [37]: s.reindex([1, 2, 3])
Out[37]: 
1    2.0
2    3.0
3    NaN
Length: 3, dtype: float64

Выбор со всеми найденными ключами остается неизменным.

In [38]: s.loc[[1, 2]]
Out[38]: 
1    2
2    3
Length: 2, dtype: int64

Изменения в наименовании NA#

Для повышения согласованности API pandas мы добавили дополнительные функции верхнего уровня isna() и notna() которые являются алиасами для isnull() и notnull(). Схема именования теперь более согласована с методами, такими как .dropna() и .fillna(). Кроме того, во всех случаях, когда .isnull() и .notnull() методы определены, они имеют дополнительные методы с именами .isna() и .notna(), они включены для классов Categorical, Index, Series, и DataFrame. (GH 15001).

Опция конфигурации pd.options.mode.use_inf_as_null устарел, и pd.options.mode.use_inf_as_na добавлен в качестве замены.

Итерация по Series/Index теперь возвращает скаляры Python#

Ранее при использовании определенных методов итерации для Series с типом данных int или float, вы получите numpy скаляр, например, np.int64, а не Python int. Проблема (GH 10904) исправил это для Series.tolist() и list(Series). Это изменение делает все методы итерации согласованными, в частности, для __iter__() и .map(); обратите внимание, что это влияет только на типы int/float. (GH 13236, GH 13258, GH 14216).

In [39]: s = pd.Series([1, 2, 3])

In [40]: s
Out[40]: 
0    1
1    2
2    3
Length: 3, dtype: int64

Ранее:

In [2]: type(list(s)[0])
Out[2]: numpy.int64

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

In [41]: type(list(s)[0])
Out[41]: int

Кроме того, теперь будет корректно упаковывать результаты итерации для DataFrame.to_dict() также.

In [42]: d = {'a': [1], 'b': ['b']}

In [43]: df = pd.DataFrame(d)

Ранее:

In [8]: type(df.to_dict()['a'][0])
Out[8]: numpy.int64

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

In [44]: type(df.to_dict()['a'][0])
Out[44]: int

Индексирование с булевым индексом#

Ранее при передаче логического значения Index to .loc, если индекс Series/DataFrame имел boolean метки, вы получите выбор на основе метки, потенциально дублируя результирующие метки, а не выбор булевой индексации (где True выбирает элементы), это было несоответствием тому, как индексировался булев массив numpy. Новое поведение заключается в том, чтобы действовать как индексатор булева массива numpy. (GH 17738)

Предыдущее поведение:

In [45]: s = pd.Series([1, 2, 3], index=[False, True, False])

In [46]: s
Out[46]: 
False    1
True     2
False    3
Length: 3, dtype: int64
In [59]: s.loc[pd.Index([True, False, True])]
Out[59]:
True     2
False    1
False    3
True     2
dtype: int64

Текущее поведение

In [47]: s.loc[pd.Index([True, False, True])]
Out[47]: 
False    1
False    3
Length: 2, dtype: int64

Кроме того, ранее если у вас был индекс, который не был числовым (например, строки), то логический Index вызывал бы KeyError. Теперь это будет рассматриваться как булевый индексатор.

Предыдущее поведение:

In [48]: s = pd.Series([1, 2, 3], index=['a', 'b', 'c'])

In [49]: s
Out[49]: 
a    1
b    2
c    3
Length: 3, dtype: int64
In [39]: s.loc[pd.Index([True, False, True])]
KeyError: "None of [Index([True, False, True], dtype='object')] are in the [index]"

Текущее поведение

In [50]: s.loc[pd.Index([True, False, True])]
Out[50]: 
a    1
c    3
Length: 2, dtype: int64

PeriodIndex ресемплинг#

В предыдущих версиях pandas, ресемплирование Series/DataFrame индексированный PeriodIndex возвращал DatetimeIndex в некоторых случаях (GH 12884). Передискретизация на умноженную частоту теперь возвращает PeriodIndex (GH 15944). В качестве небольшого улучшения, ресемплинг PeriodIndex теперь может обрабатывать NaT значения (GH 13224)

Предыдущее поведение:

In [1]: pi = pd.period_range('2017-01', periods=12, freq='M')

In [2]: s = pd.Series(np.arange(12), index=pi)

In [3]: resampled = s.resample('2Q').mean()

In [4]: resampled
Out[4]:
2017-03-31     1.0
2017-09-30     5.5
2018-03-31    10.0
Freq: 2Q-DEC, dtype: float64

In [5]: resampled.index
Out[5]: DatetimeIndex(['2017-03-31', '2017-09-30', '2018-03-31'], dtype='datetime64[ns]', freq='2Q-DEC')

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

In [51]: pi = pd.period_range('2017-01', periods=12, freq='M')

In [52]: s = pd.Series(np.arange(12), index=pi)

In [53]: resampled = s.resample('2Q').mean()

In [54]: resampled
Out[54]: 
2017Q1    2.5
2017Q3    8.5
Freq: 2Q-DEC, Length: 2, dtype: float64

In [55]: resampled.index
Out[55]: PeriodIndex(['2017Q1', '2017Q3'], dtype='period[2Q-DEC]')

Повышение частоты дискретизации и вызов .ohlc() ранее возвращал Series, практически идентично вызову .asfreq(). OHLC апсемплинг теперь возвращает DataFrame со столбцами open, high, low и close (GH 13083). Это согласуется с понижающей дискретизацией и DatetimeIndex поведение.

Предыдущее поведение:

In [1]: pi = pd.period_range(start='2000-01-01', freq='D', periods=10)

In [2]: s = pd.Series(np.arange(10), index=pi)

In [3]: s.resample('H').ohlc()
Out[3]:
2000-01-01 00:00    0.0
                ...
2000-01-10 23:00    NaN
Freq: H, Length: 240, dtype: float64

In [4]: s.resample('M').ohlc()
Out[4]:
         open  high  low  close
2000-01     0     9    0      9

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

In [56]: pi = pd.period_range(start='2000-01-01', freq='D', periods=10)

In [57]: s = pd.Series(np.arange(10), index=pi)

In [58]: s.resample('H').ohlc()
Out[58]:
                  open  high  low  close
2000-01-01 00:00   0.0   0.0  0.0    0.0
2000-01-01 01:00   NaN   NaN  NaN    NaN
2000-01-01 02:00   NaN   NaN  NaN    NaN
2000-01-01 03:00   NaN   NaN  NaN    NaN
2000-01-01 04:00   NaN   NaN  NaN    NaN
...                ...   ...  ...    ...
2000-01-10 19:00   NaN   NaN  NaN    NaN
2000-01-10 20:00   NaN   NaN  NaN    NaN
2000-01-10 21:00   NaN   NaN  NaN    NaN
2000-01-10 22:00   NaN   NaN  NaN    NaN
2000-01-10 23:00   NaN   NaN  NaN    NaN

[240 rows x 4 columns]

In [59]: s.resample('M').ohlc()
Out[59]:
         open  high  low  close
2000-01     0     9    0      9

[1 rows x 4 columns]

Улучшенная обработка ошибок при присваивании элементов в pd.eval#

eval() теперь вызовет ValueError когда присваивание элементов работает некорректно, или указаны операции inplace, но в выражении нет присваивания элементов (GH 16732)

In [56]: arr = np.array([1, 2, 3])

Ранее, если вы пытались выполнить следующее выражение, вы получали не очень полезное сообщение об ошибке:

In [3]: pd.eval("a = 1 + 2", target=arr, inplace=True)
...
IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`)
and integer or boolean arrays are valid indices

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

In [3]: pd.eval("a = 1 + 2", target=arr, inplace=True)
...
ValueError: Cannot assign expression output to target

Также ранее была возможность вычислять выражения на месте, даже если не было присваивания элемента:

In [4]: pd.eval("1 + 2", target=arr, inplace=True)
Out[4]: 3

Однако этот ввод не имеет особого смысла, потому что вывод не присваивается цели. Теперь ValueError будет вызвано, когда такой ввод передается:

In [4]: pd.eval("1 + 2", target=arr, inplace=True)
...
ValueError: Cannot operate inplace if there is no assignment

Преобразования типов данных#

Ранее присваивания, .where() и .fillna() с bool присваивание будет приводить к тому же типу (например, int / float) или вызывать ошибку для датоподобных значений. Теперь они будут сохранять логические значения с object типы данных. (GH 16821).

In [57]: s = pd.Series([1, 2, 3])
In [5]: s[1] = True

In [6]: s
Out[6]:
0    1
1    1
2    3
dtype: int64

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

In [7]: s[1] = True

In [8]: s
Out[8]:
0       1
1    True
2       3
Length: 3, dtype: object

Ранее присваивание датеподобному значению не-датеподобного приводило к преобразованию не-датеподобного элемента при присваивании (GH 14145).

In [58]: s = pd.Series([pd.Timestamp('2011-01-01'), pd.Timestamp('2012-01-01')])
In [1]: s[1] = 1

In [2]: s
Out[2]:
0   2011-01-01 00:00:00.000000000
1   1970-01-01 00:00:00.000000001
dtype: datetime64[ns]

Теперь они приводятся к object тип данных.

In [1]: s[1] = 1

In [2]: s
Out[2]:
0    2011-01-01 00:00:00
1                      1
dtype: object
  • Несогласованное поведение в .where() с объектами типа datetime, которые вызывали исключение вместо приведения к object (GH 16402)

  • Ошибка в присваивании против int64 данные с np.ndarray с float64 dtype может сохранять int64 тип данных (GH 14001)

Конструктор MultiIndex с одним уровнем#

The MultiIndex конструкторы больше не сжимают MultiIndex со всеми уровнями длины один до обычного Index. Это затрагивает все MultiIndex конструкторы. (GH 17178)

Предыдущее поведение:

In [2]: pd.MultiIndex.from_tuples([('a',), ('b',)])
Out[2]: Index(['a', 'b'], dtype='object')

Уровни длины 1 больше не обрабатываются особым образом. Они ведут себя точно так же, как если бы у вас были уровни длины 2+, поэтому MultiIndex всегда возвращается из всех MultiIndex конструкторы:

In [59]: pd.MultiIndex.from_tuples([('a',), ('b',)])
Out[59]: 
MultiIndex([('a',),
            ('b',)],
           )

Локализация UTC с Series#

Ранее, to_datetime() не локализовал дату и время Series данные, когда utc=True был передан. Теперь, to_datetime() будет корректно локализовать Series с datetime64[ns, UTC] dtype должен быть согласован с тем, как списко-подобные и Index данные обрабатываются. (GH 6415).

Предыдущее поведение

In [60]: s = pd.Series(['20130101 00:00:00'] * 3)
In [12]: pd.to_datetime(s, utc=True)
Out[12]:
0   2013-01-01
1   2013-01-01
2   2013-01-01
dtype: datetime64[ns]

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

In [61]: pd.to_datetime(s, utc=True)
Out[61]: 
0   2013-01-01 00:00:00+00:00
1   2013-01-01 00:00:00+00:00
2   2013-01-01 00:00:00+00:00
Length: 3, dtype: datetime64[ns, UTC]

Кроме того, DataFrames со столбцами даты и времени, которые были разобраны с помощью read_sql_table() и read_sql_query() также будет локализован в UTC только если исходные SQL-столбцы были столбцами datetime с учетом часового пояса.

Согласованность функций диапазона#

В предыдущих версиях были некоторые несоответствия между различными функциями диапазона: date_range(), bdate_range(), period_range(), timedelta_range(), и interval_range(). (GH 17471).

Одно из несоответствий в поведении возникало, когда start, end и period параметры были все указаны, что потенциально могло привести к неоднозначным диапазонам. Когда все три параметра были переданы, interval_range игнорировал period Можно хранить подкласс period_range игнорировал end параметр, а другие функции диапазона вызывали исключение. Для обеспечения согласованности среди функций диапазона и избежания потенциально неоднозначных диапазонов, interval_range и period_range теперь будет вызывать исключение, когда переданы все три параметра.

Предыдущее поведение:

 In [2]: pd.interval_range(start=0, end=4, periods=6)
 Out[2]:
 IntervalIndex([(0, 1], (1, 2], (2, 3]]
               closed='right',
               dtype='interval[int64]')

In [3]: pd.period_range(start='2017Q1', end='2017Q4', periods=6, freq='Q')
Out[3]: PeriodIndex(['2017Q1', '2017Q2', '2017Q3', '2017Q4', '2018Q1', '2018Q2'], dtype='period[Q-DEC]', freq='Q-DEC')

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

In [2]: pd.interval_range(start=0, end=4, periods=6)
---------------------------------------------------------------------------
ValueError: Of the three parameters: start, end, and periods, exactly two must be specified

In [3]: pd.period_range(start='2017Q1', end='2017Q4', periods=6, freq='Q')
---------------------------------------------------------------------------
ValueError: Of the three parameters: start, end, and periods, exactly two must be specified

Кроме того, параметр endpoint end не включался в интервалы, созданные interval_range. Однако все остальные функции диапазона включают end в их выводе. Для обеспечения согласованности среди функций диапазона, interval_range теперь будет включать end как правый конец конечного интервала, за исключением случаев, когда freq указан таким образом, чтобы пропускать end.

Предыдущее поведение:

In [4]: pd.interval_range(start=0, end=4)
Out[4]:
IntervalIndex([(0, 1], (1, 2], (2, 3]]
              closed='right',
              dtype='interval[int64]')

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

In [62]: pd.interval_range(start=0, end=4)
Out[62]: IntervalIndex([(0, 1], (1, 2], (2, 3], (3, 4]], dtype='interval[int64, right]')

Нет автоматических конвертеров Matplotlib#

pandas больше не регистрирует наши date, time, datetime, datetime64, и Period конвертеры с matplotlib при импорте pandas. Методы построения графиков matplotlib (plt.plot, ax.plot, …), не будет красиво форматировать ось x для DatetimeIndex или PeriodIndex значения. Вы должны явно зарегистрировать эти методы:

встроенный в pandas Series.plot и DataFrame.plot будет зарегистрировать эти конвертеры при первом использовании (GH 17710).

Примечание

Это изменение было временно отменено в pandas 0.21.1, подробнее см. здесь.

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

  • Конструктор Categorical больше не принимает скаляр для categories ключевое слово. (GH 16022)

  • Доступ к несуществующему атрибуту на закрытом HDFStore теперь будет вызывать AttributeError а не ClosedFileError (GH 16301)

  • read_csv() теперь выдает UserWarning если names параметр содержит дубликаты (GH 17095)

  • read_csv() теперь обрабатывает 'null' и 'n/a' строки как пропущенные значения по умолчанию (GH 16471, GH 16078)

  • pandas.HDFStoreстроковое представление теперь работает быстрее и менее детализировано. Для прежнего поведения используйте pandas.HDFStore.info(). (GH 16503).

  • Настройки сжатия по умолчанию в HDF хранилищах теперь соответствуют стандартам pytables. По умолчанию сжатие отсутствует, и если complib отсутствует и complevel > 0 zlib используется (GH 15943)

  • Index.get_indexer_non_unique() теперь возвращает индекс ndarray, а не Index; это согласуется с Index.get_indexer() (GH 16819)

  • Удалён @slow декоратор из pandas._testing, что вызывало проблемы для некоторых тестовых наборов зависимых пакетов. Используйте @pytest.mark.slow вместо этого, что достигает того же (GH 16850)

  • Перемещено определение MergeError в pandas.errors модуль.

  • Сигнатура Series.set_axis() и DataFrame.set_axis() было изменено с set_axis(axis, labels) to set_axis(labels, axis=0), для согласованности с остальным API. Старая сигнатура устарела и будет показывать FutureWarning (GH 14636)

  • Series.argmin() и Series.argmax() теперь вызовет TypeError при использовании с object типы данных, а не ValueError (GH 13595)

  • Period теперь неизменяем и будет вызывать AttributeError когда пользователь пытается присвоить новое значение ordinal или freq атрибуты (GH 17116).

  • to_datetime() при передаче с учетом часового пояса origin= kwarg теперь будет вызывать более информативное ValueError а не TypeError (GH 16842)

  • to_datetime() теперь вызывает ValueError когда формат включает %W или %U без включения дня недели и календарного года (GH 16774)

  • Переименован нефункциональный index to index_col в read_stata() для улучшения согласованности API (GH 16342)

  • Ошибка в DataFrame.drop() вызвал булевы метки False и True должны рассматриваться как метки 0 и 1 соответственно при удалении индексов из числового индекса. Теперь это вызовет ValueError (GH 16877)

  • Ограниченные аргументы ключевых слов DateOffset. Ранее, DateOffset подклассы разрешали произвольные аргументы ключевых слов, что могло привести к неожиданному поведению. Теперь будут приниматься только допустимые аргументы. (GH 17176).

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

  • DataFrame.from_csv() и Series.from_csv() устарели в пользу read_csv() (GH 4191)

  • read_excel() устарел sheetname в пользу sheet_name для согласованности с .to_excel() (GH 10559).

  • read_excel() устарел parse_cols в пользу usecols для согласованности с read_csv() (GH 4988)

  • read_csv() устарел tupleize_cols аргумент. Кортежи столбцов всегда будут преобразованы в MultiIndex (GH 17060)

  • DataFrame.to_csv() устарел tupleize_cols аргумент. Столбцы MultiIndex всегда будут записываться как строки в CSV-файле (GH 17060)

  • The convert параметр был объявлен устаревшим в .take() метод, так как он не соблюдался (GH 16948)

  • pd.options.html.border был объявлен устаревшим в пользу pd.options.display.html.border (GH 15793).

  • SeriesGroupBy.nth() устарел True в пользу 'all' для его kwarg dropna (GH 11038).

  • DataFrame.as_blocks() устарел, так как это раскрывает внутреннюю реализацию (GH 17302)

  • pd.TimeGrouper устарел в пользу pandas.Grouper (GH 16747)

  • cdate_range был объявлен устаревшим в пользу bdate_range(), который получил weekmask и holidays параметры для построения пользовательских диапазонов дат с частотой. См. документация для дополнительных деталей (GH 17596)

  • передача categories или ordered kwargs на Series.astype() устарел, в пользу передачи CategoricalDtype (GH 17636)

  • .get_value и .set_value на Series, DataFrame, Panel, SparseSeries, и SparseDataFrame устарели в пользу использования .iat[] или .at[] аксессоры (GH 15269)

  • Передача несуществующего столбца в .to_excel(..., columns=) устарело и вызовет KeyError в будущем (GH 17295)

  • raise_on_error параметр для Series.where(), Series.mask(), DataFrame.where(), DataFrame.mask() устарел, в пользу errors= (GH 14968)

  • Используя DataFrame.rename_axis() и Series.rename_axis() изменить индекс или столбец метки теперь устарел в пользу использования .rename. rename_axis может по-прежнему использоваться для изменения имени индекса или столбцов (GH 17833).

  • reindex_axis() был объявлен устаревшим в пользу reindex(). См. здесь для получения дополнительной информации (GH 17833).

Series.select и DataFrame.select#

The Series.select() и DataFrame.select() методы устарели в пользу использования df.loc[labels.map(crit)] (GH 12401)

In [63]: df = pd.DataFrame({'A': [1, 2, 3]}, index=['foo', 'bar', 'baz'])
In [3]: df.select(lambda x: x in ['bar', 'baz'])
FutureWarning: select is deprecated and will be removed in a future release. You can use .loc[crit] as a replacement
Out[3]:
     A
bar  2
baz  3
In [64]: df.loc[df.index.map(lambda x: x in ['bar', 'baz'])]
Out[64]: 
     A
bar  2
baz  3

[2 rows x 1 columns]

Series.argmax и Series.argmin#

Поведение Series.argmax() и Series.argmin() устарели в пользу Series.idxmax() и Series.idxmin(), соответственно (GH 16830).

Для совместимости с массивами NumPy, pd.Series реализует argmax и argmin. Начиная с pandas 0.13.0, argmax было псевдонимом для pandas.Series.idxmax(), и argmin было псевдонимом для pandas.Series.idxmin(). Они возвращают метка максимума или минимума, а не позиция.

Мы устарели текущее поведение Series.argmax и Series.argmin. Использование любого из них вызовет FutureWarning. Используйте Series.idxmax() если нужна метка максимума. Используйте Series.values.argmax() если вам нужна позиция максимума. Аналогично для минимума. В будущем релизе Series.argmax и Series.argmin вернет позицию максимального или минимального значения.

Удаление устаревших функций/изменений предыдущих версий#

  • read_excel() удалил has_index_names параметр (GH 10967)

  • The pd.options.display.height конфигурация была удалена (GH 3663)

  • The pd.options.display.line_width конфигурация была удалена (GH 2881)

  • The pd.options.display.mpl_style конфигурация была удалена (GH 12190)

  • Index удалил .sym_diff() метод в пользу .symmetric_difference() (GH 12591)

  • Categorical удалил .order() и .sort() методы в пользу .sort_values() (GH 12882)

  • eval() и DataFrame.eval() изменили значение по умолчанию для inplace из None to False (GH 11149)

  • Функция get_offset_name был удалён в пользу .freqstr атрибут для смещения (GH 11834)

  • pandas больше не проверяет совместимость с hdf5-файлами, созданными в pandas < 0.11 (GH 17404).

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

  • Улучшена производительность создания экземпляра SparseDataFrame (GH 16773)

  • Series.dt больше не выполняет определение частоты, что дает значительное ускорение при доступе к атрибуту (GH 17210)

  • Улучшена производительность set_categories() не материализуя значения (GH 17508)

  • Timestamp.microsecond больше не пересчитывается при доступе к атрибуту (GH 17331)

  • Улучшена производительность CategoricalIndex для данных, которые уже имеют категориальный dtype (GH 17513)

  • Улучшена производительность RangeIndex.min() и RangeIndex.max() используя RangeIndex свойства для выполнения вычислений (GH 17607)

Изменения в документации#

  • Несколько NaT строки документации методов (например, NaT.ctime()) были некорректными (GH 17327)

  • Из документации удалены ссылки на версии < v0.17 и проведена очистка (GH 17442, GH 17442, GH 17404 & GH 17504)

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

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

  • Ошибка при присваивании для данных типа datetime с int может некорректно преобразовываться в дату-время (GH 14145)

  • Ошибка в присваивании против int64 данные с np.ndarray с float64 dtype может сохранять int64 тип данных (GH 14001)

  • Исправлен возвращаемый тип IntervalIndex.is_non_overlapping_monotonic должен быть Python bool для согласованности с аналогичными атрибутами/методами. Ранее возвращал numpy.bool_. (GH 17237)

  • Ошибка в IntervalIndex.is_non_overlapping_monotonic когда интервалы закрыты с обеих сторон и перекрываются в точке (GH 16560)

  • Ошибка в Series.fillna() возвращает frame, когда inplace=True и value является словарем (GH 16156)

  • Ошибка в Timestamp.weekday_name возвращающий название дня недели на основе UTC при локализации в часовом поясе (GH 17354)

  • Ошибка в Timestamp.replace при замене tzinfo вокруг изменений летнего времени (GH 15683)

  • Ошибка в Timedelta конструкция и арифметические операции, которые не распространяют Overflow исключение (GH 17367)

  • Ошибка в astype() преобразование в object dtype при передаче классов типов расширений (DatetimeTZDtype, CategoricalDtype) вместо экземпляров. Теперь TypeError вызывается, когда передается класс (GH 17780).

  • Ошибка в to_numeric() в котором элементы не всегда приводились к числовым, когда errors='coerce' (GH 17007, GH 17125)

  • Ошибка в DataFrame и Series конструкторы, где range объекты преобразуются в int32 dtype в Windows вместо int64 (GH 16804)

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

  • При вызове с нулевым срезом (например, df.iloc[:]), .iloc и .loc индексаторы возвращают поверхностную копию исходного объекта. Ранее они возвращали исходный объект. (GH 13873).

  • При вызове на несортированном MultiIndex, loc индексатор теперь будет вызывать UnsortedIndexError только если используется правильное срезание на несортированных уровнях (GH 16734).

  • Исправление регрессии в версии 0.20.3 при индексации строкой на TimedeltaIndex (GH 16896).

  • Исправлено TimedeltaIndex.get_loc() обработка np.timedelta64 входные данные (GH 16909).

  • Исправление MultiIndex.sort_index() упорядочивание при ascending аргумент является списком, но не все уровни указаны, или указаны в другом порядке (GH 16934).

  • Исправлена ошибка, при которой индексирование с np.inf вызвал OverflowError будет вызвано (GH 16957)

  • Ошибка при переиндексации пустого CategoricalIndex (GH 16770)

  • Исправления DataFrame.loc для установки с выравниванием и учетом часового пояса DatetimeIndex (GH 16889)

  • Избегает IndexError при передаче Index или Series в .iloc со старым numpy (GH 17193)

  • Разрешить пустые строки юникода в качестве заполнителей в многоуровневых столбцах в Python 2 (GH 17099)

  • Ошибка в .iloc при использовании с добавлением или присваиванием на месте и целочисленным индексатором на MultiIndex вызывая чтение и запись неправильных индексов (GH 17148)

  • Ошибка в .isin() в котором проверка принадлежности к пустому Series объекты вызывали ошибку (GH 16991)

  • Ошибка в CategoricalIndex переиндексация, при которой указанные индексы, содержащие дубликаты, не учитывались (GH 17323)

  • Ошибка в пересечении RangeIndex с отрицательным шагом (GH 17296)

  • Ошибка в IntervalIndex где выполнение скалярного поиска не удаётся для включённых правых границ непересекающихся монотонно убывающих индексов (GH 16417, GH 17271)

  • Ошибка в DataFrame.first_valid_index() и DataFrame.last_valid_index() когда нет допустимой записи (GH 17400)

  • Ошибка в Series.rename() при вызове с вызываемым объектом, некорректно изменяет имя Series, а не имя Index. (GH 17407)

  • Ошибка в String.str_get() вызывает IndexError вместо вставки NaN при использовании отрицательного индекса. (GH 17704)

Ввод-вывод#

  • Ошибка в read_hdf() при чтении индекса с учетом часового пояса из fixed формат HDFStore (GH 17618)

  • Ошибка в read_csv() в котором столбцы не были полностью дедуплицированы (GH 17060)

  • Ошибка в read_csv() в котором указанные имена столбцов не были полностью дедуплицированы (GH 17095)

  • Ошибка в read_csv() в котором нецелочисленные значения для аргумента header генерировали бесполезное/несвязанное сообщение об ошибке (GH 16338)

  • Ошибка в read_csv() в котором проблемы управления памятью при обработке исключений, при определённых условиях, вызывали сегфолт интерпретатора (GH 14696, GH 16798).

  • Ошибка в read_csv() при вызове с low_memory=False в котором CSV с хотя бы одним столбцом размером > 2 ГБ некорректно вызывал MemoryError (GH 16798).

  • Ошибка в read_csv() при вызове со списком из одного элемента header вернет DataFrame всех значений NaN (GH 7757)

  • Ошибка в DataFrame.to_csv() использование кодировки 'ascii' по умолчанию в Python 3 вместо 'utf-8' (GH 17097)

  • Ошибка в read_stata() где метки значений не могли быть прочитаны при использовании итератора (GH 16923)

  • Ошибка в read_stata() где индекс не был установлен (GH 16342)

  • Ошибка в read_html() где проверка импорта не выполняется при запуске в нескольких потоках (GH 16928)

  • Ошибка в read_csv() где автоматическое определение разделителя вызвало TypeError будет выброшено при обнаружении плохой строки вместо правильного сообщения об ошибке ((other, func[, fill_value, ...]))

  • Ошибка в DataFrame.to_html() с notebook=True где DataFrame с именованными индексами или не-MultiIndex индексами имели нежелательное горизонтальное или вертикальное выравнивание для меток столбцов или строк соответственно (GH 16792)

  • Ошибка в DataFrame.to_html() в котором не было проверки justify параметр (GH 17527)

  • Ошибка в HDFStore.select() при чтении смешанной таблицы данных с VLArray (GH 17021)

  • Ошибка в to_json() где несколько условий (включая объекты с непечатаемыми символами, объекты с глубокой рекурсией, слишком длинные метки) вызывали segfault вместо поднятия соответствующего исключения (GH 14256)

Построение графиков#

  • Ошибка в методах построения графиков с использованием secondary_y и fontsize не установлен размер шрифта вторичной оси (GH 12565)

  • Ошибка при построении графика timedelta и datetime типы данных на оси y (GH 16953)

  • Линейные графики больше не предполагают монотонные данные x при расчёте xlims, теперь они показывают все линии даже для несортированных данных x. (GH 11310, GH 11471)

  • С matplotlib 2.0.0 и выше, вычисление пределов по оси x для линейных графиков оставлено matplotlib, чтобы применялись её новые настройки по умолчанию. (GH 15495)

  • Ошибка в Series.plot.bar или DataFrame.plot.bar с y не учитывает переданные пользователем color (GH 16822)

  • Ошибка, вызывающая plotting.parallel_coordinates сбросить случайное начальное значение при использовании случайных цветов (GH 17525)

GroupBy/resample/rolling#

  • Ошибка в DataFrame.resample(...).size() где пустой DataFrame не возвращал Series (GH 14962)

  • Ошибка в infer_freq() вызывая неправильное определение индексов с 2-дневными пропусками в рабочей неделе как бизнес-дневных (GH 16624)

  • Ошибка в .rolling(...).quantile() который некорректно использовал другие значения по умолчанию, чем Series.quantile() и DataFrame.quantile() (GH 9413, GH 16211)

  • Ошибка в groupby.transform() что привело бы к приведению булевых типов обратно к float (GH 16875)

  • Ошибка в Series.resample(...).apply() где пустой Series изменил исходный индекс и не вернул имя Series (GH 14313)

  • Ошибка в .rolling(...).apply(...) с DataFrame с DatetimeIndex, a window преобразуемого в timedelta и min_periods >= 1 (GH 15305)

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

  • Ошибка в groupby.nunique() с TimeGrouper который не может обработать NaT правильно (GH 17575)

  • Ошибка в DataFrame.groupby где одиночный выбор уровня из MultiIndex неожиданно сортирует (GH 17537)

  • Ошибка в DataFrame.groupby где возникает ложное предупреждение, когда Grouper объект используется для переопределения неоднозначного имени столбца (GH 17383)

  • Ошибка в TimeGrouper отличается при передаче в виде списка и в виде скаляра (GH 17530)

Разреженный#

  • Ошибка в SparseSeries вызывает AttributeError когда словарь передается в качестве данных (GH 16905)

  • Ошибка в SparseDataFrame.fillna() не заполнял все значения NaN, когда фрейм был создан из разреженной матрицы SciPy (GH 16112)

  • Ошибка в SparseSeries.unstack() и SparseDataFrame.stack() (GH 16614, GH 15045)

  • Ошибка в make_sparse() обрабатывая два числовых/логических данных, которые имеют одинаковые биты, как одинаковые при работе с массивом dtype является object (GH 17574)

  • SparseArray.all() и SparseArray.any() теперь реализованы для обработки SparseArray, они использовались, но не были реализованы (GH 17570)

Изменение формы#

  • Объединение/слияние с неуникальным PeriodIndex вызывал TypeError (GH 16871)

  • Ошибка в crosstab() где невыровненные серии целых чисел приводились к float (GH 17005)

  • Ошибка при слиянии с категориальными типами данных с датами/временем некорректно вызывала TypeError (GH 16900)

  • Ошибка при использовании isin() на большом объектном series и большом массиве сравнения (GH 16012)

  • Исправляет регрессию с версии 0.20, Series.aggregate() и DataFrame.aggregate() снова разрешить словари в качестве возвращаемых значений (GH 16741)

  • Исправляет dtype результата при вводе целочисленного dtype, с pivot_table() при вызове с margins=True (GH 17013)

  • Ошибка в crosstab() где передача двух Series с тем же именем вызвал KeyError (GH 13279)

  • Series.argmin(), Series.argmax(), и их аналоги на DataFrame и объекты groupby работают корректно с данными с плавающей точкой, содержащими бесконечные значения (GH 13595).

  • Ошибка в unique() где проверка кортежа строк вызывала TypeError (GH 17108)

  • Ошибка в concat() где порядок индекса результата был непредсказуем, если он содержал несравнимые элементы (GH 17344)

  • Исправление регрессии при сортировке по нескольким столбцам на datetime64 dtype Series с NaT значения (GH 16836)

  • Ошибка в pivot_table() где столбцы результата не сохранили категориальный тип данных (dtype) из columns когда dropna был False (GH 17842)

  • Ошибка в DataFrame.drop_duplicates где удаление с неуникальными именами столбцов вызывало ValueError (GH 17836)

  • Ошибка в unstack() который при вызове на списке уровней отбрасывал бы fillna аргумент (GH 13971)

  • Ошибка в выравнивании range объектами и другими списко-подобными структурами с DataFrame приводя к выполнению операций построчно вместо постолбцово (GH 17901)

Числовой#

  • Ошибка в .clip() с axis=1 и список-подобный для threshold передаётся; ранее это вызывало ValueError (GH 15390)

  • Series.clip() и DataFrame.clip() теперь обрабатывает NA-значения для аргументов upper и lower как None вместо вызова исключения ValueError (GH 17276).

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

  • Ошибка в Series.isin() при вызове с категориальным (GH 16639)

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

  • Ошибка в операциях с категориальными данными при Series.cat не сохраняет исходное имя Series (GH 17509)

  • Ошибка в DataFrame.merge() ошибка для категориальных столбцов с типами данных boolean/int (GH 17187)

  • Ошибка при построении Categorical/CategoricalDtype когда указанный categories имеют категориальный тип (GH 17884).

PyPy#

  • Совместимость с PyPy в read_csv() с usecols=[ ints>] и read_json() (GH 17351)

  • Разделить тесты на случаи для CPython и PyPy, где это необходимо, что подчеркивает хрупкость сопоставления индексов с float('nan'), np.nan и NAT (GH 17351)

  • Исправление DataFrame.memory_usage() для поддержки PyPy. Объекты в PyPy не имеют фиксированного размера, поэтому вместо этого используется приближение (GH 17228)

Другие#

  • Ошибка, при которой некоторые операторы на месте не оборачивались и создавали копию при вызове (GH 12962)

  • Ошибка в eval() где inplace параметр обрабатывался некорректно (GH 16732)

Участники#

Всего 206 человек внесли патчи в этот релиз. Люди со знаком «+» рядом с именами внесли патч впервые.

  • 3553x +

  • Аарон Барбер

  • Adam Gleave +

  • Adam Smith +

  • AdamShamlian +

  • Adrian Liaw +

  • Value counts устанавливает результирующее имя в

  • Alan Yee +

  • Alex B +

  • Alex Lubbock +

  • Alex Marchenko +

  • Alex Rychyk +

  • Amol K +

  • Andreas Winkler

  • Andrew +

  • Эндрю Лян

  • André Jonasson +

  • Becky Sweger

  • Berkay +

  • Боб Хаффнер +

  • Bran Yang

  • Brian Tu +

  • Brock Mendel +

  • Carol Willing +

  • Картер Грин +

  • Chankey Pathak +

  • Chris

  • Крис Биллингтон

  • Крис Фило Горголевски +

  • Крис Керр

  • Chris M +

  • Крис Маццулло +

  • Christian Prinoth

  • Christian Stade-Schuldt

  • Christoph Moehl +

  • DSM

  • Daniel Chen +

  • Daniel Grady

  • Daniel Himmelstein

  • Dave Willmer

  • David Cook

  • David Gwynne

  • David Read +

  • Dillon Niederhut +

  • Douglas Rudd

  • Eric Stein +

  • Eric Wieser +

  • Erik Fredriksen

  • Florian Wilhelm +

  • Floris Kint +

  • Запрещённый пончик

  • Gabe F +

  • Гифтлин +

  • Giftlin Rajaiah +

  • Джулио Пепе +

  • Guilherme Beltramini

  • Guillem Borrell +

  • Hanmin Qin +

  • Hendrik Makait +

  • Hugues Valois

  • Hussain Tamboli +

  • Iva Miholic +

  • Jan Novotný +

  • Ян Рудольф

  • Jean Helie +

  • Жан-Батист Ширатти +

  • Jean-Mathieu Deschenes

  • Jeff Knupp +

  • Jeff Reback

  • Jeff Tratner

  • JennaVergeynst

  • JimStearns206

  • Joel Nothman

  • John W. O’Brien

  • Jon Crall +

  • Jon Mease

  • Jonathan J. Helmus +

  • Joris Van den Bossche

  • JosephWagner

  • Хуарес Бочи

  • Julian Kuhlmann +

  • Karel De Brabandere

  • Kassandra Keeton +

  • Keiron Pizzey +

  • Keith Webber

  • Kernc

  • Кевин Шеппард

  • Кирк Хансен +

  • Licht Takeuchi +

  • Лукас Кушнер +

  • Mahdi Ben Jelloul +

  • Makarov Andrey +

  • Malgorzata Turzanska +

  • Marc Garcia +

  • Margaret Sy +

  • GH 3714

  • Matt Bark +

  • Мэтью Рёшке

  • Matti Picus

  • Мехмет Али "Мали" Акманалп

  • Michael Gasvoda +

  • Michael Penkov +

  • Milo +

  • Morgan Stuart +

  • Morgan243 +

  • Натан Форд +

  • Nick Eubank

  • Nick Garvey +

  • Oleg Shteynbuk +

  • P-Tillmann +

  • Pankaj Pandey

  • Patrick Luo

  • Patrick O’Melveny

  • Paul Reidy +

  • Paula +

  • Peter Quackenbush

  • Peter Yanovich +

  • Филлип Клауд

  • Pierre Haessig

  • Пьетро Баттистон

  • Pradyumna Reddy Chinthala

  • Прасанджит Пракаш

  • RobinFiveWords

  • Райан Хендриксон

  • Сэм Фу

  • Sangwoong Yoon +

  • Simon Gibbons +

  • SimonBaron

  • Steven Cutting +

  • Sudeep +

  • Sylvia +

  • T N +

  • Telt

  • Thomas A Caswell

  • Tim Swast +

  • Tom Augspurger

  • Tong SHEN

  • Tuan +

  • Utkarsh Upadhyay +

  • Винсент Ла +

  • Vivek +

  • WANG Aiyong

  • WBare

  • Wes McKinney

  • XF +

  • Yi Liu +

  • Yosuke Nakabayashi +

  • aaron315 +

  • abarber4gh +

  • aernlund +

  • agustín méndez +

  • andymaheshw +

  • ante328 +

  • aviolov +

  • bpraggastis

  • cbertinato +

  • cclauss +

  • chernrick

  • chris-b1

  • dkamm +

  • dwkenefick

  • экономика

  • faic +

  • fding253 +

  • gfyoung

  • guygoldberg +

  • hhuuggoo +

  • huashuai +

  • ian

  • iulia +

  • jaredsnyder

  • jbrockmendel +

  • jdeschenes

  • jebob +

  • jschendel +

  • keitakurita

  • kernc +

  • kiwirob +

  • kjford

  • linebp

  • lloydkirk

  • louispotok +

  • majiang +

  • manikbhandari +

  • margotphoenix +

  • matthiashuschle +

  • mattip

  • mjlove12 +

  • nmartensen +

  • pandas-docs-bot +

  • parchd-1 +

  • philipphanemann +

  • rdk1024 +

  • reidy-p +

  • ri938

  • ruiann +

  • rvernica +

  • s-weigand +

  • scotthavard92 +

  • skwbc +

  • step4me +

  • tobycheese +

  • topper-123 +

  • tsdlovell

  • ysau +

  • zzgao +