Что нового в 0.25.0 (18 июля 2019)#
Предупреждение
Начиная с серии выпусков 0.25.x, pandas поддерживает только Python 3.5.3 и выше. См. Удаление Python 2.7 для получения дополнительной информации.
Предупреждение
Минимальная поддерживаемая версия Python будет повышена до 3.6 в будущем релизе.
Предупреждение
Panel был полностью удален. Для N-мерных помеченных структур данных, пожалуйста,
используйте xarray
Предупреждение
read_pickle() и read_msgpack() гарантируется обратная совместимость только до
версии pandas 0.20.3 (GH 27082)
Это изменения в pandas 0.25.0. См. Примечания к выпуску для полного списка изменений, включая другие версии pandas.
Улучшения#
Агрегация GroupBy с переименованием#
pandas добавил специальное поведение groupby, известное как "именованная агрегация", для именования выходных столбцов при применении нескольких агрегационных функций к определенным столбцам (GH 18366, GH 26512).
In [1]: animals = pd.DataFrame({'kind': ['cat', 'dog', 'cat', 'dog'],
...: 'height': [9.1, 6.0, 9.5, 34.0],
...: 'weight': [7.9, 7.5, 9.9, 198.0]})
...:
In [2]: animals
Out[2]:
kind height weight
0 cat 9.1 7.9
1 dog 6.0 7.5
2 cat 9.5 9.9
3 dog 34.0 198.0
[4 rows x 3 columns]
In [3]: animals.groupby("kind").agg(
...: min_height=pd.NamedAgg(column='height', aggfunc='min'),
...: max_height=pd.NamedAgg(column='height', aggfunc='max'),
...: average_weight=pd.NamedAgg(column='weight', aggfunc="mean"),
...: )
...:
Out[3]:
min_height max_height average_weight
kind
cat 9.1 9.5 8.90
dog 6.0 34.0 102.75
[2 rows x 3 columns]
Передайте желаемые имена столбцов как **kwargs to .agg. Значения **kwargs
должны быть кортежами, где первый элемент - выбор столбца, а второй - агрегирующая функция для применения. pandas предоставляет pandas.NamedAgg namedtuple для более ясного обозначения аргументов функции, но также принимаются обычные кортежи.
In [4]: animals.groupby("kind").agg(
...: min_height=('height', 'min'),
...: max_height=('height', 'max'),
...: average_weight=('weight', 'mean'),
...: )
...:
Out[4]:
min_height max_height average_weight
kind
cat 9.1 9.5 8.90
dog 6.0 34.0 102.75
[2 rows x 3 columns]
Именованная агрегация — рекомендуемая замена устаревшего подхода «словарь словарей» для именования вывода агрегаций по столбцам (Устаревание groupby.agg() со словарём при переименовании).
Аналогичный подход теперь доступен и для объектов groupby Series. Поскольку нет необходимости в выборе столбцов, значениями могут быть просто применяемые функции
In [5]: animals.groupby("kind").height.agg(
...: min_height="min",
...: max_height="max",
...: )
...:
Out[5]:
min_height max_height
kind
cat 9.1 9.5
dog 6.0 34.0
[2 rows x 2 columns]
Этот тип агрегации является рекомендуемой альтернативой устаревшему поведению при передаче словаря в агрегацию группировки Series (Устаревание groupby.agg() со словарём при переименовании).
См. Именованная агрегация подробнее.
Групповая агрегация с несколькими лямбда-функциями#
Теперь вы можете предоставить несколько лямбда-функций для агрегации в виде списка в
GroupBy.agg (GH 26430).
In [6]: animals.groupby('kind').height.agg([
...: lambda x: x.iloc[0], lambda x: x.iloc[-1]
...: ])
...:
Out[6]:
kind
cat 9.1 9.5
dog 6.0 34.0
[2 rows x 2 columns]
In [7]: animals.groupby('kind').agg([
...: lambda x: x.iloc[0] - x.iloc[1],
...: lambda x: x.iloc[0] + x.iloc[1]
...: ])
...:
Out[7]:
height weight
kind
cat -0.4 18.6 -2.0 17.8
dog -28.0 40.0 -190.5 205.5
[2 rows x 4 columns]
Ранее это вызывало SpecificationError.
Улучшенное repr для MultiIndex#
Печать MultiIndex экземпляры теперь показывают кортежи каждой строки и обеспечивают
вертикальное выравнивание элементов кортежа, что упрощает понимание
структуры MultiIndex. (GH 13480):
Теперь repr выглядит так:
In [8]: pd.MultiIndex.from_product([['a', 'abc'], range(500)])
Out[8]:
MultiIndex([( 'a', 0),
( 'a', 1),
( 'a', 2),
( 'a', 3),
( 'a', 4),
( 'a', 5),
( 'a', 6),
( 'a', 7),
( 'a', 8),
( 'a', 9),
...
('abc', 490),
('abc', 491),
('abc', 492),
('abc', 493),
('abc', 494),
('abc', 495),
('abc', 496),
('abc', 497),
('abc', 498),
('abc', 499)],
length=1000)
Ранее вывод MultiIndex выводились все levels и
codes из MultiIndex, что было визуально непривлекательно и затрудняло
навигацию по выводу. Например (ограничивая диапазон до 5):
In [1]: pd.MultiIndex.from_product([['a', 'abc'], range(5)])
Out[1]: MultiIndex(levels=[['a', 'abc'], [0, 1, 2, 3]],
...: codes=[[0, 0, 0, 0, 1, 1, 1, 1], [0, 1, 2, 3, 0, 1, 2, 3]])
В новом представлении все значения будут показаны, если количество строк меньше чем options.display.max_seq_items (по умолчанию: 100 элементов). По горизонтали вывод будет обрезан, если он шире, чем options.display.width
(по умолчанию: 80 символов).
Сокращённое представление для Series и DataFrame#
В настоящее время параметры отображения pandas по умолчанию гарантируют, что когда Series
или DataFrame содержит более 60 строк, их repr обрезается до этого максимума
в 60 строк ( display.max_rows опция). Однако это все равно дает
repr, занимающий большую часть вертикального пространства экрана. Поэтому
новая опция display.min_rows вводится со значением по умолчанию 10, которое
определяет количество строк, отображаемых в усечённом представлении:
Для небольших Series или DataFrame, до
max_rowsпоказывается количество строк (по умолчанию: 60).Для больших Series или DataFrame с длиной выше
max_rows, толькоmin_rowsпоказывается количество строк (по умолчанию: 10, т.е. первые и последние 5 строк).
Эта двойная опция позволяет по-прежнему видеть полное содержимое относительно небольших объектов (например, df.head(20) показывает все 20 строк), давая краткое представление для больших объектов.
Чтобы восстановить предыдущее поведение с одним порогом, установите
pd.options.display.min_rows = None.
JSON normalize с поддержкой параметра max_level#
json_normalize() нормализует предоставленный входной словарь на всех вложенных уровнях. Новый параметр max_level обеспечивает больший контроль над уровнем, на котором завершить нормализацию (GH 23843):
Теперь repr выглядит так:
from pandas.io.json import json_normalize
data = [{
'CreatedBy': {'Name': 'User001'},
'Lookup': {'TextField': 'Some text',
'UserField': {'Id': 'ID001', 'Name': 'Name001'}},
'Image': {'a': 'b'}
}]
json_normalize(data, max_level=1)
Series.explode для разделения спископодобных значений на строки#
Series и DataFrame получили DataFrame.explode() методы преобразования списков в отдельные строки. См. раздел о преобразовании столбца со списком в документации для получения дополнительной информации (GH 16538, GH 10511)
Вот типичный случай использования. У вас есть строка, разделенная запятыми, в столбце.
In [9]: df = pd.DataFrame([{'var1': 'a,b,c', 'var2': 1},
...: {'var1': 'd,e,f', 'var2': 2}])
...:
In [10]: df
Out[10]:
var1 var2
0 a,b,c 1
1 d,e,f 2
[2 rows x 2 columns]
Создание длинной формы DataFrame теперь просто с использованием цепочечных операций
In [11]: df.assign(var1=df.var1.str.split(',')).explode('var1')
Out[11]:
var1 var2
0 a 1
0 b 1
0 c 1
1 d 2
1 e 2
1 f 2
[6 rows x 2 columns]
Другие улучшения#
DataFrame.plot()ключевые словаlogy,logxиloglogтеперь может принимать значение'sym'для симметричного логарифмического масштабирования. (GH 24867)Добавлена поддержка формата недельного года ISO ('%G-%V-%u') при разборе дат и времени с использованием
to_datetime()(GH 16607)Индексирование
DataFrameиSeriesтеперь принимает zerodimnp.ndarray(GH 24919)Timestamp.replace()теперь поддерживаетfoldаргумент для устранения неоднозначности времён перехода на летнее время (GH 25017)DataFrame.at_time()иSeries.at_time()теперь поддерживаетdatetime.timeобъекты с часовыми поясами (GH 24043)DataFrame.pivot_table()теперь принимаетobservedпараметр, который передается в базовые вызовыDataFrame.groupby()для ускорения группировки категориальных данных. (GH 24923)Series.strполучилSeries.str.casefold()метод для удаления всех различий регистра, присутствующих в строке (GH 25405)DataFrame.set_index()теперь работает для экземпляровabc.Iterator, при условии, что их вывод имеет ту же длину, что и вызывающий фрейм (GH 22484, GH 24984)DatetimeIndex.union()теперь поддерживаетsortаргумент. Поведение параметра sort соответствует поведениюIndex.union()(GH 24994)RangeIndex.union()теперь поддерживаетsortаргумент. Еслиsort=FalseнесортированныйInt64Indexвсегда возвращается.sort=Noneявляется значением по умолчанию и возвращает монотонно возрастающийRangeIndexесли возможно, или отсортированныйInt64Indexесли не (GH 24471)TimedeltaIndex.intersection()теперь также поддерживаетsortключевое слово (GH 24471)DataFrame.rename()теперь поддерживаетerrorsаргумент для вызова ошибок при попытке переименовать несуществующие ключи (GH 13473)Добавлен Sparse аксессор для работы с
DataFrameзначения которых разрежены (GH 25681)RangeIndexполучилstart,stop, иstepатрибуты (GH 25710)datetime.timezoneобъекты теперь поддерживаются в качестве аргументов для методов и конструкторов часовых поясов (GH 25065)DataFrame.query()иDataFrame.eval()теперь поддерживает заключение имен столбцов в обратные кавычки для ссылки на имена с пробелами (GH 6508)merge_asof()теперь выдает более понятное сообщение об ошибке, когда ключи слияния — категориальные, но не равны (GH 26136)Rolling()поддерживает экспоненциальный (или Пуассоновский) тип окна (GH 21303)Сообщение об ошибке для отсутствующих обязательных импортов теперь включает текст исходной ошибки импорта (GH 23868)
DatetimeIndexиTimedeltaIndexтеперь имеютmeanметод (GH 24757)DataFrame.describe()теперь форматирует целые процентили без десятичной точки (GH 26660)Добавлена поддержка чтения файлов SPSS .sav с использованием
read_spss()(GH 26537)Добавлена новая опция
plotting.backendчтобы иметь возможность выбрать бэкенд построения графиков, отличный от существующегоmatplotlibодин. Используйтеpandas.set_option('plotting.backend', 'где') это библиотека, реализующая API построения графиков pandas (GH 14130)pandas.offsets.BusinessHourподдерживает несколько интервалов рабочего времени (GH 15481)read_excel()теперь может использоватьopenpyxlдля чтения файлов Excel черезengine='openpyxl'аргумент. Это станет значением по умолчанию в будущем релизе (GH 11499)pandas.io.excel.read_excel()поддерживает чтение таблиц OpenDocument. Укажитеengine='odf'для включения. Обратитесь к Руководство пользователя IO для дополнительных деталей (GH 9070)Interval,IntervalIndex, иIntervalArrayполучилиis_emptyатрибут, указывающий, являются ли заданные интервалы пустыми (GH 27219)
Обратно несовместимые изменения API#
Индексирование строк дат со смещениями UTC#
Индексирование DataFrame или Series с DatetimeIndex с датой в строковом формате со смещением UTC ранее игнорировало смещение UTC. Теперь смещение UTC учитывается при индексировании. (GH 24076, GH 16785)
In [12]: df = pd.DataFrame([0], index=pd.DatetimeIndex(['2019-01-01'], tz='US/Pacific'))
In [13]: df
Out[13]:
0
2019-01-01 00:00:00-08:00 0
[1 rows x 1 columns]
Предыдущее поведение:
In [3]: df['2019-01-01 00:00:00+04:00':'2019-01-01 01:00:00+04:00']
Out[3]:
0
2019-01-01 00:00:00-08:00 0
Новое поведение:
In [14]: df['2019-01-01 12:00:00+04:00':'2019-01-01 13:00:00+04:00']
Out[14]:
0
2019-01-01 00:00:00-08:00 0
[1 rows x 1 columns]
MultiIndex построенный из уровней и кодов#
Создание MultiIndex с NaN ранее допускались уровни или значения кодов < -1.
Теперь создание со значением кода < -1 не допускается и NaN соответствующие коды уровней
будут переназначены как -1. (GH 19387)
Предыдущее поведение:
In [1]: pd.MultiIndex(levels=[[np.nan, None, pd.NaT, 128, 2]],
...: codes=[[0, -1, 1, 2, 3, 4]])
...:
Out[1]: MultiIndex(levels=[[nan, None, NaT, 128, 2]],
codes=[[0, -1, 1, 2, 3, 4]])
In [2]: pd.MultiIndex(levels=[[1, 2]], codes=[[0, -2]])
Out[2]: MultiIndex(levels=[[1, 2]],
codes=[[0, -2]])
Новое поведение:
In [15]: pd.MultiIndex(levels=[[np.nan, None, pd.NaT, 128, 2]],
....: codes=[[0, -1, 1, 2, 3, 4]])
....:
Out[15]:
MultiIndex([(nan,),
(nan,),
(nan,),
(nan,),
(128,),
( 2,)],
)
In [16]: pd.MultiIndex(levels=[[1, 2]], codes=[[0, -2]])
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[16], line 1
----> 1 pd.MultiIndex(levels=[[1, 2]], codes=[[0, -2]])
File ~/work/pandas/pandas/pandas/core/indexes/multi.py:365, in MultiIndex.__new__(cls, levels, codes, sortorder, names, dtype, copy, name, verify_integrity)
362 result.sortorder = sortorder
364 if verify_integrity:
--> 365 new_codes = result._verify_integrity()
366 result._codes = new_codes
368 result._reset_identity()
File ~/work/pandas/pandas/pandas/core/indexes/multi.py:452, in MultiIndex._verify_integrity(self, codes, levels, levels_to_verify)
446 raise ValueError(
447 f"On level {i}, code max ({level_codes.max()}) >= length of "
448 f"level ({len(level)}). NOTE: this index is in an "
449 "inconsistent state"
450 )
451 if len(level_codes) and level_codes.min() < -1:
--> 452 raise ValueError(f"On level {i}, code value ({level_codes.min()}) < -1")
453 if not level.is_unique:
454 raise ValueError(
455 f"Level values must be unique: {list(level)} on level {i}"
456 )
ValueError: On level 0, code value (-2) < -1
GroupBy.apply на DataFrame оценивает первую группу только один раз#
Реализация DataFrameGroupBy.apply()
ранее выполнял предоставленную функцию дважды для первой группы
чтобы определить, безопасно ли использовать быстрый путь выполнения. Особенно для функций с
побочными эффектами это было нежелательным поведением и могло приводить к неожиданностям. (GH 2936, GH 2656, GH 7739, GH 10519, GH 12155, GH 20084, GH 21417)
Теперь каждая группа вычисляется только один раз.
In [17]: df = pd.DataFrame({"a": ["x", "y"], "b": [1, 2]})
In [18]: df
Out[18]:
a b
0 x 1
1 y 2
[2 rows x 2 columns]
In [19]: def func(group):
....: print(group.name)
....: return group
....:
Предыдущее поведение:
In [3]: df.groupby('a').apply(func)
x
x
y
Out[3]:
a b
0 x 1
1 y 2
Новое поведение:
In [3]: df.groupby('a').apply(func)
x
y
Out[3]:
a b
0 x 1
1 y 2
Объединение разреженных значений#
При передаче DataFrame, значения которых являются разреженными, concat() теперь возвращает
Series или DataFrame с разреженными значениями, а не с SparseDataFrame (GH 25702).
In [20]: df = pd.DataFrame({"A": pd.arrays.SparseArray([0, 1])})
Предыдущее поведение:
In [2]: type(pd.concat([df, df]))
pandas.core.sparse.frame.SparseDataFrame
Новое поведение:
In [21]: type(pd.concat([df, df]))
Out[21]: pandas.core.frame.DataFrame
Теперь это соответствует существующему поведению concat на Series со значениями sparse.
concat() продолжит возвращать SparseDataFrame когда все значения
являются экземплярами SparseDataFrame.
Это изменение также затрагивает процедуры, использующие concat() внутренне, как get_dummies(),
который теперь возвращает DataFrame во всех случаях (ранее SparseDataFrame возвращалось, если все столбцы были закодированы как фиктивные, и DataFrame в противном случае).
Предоставление любого SparseSeries или SparseDataFrame to concat() вызовет SparseSeries или SparseDataFrame для возврата, как и раньше.
The .str-аксессор выполняет более строгие проверки типов#
Из-за отсутствия более детальных типов данных, Series.str пока что проверял только, были ли данные object тип данных. Series.str теперь будет определять тип данных внутри Series; в частности,
'bytes'-only данные вызовут исключение (кроме Series.str.decode(), Series.str.get(),
Series.str.len(), Series.str.slice()), см. GH 23163, GH 23011, GH 23551.
Предыдущее поведение:
In [1]: s = pd.Series(np.array(['a', 'ba', 'cba'], 'S'), dtype=object)
In [2]: s
Out[2]:
0 b'a'
1 b'ba'
2 b'cba'
dtype: object
In [3]: s.str.startswith(b'a')
Out[3]:
0 True
1 False
2 False
dtype: bool
Новое поведение:
In [22]: s = pd.Series(np.array(['a', 'ba', 'cba'], 'S'), dtype=object)
In [23]: s
Out[23]:
0 b'a'
1 b'ba'
2 b'cba'
Length: 3, dtype: object
In [24]: s.str.startswith(b'a')
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[24], line 1
----> 1 s.str.startswith(b'a')
File ~/work/pandas/pandas/pandas/core/strings/accessor.py:139, in forbid_nonstring_types.._forbid_nonstring_types..wrapper (self, *args, **kwargs)
134 if self._inferred_dtype not in allowed_types:
135 msg = (
136 f"Cannot use .str.{func_name} with values of "
137 f"inferred dtype '{self._inferred_dtype}'."
138 )
--> 139 raise TypeError(msg)
140 return func(self, *args, **kwargs)
TypeError: Cannot use .str.startswith with values of inferred dtype 'bytes'.
Категориальные типы данных сохраняются во время GroupBy#
Ранее столбцы, которые были категориальными, но не являлись ключами группировки, преобразовывались в object dtype во время операций groupby. Теперь pandas будет сохранять эти dtypes. (GH 18502)
In [25]: cat = pd.Categorical(["foo", "bar", "bar", "qux"], ordered=True)
In [26]: df = pd.DataFrame({'payload': [-1, -2, -1, -2], 'col': cat})
In [27]: df
Out[27]:
payload col
0 -1 foo
1 -2 bar
2 -1 bar
3 -2 qux
[4 rows x 2 columns]
In [28]: df.dtypes
Out[28]:
payload int64
col category
Length: 2, dtype: object
Предыдущее поведение:
In [5]: df.groupby('payload').first().col.dtype
Out[5]: dtype('O')
Новое поведение:
In [29]: df.groupby('payload').first().col.dtype
Out[29]: CategoricalDtype(categories=['bar', 'foo', 'qux'], ordered=True, categories_dtype=object)
Несовместимые объединения типов индексов#
При выполнении Index.union() nan Index типа данных object. Это поведение сохраняется для объединений между Index объекты, которые ранее были запрещены. Тип данных пустого Index объекты теперь будут оцениваться перед выполнением операций объединения, а не просто возвращать другой Index объект. Index.union() теперь можно считать коммутативной, так что A.union(B) == B.union(A) (GH 23525).
Предыдущее поведение:
In [1]: pd.period_range('19910905', periods=2).union(pd.Int64Index([1, 2, 3]))
...
ValueError: can only call with other PeriodIndex-ed objects
In [2]: pd.Index([], dtype=object).union(pd.Index([1, 2, 3]))
Out[2]: Int64Index([1, 2, 3], dtype='int64')
Новое поведение:
In [3]: pd.period_range('19910905', periods=2).union(pd.Int64Index([1, 2, 3]))
Out[3]: Index([1991-09-05, 1991-09-06, 1, 2, 3], dtype='object')
In [4]: pd.Index([], dtype=object).union(pd.Index([1, 2, 3]))
Out[4]: Index([1, 2, 3], dtype='object')
Обратите внимание, что индексы целочисленного и плавающего типов считаются "совместимыми". Целочисленные значения приводятся к плавающей точке, что может привести к потере точности. См. Операции над множествами для объектов Index подробнее.
DataFrame GroupBy ffill/bfill больше не возвращают метки групп#
Методы ffill, bfill, pad и backfill of
DataFrameGroupBy
ранее включал метки групп в возвращаемое значение, что было
несовместимо с другими преобразованиями groupby. Теперь возвращаются только заполненные значения.
(GH 21521)
In [30]: df = pd.DataFrame({"a": ["x", "y"], "b": [1, 2]})
In [31]: df
Out[31]:
a b
0 x 1
1 y 2
[2 rows x 2 columns]
Предыдущее поведение:
In [3]: df.groupby("a").ffill()
Out[3]:
a b
0 x 1
1 y 2
Новое поведение:
In [32]: df.groupby("a").ffill()
Out[32]:
b
0 1
1 2
[2 rows x 1 columns]
DataFrame describe для пустого категориального/объектного столбца вернет top и freq#
При вызове DataFrame.describe() При пустом категориальном/объектном столбце столбцы 'top' и 'freq' ранее опускались, что было несогласованно с выводом для непустых столбцов. Теперь столбцы 'top' и 'freq' будут всегда включаться, numpy.nan в случае пустого DataFrame (GH 26397)
In [33]: df = pd.DataFrame({"empty_col": pd.Categorical([])})
In [34]: df
Out[34]:
Empty DataFrame
Columns: [empty_col]
Index: []
[0 rows x 1 columns]
Предыдущее поведение:
In [3]: df.describe()
Out[3]:
empty_col
count 0
unique 0
Новое поведение:
In [35]: df.describe()
Out[35]:
empty_col
count 0
unique 0
top NaN
freq NaN
[4 rows x 1 columns]
__str__ методы теперь вызывают __repr__ а не наоборот#
pandas до сих пор в основном определял строковые представления в
__str__/__unicode__/__bytes__ методы, и вызывается __str__ из __repr__
метод, если конкретный __repr__ метод не найден. Это не требуется для Python3.
В pandas 0.25 строковые представления объектов pandas теперь обычно определяются в __repr__, и вызовы __str__ в целом теперь передают вызов
в __repr__, если конкретный __str__ метод не существует, как это принято в Python.
Это изменение обратно совместимо для прямого использования pandas, но если вы создаете подклассы
объектов pandas и дайте вашим подклассам конкретные __str__/__repr__ методов, вам может потребоваться настроить свои __str__/__repr__ методы (GH 26495).
Индексирование IntervalIndex с Interval объекты#
Методы индексации для IntervalIndex были изменены, чтобы требовать только точных совпадений для Interval запросы.
IntervalIndex методы ранее совпадали при любом перекрытии Interval. Поведение со скалярными точками, например, запрос с целым числом, не изменяется (GH 16316).
In [36]: ii = pd.IntervalIndex.from_tuples([(0, 4), (1, 5), (5, 8)])
In [37]: ii
Out[37]: IntervalIndex([(0, 4], (1, 5], (5, 8]], dtype='interval[int64, right]')
The in оператор (__contains__) теперь возвращает только True для точных совпадений с Intervals в IntervalIndex, тогда как
ранее это возвращало True для любого Interval перекрывающий Interval в IntervalIndex.
Предыдущее поведение:
In [4]: pd.Interval(1, 2, closed='neither') in ii
Out[4]: True
In [5]: pd.Interval(-10, 10, closed='both') in ii
Out[5]: True
Новое поведение:
In [38]: pd.Interval(1, 2, closed='neither') in ii
Out[38]: False
In [39]: pd.Interval(-10, 10, closed='both') in ii
Out[39]: False
The get_loc() метод теперь возвращает только местоположения для точных совпадений с Interval запросы, в отличие от предыдущего поведения возврата местоположений для перекрывающихся совпадений. KeyError будет вызвано, если точное совпадение не найдено.
Предыдущее поведение:
In [6]: ii.get_loc(pd.Interval(1, 5))
Out[6]: array([0, 1])
In [7]: ii.get_loc(pd.Interval(2, 6))
Out[7]: array([0, 1, 2])
Новое поведение:
In [6]: ii.get_loc(pd.Interval(1, 5))
Out[6]: 1
In [7]: ii.get_loc(pd.Interval(2, 6))
---------------------------------------------------------------------------
KeyError: Interval(2, 6, closed='right')
Аналогично, get_indexer() и get_indexer_non_unique() также будет возвращать только местоположения для точных совпадений
с Interval запросы, с -1 указывает, что точное совпадение не найдено.
Эти изменения индексации распространяются на запрос к Series или DataFrame с IntervalIndex index.
In [40]: s = pd.Series(list('abc'), index=ii)
In [41]: s
Out[41]:
(0, 4] a
(1, 5] b
(5, 8] c
Length: 3, dtype: object
Выбор из Series или DataFrame используя [] (__getitem__) или loc теперь возвращает только точные совпадения для Interval запросы.
Предыдущее поведение:
In [8]: s[pd.Interval(1, 5)]
Out[8]:
(0, 4] a
(1, 5] b
dtype: object
In [9]: s.loc[pd.Interval(1, 5)]
Out[9]:
(0, 4] a
(1, 5] b
dtype: object
Новое поведение:
In [42]: s[pd.Interval(1, 5)]
Out[42]: 'b'
In [43]: s.loc[pd.Interval(1, 5)]
Out[43]: 'b'
Аналогично, KeyError будет вызываться для неточных совпадений вместо возврата перекрывающихся совпадений.
Предыдущее поведение:
In [9]: s[pd.Interval(2, 3)]
Out[9]:
(0, 4] a
(1, 5] b
dtype: object
In [10]: s.loc[pd.Interval(2, 3)]
Out[10]:
(0, 4] a
(1, 5] b
dtype: object
Новое поведение:
In [6]: s[pd.Interval(2, 3)]
---------------------------------------------------------------------------
KeyError: Interval(2, 3, closed='right')
In [7]: s.loc[pd.Interval(2, 3)]
---------------------------------------------------------------------------
KeyError: Interval(2, 3, closed='right')
The overlaps() метод может быть использован для создания булева индексатора, который воспроизводит
предыдущее поведение возврата перекрывающихся совпадений.
Новое поведение:
In [44]: idxr = s.index.overlaps(pd.Interval(2, 3))
In [45]: idxr
Out[45]: array([ True, True, False])
In [46]: s[idxr]
Out[46]:
(0, 4] a
(1, 5] b
Length: 2, dtype: object
In [47]: s.loc[idxr]
Out[47]:
(0, 4] a
(1, 5] b
Length: 2, dtype: object
Бинарные ufuncs для Series теперь выравниваются#
Применение бинарной универсальной функции, такой как numpy.power() теперь выравнивает входные данные
когда оба являются Series (GH 23293).
In [48]: s1 = pd.Series([1, 2, 3], index=['a', 'b', 'c'])
In [49]: s2 = pd.Series([3, 4, 5], index=['d', 'c', 'b'])
In [50]: s1
Out[50]:
a 1
b 2
c 3
Length: 3, dtype: int64
In [51]: s2
Out[51]:
d 3
c 4
b 5
Length: 3, dtype: int64
Предыдущее поведение
In [5]: np.power(s1, s2)
Out[5]:
a 1
b 16
c 243
dtype: int64
Новое поведение
In [52]: np.power(s1, s2)
Out[52]:
a 1.0
b 32.0
c 81.0
d NaN
Length: 4, dtype: float64
Это соответствует поведению других бинарных операций в pandas, таких как Series.add().
Чтобы сохранить предыдущее поведение, преобразуйте другой Series в массив перед применением ufunc.
In [53]: np.power(s1, s2.array)
Out[53]:
a 1
b 16
c 243
Length: 3, dtype: int64
Categorical.argsort теперь помещает пропущенные значения в конец#
Categorical.argsort() теперь помещает пропущенные значения в конец массива, делая его
согласованным с NumPy и остальной частью pandas (GH 21801).
In [54]: cat = pd.Categorical(['b', None, 'a'], categories=['a', 'b'], ordered=True)
Предыдущее поведение
In [2]: cat = pd.Categorical(['b', None, 'a'], categories=['a', 'b'], ordered=True)
In [3]: cat.argsort()
Out[3]: array([1, 2, 0])
In [4]: cat[cat.argsort()]
Out[4]:
[NaN, a, b]
categories (2, object): [a < b]
Новое поведение
In [55]: cat.argsort()
Out[55]: array([2, 0, 1])
In [56]: cat[cat.argsort()]
Out[56]:
['a', 'b', NaN]
Categories (2, object): ['a' < 'b']
Порядок столбцов сохраняется при передаче списка словарей в DataFrame#
Начиная с Python 3.7 порядок ключей в dict является гарантировано. На практике это верно с
Python 3.6. DataFrame конструктор теперь обрабатывает список словарей так же, как он обрабатывает список OrderedDict, т.е. сохраняя порядок словарей.
Это изменение применяется только когда pandas работает на Python>=3.6 (GH 27309).
In [57]: data = [
....: {'name': 'Joe', 'state': 'NY', 'age': 18},
....: {'name': 'Jane', 'state': 'KY', 'age': 19, 'hobby': 'Minecraft'},
....: {'name': 'Jean', 'state': 'OK', 'age': 20, 'finances': 'good'}
....: ]
....:
Предыдущее поведение:
Ранее столбцы сортировались лексикографически,
In [1]: pd.DataFrame(data)
Out[1]:
age finances hobby name state
0 18 NaN NaN Joe NY
1 19 NaN Minecraft Jane KY
2 20 good NaN Jean OK
Новое поведение:
Порядок столбцов теперь соответствует порядку вставки ключей в dict, учитывая все записи сверху вниз. В результате порядок столбцов в полученном DataFrame изменился по сравнению с предыдущими версиями pandas.
In [58]: pd.DataFrame(data)
Out[58]:
name state age hobby finances
0 Joe NY 18 NaN NaN
1 Jane KY 19 Minecraft NaN
2 Jean OK 20 NaN good
[3 rows x 5 columns]
Повышенные минимальные версии для зависимостей#
Из-за прекращения поддержки Python 2.7, ряд опциональных зависимостей обновил минимальные версии (GH 25725, GH 24942, GH 25752). Независимо, некоторые минимальные поддерживаемые версии зависимостей были обновлены (GH 23519, GH 25554). Если установлено, теперь требуется:
Пакет |
Минимальная версия |
Обязательно |
|---|---|---|
numpy |
1.13.3 |
X |
pytz |
2015.4 |
X |
python-dateutil |
2.6.1 |
X |
bottleneck |
1.2.1 |
|
numexpr |
2.6.2 |
|
pytest (разработка) |
4.0.2 |
Для дополнительные библиотеки общая рекомендация — использовать последнюю версию. Следующая таблица перечисляет минимальную версию для каждой библиотеки, которая в настоящее время тестируется в ходе разработки pandas. Опциональные библиотеки ниже минимальной тестируемой версии могут всё ещё работать, но не считаются поддерживаемыми.
Пакет |
Минимальная версия |
|---|---|
beautifulsoup4 |
4.6.0 |
fastparquet |
0.2.1 |
gcsfs |
0.2.2 |
lxml |
3.8.0 |
matplotlib |
2.2.2 |
openpyxl |
2.4.8 |
pyarrow |
0.9.0 |
pymysql |
0.7.1 |
pytables |
3.4.2 |
scipy |
0.19.0 |
sqlalchemy |
1.1.4 |
xarray |
0.8.2 |
xlrd |
1.1.0 |
xlsxwriter |
0.9.8 |
xlwt |
1.2.0 |
См. Зависимости и Необязательные зависимости подробнее.
Другие изменения API#
DatetimeTZDtypeтеперь будет стандартизировать часовые пояса pytz к общему экземпляру часового пояса (GH 24713)TimestampиTimedeltaскаляры теперь реализуютto_numpy()метод как псевдонимы дляTimestamp.to_datetime64()иTimedelta.to_timedelta64(), соответственно. (GH 24653)Timestamp.strptime()теперь вызоветNotImplementedError(GH 25016)Сравнение
Timestampс неподдерживаемыми объектами теперь возвращаетNotImplementedвместо вызова исключенияTypeError. Это означает, что неподдерживаемые расширенные сравнения делегируются другому объекту и теперь соответствуют поведению Python 3 дляdatetimeобъекты (GH 24011)Ошибка в
DatetimeIndex.snap()который не сохранялnameвходных данныхIndex(GH 25575)The
argаргумент вDataFrameGroupBy.agg()был переименован вfunc(GH 26089)The
argаргумент вWindow.aggregate()был переименован вfunc(GH 26372)У большинства классов pandas был
__bytes__метод, который использовался для получения представления объекта в стиле Python2 в виде байтовой строки. Этот метод был удален в рамках отказа от Python2 (GH 26447)The
.str-accessor был отключен для 1-уровневогоMultiIndex, используйтеMultiIndex.to_flat_index()при необходимости (GH 23679)Удалена поддержка пакета gtk для буферов обмена (GH 26563)
Использование неподдерживаемой версии Beautiful Soup 4 теперь вызывает
ImportErrorвместоValueError(GH 27063)Series.to_excel()иDataFrame.to_excel()теперь вызоветValueErrorпри сохранении данных с учётом часового пояса. (GH 27008, GH 7056)ExtensionArray.argsort()помещает значения NA в конец отсортированного массива. (GH 21801)DataFrame.to_hdf()иSeries.to_hdf()теперь вызоветNotImplementedErrorпри сохраненииMultiIndexс типами данных расширений дляfixedформат. (GH 7775)Передача дублирующихся
namesвread_csv()теперь вызоветValueError(GH 17346)
Устаревшие функции#
Разреженные подклассы#
The SparseSeries и SparseDataFrame подклассы устарели. Их функциональность лучше предоставляется
через Series или DataFrame со значениями sparse.
Предыдущий способ
df = pd.SparseDataFrame({"A": [0, 0, 1, 2]})
df.dtypes
Новый способ
In [59]: df = pd.DataFrame({"A": pd.arrays.SparseArray([0, 0, 1, 2])})
In [60]: df.dtypes
Out[60]:
A Sparse[int64, 0]
Length: 1, dtype: object
Использование памяти двумя подходами идентично (GH 19239).
формат msgpack#
Формат msgpack устарел с версии 0.25 и будет удален в будущей версии. Рекомендуется использовать pyarrow для передачи объектов pandas по сети. (GH 27084)
Другие устаревшие функции#
Устаревший
.ix[]индексатор теперь вызывает более заметноеFutureWarningвместоDeprecationWarning(GH 26438).Устарел
units=M(месяцы) иunits=Y(год) параметры дляunitsofpandas.to_timedelta(),pandas.Timedelta()иpandas.TimedeltaIndex()(GH 16344)pandas.concat()устарелjoin_axes-keyword. Вместо этого используйтеDataFrame.reindex()илиDataFrame.reindex_like()на результате или на входных данных (GH 21951)The
SparseArray.valuesатрибут устарел. Вы можете использоватьnp.asarray(...)илиSparseArray.to_dense()метод вместо (GH 26421).Функции
pandas.to_datetime()иpandas.to_timedelta()устарелиboxключевое слово. Вместо этого используйтеto_numpy()илиTimestamp.to_datetime64()илиTimedelta.to_timedelta64(). (GH 24416)The
DataFrame.compound()иSeries.compound()методы устарели и будут удалены в будущей версии (GH 26405).Внутренние атрибуты
_start,_stopи_stepатрибутыRangeIndexбыли устаревшими. Используйте публичные атрибутыstart,stopиstepвместо (GH 26581).The
Series.ftype(),Series.ftypes()иDataFrame.ftypes()методы устарели и будут удалены в будущей версии. Вместо этого используйтеSeries.dtype()иDataFrame.dtypes()(GH 26705).The
Series.get_values(),DataFrame.get_values(),Index.get_values(),SparseArray.get_values()иCategorical.get_values()методы устарели. Один изnp.asarray(..)илиto_numpy()может использоваться вместо (GH 19617).Метод 'outer' для NumPy ufuncs, например.
np.subtract.outerбыл объявлен устаревшим вSeriesобъектов. Преобразуйте входные данные в массив с помощьюSeries.arrayпервый (GH 27186)Timedelta.resolution()устарел и заменен наTimedelta.resolution_string(). В будущей версии,Timedelta.resolution()будет изменено для поведения, аналогичного стандартной библиотекеdatetime.timedelta.resolution(GH 21344)read_table()был восстановлен из устаревших. (GH 25220)Index.dtype_strустарело. (GH 18262)Series.imagиSeries.realустарели. (GH 18262)Series.put()устарело. (GH 18262)Index.item()иSeries.item()устарело. (GH 18262)Значение по умолчанию
ordered=NoneвCategoricalDtypeбыл объявлен устаревшим в пользуordered=False. При преобразовании между категориальными типамиordered=Trueдолжен быть явно передан, чтобы быть сохраненным. (GH 26336)Index.contains()устарел. Используйтеkey in index(__contains__) вместо (GH 17753).DataFrame.get_dtype_counts()устарело. (GH 18262)Categorical.ravel()вернётCategoricalвместоnp.ndarray(GH 27199)
Удаление устаревших функций/изменений предыдущих версий#
Удалена ранее устаревшая
sheetnameключевое слово вread_excel()(GH 16442, GH 20938)Удалена ранее устаревшая
TimeGrouper(GH 16942)Удалена ранее устаревшая
parse_colsключевое слово вread_excel()(GH 16488)Удалена ранее устаревшая
pd.options.html.border(GH 16970)Удалена ранее устаревшая
convert_objects(GH 11221)Удалена ранее устаревшая
selectметодDataFrameиSeries(GH 17633)Удалено ранее устаревшее поведение
Seriesрассматривается как список вrename_categories()(GH 17982)Удалена ранее устаревшая
DataFrame.reindex_axisиSeries.reindex_axis(GH 17842)Удалено ранее устаревшее поведение изменения меток столбцов или индекса с помощью
Series.rename_axis()илиDataFrame.rename_axis()(GH 17842)Удалена ранее устаревшая
tupleize_colsименованный аргумент вread_html(),read_csv(), иDataFrame.to_csv()(GH 17877, GH 17820)Удалена ранее устаревшая
DataFrame.from.csvиSeries.from_csv(GH 17812)Удалена ранее устаревшая
raise_on_errorименованный аргумент вDataFrame.where()иDataFrame.mask()(GH 17744)Удалена ранее устаревшая
orderedиcategoriesименованные аргументы вastype(GH 17742)Удалена ранее устаревшая
cdate_range(GH 17691)Удалена ранее устаревшая
Trueопция дляdropnaименованный аргумент вSeriesGroupBy.nth()(GH 17493)Удалена ранее устаревшая
convertименованный аргумент вSeries.take()иDataFrame.take()(GH 17352)Удалено ранее устаревшее поведение арифметических операций с
datetime.dateобъекты (GH 21152)
Улучшения производительности#
Значительное ускорение в
SparseArrayинициализации, которая приносит пользу большинству операций, исправляя регрессию производительности, введённую в v0.20.0 (GH 24985)DataFrame.to_stata()теперь работает быстрее при выводе данных с любыми строковыми или не-нативными колонками с порядком байт (GH 25045)Улучшена производительность
Series.searchsorted(). Ускорение особенно заметно, когда тип данных int8/int16/int32 и искомый ключ находится в пределах целочисленных границ для этого типа (GH 22034)Улучшена производительность
GroupBy.quantile()(GH 20405)Улучшена производительность срезов и других выбранных операций над
RangeIndex(GH 26565, GH 26617, GH 26722)RangeIndexтеперь выполняет стандартный поиск без создания фактической хэш-таблицы, экономя память (GH 16685)Улучшена производительность
read_csv()за счёт более быстрой токенизации и более быстрого разбора маленьких чисел с плавающей точкой (GH 25784)Улучшена производительность
read_csv()за счет более быстрого разбора значений N/A и булевых значений (GH 25804)Улучшена производительность
IntervalIndex.is_monotonic,IntervalIndex.is_monotonic_increasingиIntervalIndex.is_monotonic_decreasingпутем удаления преобразования вMultiIndex(GH 24813)Улучшена производительность
DataFrame.to_csv()при записи типов данных datetime (GH 25708)Улучшена производительность
read_csv()значительно более быстрым парсингомMM/YYYYиDD/MM/YYYYформаты даты и времени (GH 25922)Улучшена производительность nanops для типов данных, которые не могут хранить NaN. Ускорение особенно заметно для
Series.all()иSeries.any()(GH 25070)Улучшена производительность
Series.map()для словарных мапперов на категориальных сериях путём маппинга категорий вместо маппинга всех значений (GH 23785)Улучшена производительность
IntervalIndex.intersection()(GH 24813)Улучшена производительность
read_csv()за счёт более быстрого объединения столбцов дат без дополнительного преобразования в строку для целого/вещественного нуля и вещественногоNaN; за счёт более быстрой проверки строки на возможность быть датой (GH 25754)Улучшена производительность
IntervalIndex.is_uniqueпутем удаления преобразования вMultiIndex(GH 24813)Восстановлена производительность
DatetimeIndex.__iter__()путем повторного включения специализированного пути кода (GH 26702)Улучшена производительность при построении
MultiIndexс хотя бы однимCategoricalIndexуровень (GH 22044)Улучшена производительность за счёт устранения необходимости сборки мусора при проверке
SettingWithCopyWarning(GH 27031)Для
to_datetime()изменено значение по умолчанию параметра cache наTrue(GH 26043)Улучшена производительность
DatetimeIndexиPeriodIndexсрез при задании неуникальных, монотонных данных (GH 27136).Улучшена производительность
pd.read_json()для данных, ориентированных на индекс. (GH 26773)Улучшена производительность
MultiIndex.shape()(GH 27384).
Исправления ошибок#
Категориальный#
Ошибка в
DataFrame.at()иSeries.at()который вызывал бы исключение, если индекс былCategoricalIndex(GH 20629)Исправлена ошибка в сравнении упорядоченных
Categoricalкоторый содержал пропущенные значения со скаляром, что иногда некорректно приводило кTrue(GH 26504)Ошибка в
DataFrame.dropna()когдаDataFrameимеетCategoricalIndexсодержащийIntervalобъекты некорректно вызываютTypeError(GH 25087)
Datetimelike#
Ошибка в
to_datetime()что вызывало (неправильную)ValueErrorпри вызове с датой далеко в будущем иformatаргумент указан вместо вызова исключенияOutOfBoundsDatetime(GH 23830)Ошибка в
to_datetime()что вызвало быInvalidIndexError: Reindexing only valid with uniquely valued Index objectsпри вызове сcache=True, сargвключая как минимум два различных элемента из множества{None, numpy.nan, pandas.NaT}(GH 22305)Ошибка в
DataFrameиSeriesгде данные с учётом часового пояса сdtype='datetime64[ns]не был преобразован в наивный (GH 25843)Улучшено
Timestampпроверка типа в различных функциях работы с датой и временем для предотвращения исключений при использовании подклассаdatetime(GH 25851)Ошибка в
SeriesиDataFramerepr гдеnp.datetime64('NaT')иnp.timedelta64('NaT')сdtype=objectбудет представлен какNaN(GH 25445)Ошибка в
to_datetime()который не заменяет недопустимый аргумент наNaTкогда error установлен в coerce (GH 26122)Ошибка при добавлении
DateOffsetс ненулевым месяцем вDatetimeIndexвызоветValueError(GH 26258)Ошибка в
to_datetime()который вызывает необработанноеOverflowErrorпри вызове со смесью недопустимых дат иNaNзначения сformat='%Y%m%d'иerror='coerce'(GH 25512)Ошибка в
isin()для индексов типа datetime;DatetimeIndex,TimedeltaIndexиPeriodIndexгдеlevelsпараметр игнорировался. (GH 26675)Ошибка в
to_datetime()который вызываетTypeErrorдляformat='%Y%m%d'при вызове для недопустимых целочисленных дат с длиной >= 6 цифр сerrors='ignore'Ошибка при сравнении
PeriodIndexпротив нульмерного массива numpy (GH 26689)Ошибка при построении
SeriesилиDataFrameиз numpydatetime64массив с не-ns единицей измерения и выходящими за границы временными метками, генерирующий некорректные данные, что теперь правильно вызывает исключениеOutOfBoundsDatetimeошибка (GH 26206).Ошибка в
date_range()с ненужнымиOverflowErrorвызывается для очень больших или очень маленьких дат (GH 26651)Ошибка, при которой добавление
Timestampвnp.timedelta64объект вызывал исключение вместо возвратаTimestamp(GH 24775)Ошибка, при сравнении нульмерного массива numpy, содержащего
np.datetime64объект вTimestampнекорректно вызывалTypeError(GH 26916)Ошибка в
to_datetime()что вызвало быValueError: Tz-aware datetime.datetime cannot be converted to datetime64 unless utc=Trueпри вызове сcache=True, сargвключая строки даты и времени с различным смещением (GH 26097)
Timedelta#
Ошибка в
TimedeltaIndex.intersection()где для немонотонных индексов в некоторых случаях пустойIndexвозвращалось, когда на самом деле существовало пересечение (GH 25913)Ошибка при сравнениях между
TimedeltaиNaTвызовTypeError(GH 26039)Ошибка при добавлении или вычитании
BusinessHourвTimestampс результирующим временем, попадающим в следующий или предыдущий день соответственно (GH 26381)Ошибка при сравнении
TimedeltaIndexпротив нульмерного массива numpy (GH 26689)
Часовые пояса#
Ошибка в
DatetimeIndex.to_frame()где данные с учетом часового пояса преобразовывались бы в данные без учета часового пояса (GH 25809)Ошибка в
to_datetime()сutc=Trueи строки даты-времени, которые применяли ранее разобранные смещения UTC к последующим аргументам (GH 24992)Ошибка в
Timestamp.tz_localize()иTimestamp.tz_convert()не распространяетсяfreq(GH 25241)Ошибка в
Series.at()где установкаTimestampс часовым поясом вызываетTypeError(GH 25506)Ошибка в
DataFrame.update()при обновлении с данными, учитывающими часовой пояс, возвращало данные без учёта часового пояса (GH 25807)Ошибка в
to_datetime()где неинформативныйRuntimeErrorбыло вызвано при передаче наивногоTimestampс строками даты-времени со смещенными смещениями UTC (GH 25978)Ошибка в
to_datetime()сunit='ns'удалял бы информацию о часовом поясе из разобранного аргумента (GH 26168)Ошибка в
DataFrame.join()при объединении индекса с учетом часового пояса со столбцом с учетом часового пояса может получиться столбецNaN(GH 26335)Ошибка в
date_range()где неоднозначные или несуществующие начальные или конечные времена не обрабатывалисьambiguousилиnonexistentключевые слова соответственно (GH 27088)Ошибка в
DatetimeIndex.union()при объединении timezone aware и timezone unawareDatetimeIndex(GH 21671)Ошибка при применении функции редукции numpy (например,
numpy.minimum()) в осведомленный о часовом поясеSeries(GH 15552)
Числовой#
Ошибка в
to_numeric()в котором большие отрицательные числа обрабатывались неправильно (GH 24910)Ошибка в
to_numeric()в котором числа приводились к типу float, хотяerrorsне былcoerce(GH 24910)Ошибка в
to_numeric()в котором недопустимые значения дляerrorsбыли разрешены (GH 26466)Ошибка в
formatв котором числа с плавающей точкой комплексного типа не форматировались с правильной точностью отображения и обрезкой (GH 25514)Ошибка в сообщениях об ошибках в
DataFrame.corr()иSeries.corr(). Добавлена возможность использования вызываемого объекта. (GH 25729)Ошибка в
Series.divmod()иSeries.rdivmod()что вызывало (неправильную)ValueErrorвместо возврата парыSeriesобъекты в качестве результата (GH 25557)Вызывает полезное исключение, когда нечисловой индекс передается в
interpolate()с методами, требующими числового индекса. (GH 21662)Ошибка в
eval()при сравнении чисел с плавающей точкой со скалярными операторами, например:x < -0.1(GH 25928)Исправлена ошибка, при которой приведение полностью булевого массива к целочисленному расширенному массиву завершалось неудачей (GH 25211)
Ошибка в
divmodсSeriesобъект, содержащий нули, неправильно вызывающийAttributeError(GH 26987)Несогласованность в
Seriesцелочисленное деление (//) иdivmodзаполнение положительных//нулевых сNaNвместоInf(GH 27321)
Преобразование#
Ошибка в
DataFrame.astype()при передаче словаря столбцов и типовerrorsпараметр игнорировался. (GH 25905)
Строки#
Ошибка в
__name__атрибут нескольких методовSeries.str, которые были установлены некорректно (GH 23551)Улучшено сообщение об ошибке при передаче
Seriesнеправильного типа данных дляSeries.str.cat()(GH 22722)
Interval#
Конструкция
Intervalограничен числовыми,TimestampиTimedeltaконечные точки (GH 23013)Исправлена ошибка в
Series/DataFrameне отображаетсяNaNвIntervalIndexс пропущенными значениями (GH 25984)Ошибка в
IntervalIndex.get_loc()гдеKeyErrorбудет некорректно вызываться для убывающегоIntervalIndex(GH 25860)Ошибка в
Indexконструктор, где передача смешанных закрытыхIntervalобъекты приведут кValueErrorвместоobjectdtypeIndex(GH 27172)
Индексирование#
Улучшенное сообщение об исключении при вызове
DataFrame.iloc()со списком нечисловых объектов (GH 25753).Улучшенное сообщение об исключении при вызове
.ilocили.locс булевым индексатором другой длины (GH 26658).Ошибка в
KeyErrorсообщение об исключении при индексацииMultiIndexс несуществующим ключом, не отображающим исходный ключ (GH 27250).Ошибка в
.ilocи.locс булевым индексатором, не вызывающимIndexErrorкогда передано слишком мало элементов (GH 26658).Ошибка в
DataFrame.loc()иSeries.loc()гдеKeyErrorне было вызвано дляMultiIndexкогда ключ был меньше или равен количеству уровней вMultiIndex(GH 14885).Ошибка, при которой
DataFrame.append()выдавало ошибочное предупреждение, указывающее, чтоKeyErrorбудет выброшено в будущем, когда добавляемые данные содержат новые столбцы (GH 22252).Ошибка, при которой
DataFrame.to_csv()вызывал ошибку сегментации для переиндексированного фрейма данных, когда индексы были одноуровневымиMultiIndex(GH 26303).Исправлена ошибка, при которой присваивание
arrays.PandasArrayвDataFrameвызовет ошибку (GH 26390)Разрешить ключевые аргументы для вызываемой локальной ссылки, используемой в
DataFrame.query()строка (GH 26426)Исправлена
KeyErrorпри индексацииMultiIndexуровень со списком, содержащим ровно одну метку, которая отсутствует (GH 27148)Ошибка, которая вызывала
AttributeErrorо частичном совпаденииTimestampвMultiIndex(GH 26944)Ошибка в
CategoricalиCategoricalIndexсIntervalзначения при использованииinоператор (__contains) с объектами, которые несопоставимы со значениями вInterval(GH 23705)Ошибка в
DataFrame.loc()иDataFrame.iloc()наDataFrameс одним столбцом datetime64[ns] с учетом часового пояса, ошибочно возвращающим скаляр вместоSeries(GH 27110)Ошибка в
CategoricalIndexиCategoricalнекорректное возбуждениеValueErrorвместоTypeErrorкогда список передается с использованиемinоператор (__contains__) (GH 21729)Ошибка при установке нового значения в
SeriesсTimedeltaобъект некорректно преобразует значение в целое число (GH 22717)Ошибка в
Seriesустановка нового ключа (__setitem__) с datetime с учетом часового пояса, некорректно вызывающийValueError(GH 12862)Ошибка в
DataFrame.iloc()при индексировании с помощью доступного только для чтения индексатора (GH 17192)Ошибка в
Seriesустановка существующего ключа-кортежа (__setitem__) с datetime значениями с часовым поясом ошибочно вызываетTypeError(GH 20441)
Отсутствует#
Исправлено вводящее в заблуждение сообщение об исключении в
Series.interpolate()если аргументorderтребуется, но опущен (GH 10633, GH 24014).Исправлен тип класса, отображаемый в сообщении об исключении в
DataFrame.dropna()если недействителенaxisпереданный параметр (GH 25555)A
ValueErrorтеперь будет вызыватьсяDataFrame.fillna()когдаlimitне является положительным целым числом (GH 27042)
MultiIndex#
Ошибка, при которой вызывается некорректное исключение
Timedeltaпри проверке принадлежностиMultiIndex(GH 24570)
Ввод-вывод#
Ошибка в
DataFrame.to_html()где значения были усечены с использованием параметров отображения вместо вывода полного содержимого (GH 17004)Исправлена ошибка с отсутствующим текстом при использовании
to_clipboard()при копировании символов utf-16 в Python 3 на Windows (GH 25040)Ошибка в
read_json()дляorient='table'когда он пытается определить типы данных по умолчанию, что неприменимо, так как типы данных уже определены в схеме JSON (GH 21345)Ошибка в
read_json()дляorient='table'и индекс с плавающей точкой, так как он выводит тип данных индекса по умолчанию, что неприменимо, потому что тип данных индекса уже определен в схеме JSON (GH 25433)Ошибка в
read_json()дляorient='table'и строку имен столбцов float, так как это преобразует тип имени столбца вTimestamp, что неприменимо, поскольку имена столбцов уже определены в схеме JSON (GH 25435)Ошибка в
json_normalize()дляerrors='ignore'где пропущенные значения во входных данных были заполнены в результатеDataFrameсо строкой"nan"вместоnumpy.nan(GH 25468)DataFrame.to_html()теперь вызываетTypeErrorпри использовании недопустимого типа дляclassesпараметр вместоAssertionError(GH 25608)Ошибка в
DataFrame.to_string()иDataFrame.to_latex()что привело бы к некорректному выводу, когдаheaderиспользуется ключевое слово (GH 16718)Ошибка в
read_csv()неправильная интерпретация имен файлов, закодированных в UTF8, в Windows на Python 3.6+ (GH 15086)Улучшена производительность в
pandas.read_stata()иpandas.io.stata.StataReaderпри преобразовании столбцов с пропущенными значениями (GH 25772)Ошибка в
DataFrame.to_html()где номера заголовков игнорировали параметры отображения при округлении (GH 17280)Ошибка в
read_hdf()где чтение таблицы из файла HDF5, записанного напрямую с помощью PyTables, завершается ошибкойValueErrorпри использовании частичного выбора черезstartилиstopаргументы (GH 11188)Ошибка в
read_hdf()неправильное закрытие хранилища послеKeyErrorвозникает (GH 25766)Улучшено объяснение ошибки при повторяющихся метках значений в файлах Stata dta и предложены обходные пути (GH 25772)
Улучшено
pandas.read_stata()иpandas.io.stata.StataReaderдля чтения неправильно отформатированных файлов формата 118, сохраненных Stata (GH 25960)Улучшен
col_spaceпараметр вDataFrame.to_html()принимать строку, чтобы значения длины CSS могли быть установлены корректно (GH 25941)Исправлена ошибка при загрузке объектов из S3, содержащих
#символы в URL (GH 25945)Добавляет
use_bqstorage_apiпараметр дляread_gbq()для ускорения загрузки больших фреймов данных. Эта функция требует версии 0.10.0pandas-gbqбиблиотека, а такжеgoogle-cloud-bigquery-storageиfastavroбиблиотек. (GH 26104)Исправлена утечка памяти в
DataFrame.to_json()при работе с числовыми данными (GH 24889)Ошибка в
read_json()где строки дат сZне были преобразованы в часовой пояс UTC (GH 26168)Добавлен
cache_dates=Trueпараметр дляread_csv(), что позволяет кэшировать уникальные даты при их разборе (GH 25990)DataFrame.to_excel()теперь вызываетValueErrorкогда размеры вызывающего объекта превышают ограничения Excel (GH 26051)Исправлена ошибка в
pandas.read_csv()где BOM приводил к некорректному разбору при использовании engine='python' (GH 26545)read_excel()теперь вызываетValueErrorкогда входные данные имеют типpandas.io.excel.ExcelFileиengineпараметр передаётся, так какpandas.io.excel.ExcelFileимеет определенный движок (GH 26566)Ошибка при выборе из
HDFStoreсwhere=''указано (GH 26610).Исправлена ошибка в
DataFrame.to_excel()где пользовательские объекты (т.е.PeriodIndex) внутри объединенных ячеек не преобразовывались в типы, безопасные для записи в Excel (GH 27006)Ошибка в
read_hdf()где чтение данных с учетом часового поясаDatetimeIndexвызоветTypeError(GH 11926)Ошибка в
to_msgpack()иread_msgpack()что вызвало быValueErrorа неFileNotFoundErrorдля недопустимого пути (GH 27160)Исправлена ошибка в
DataFrame.to_parquet()что вызвало быValueErrorкогда фрейм данных не имел столбцов (GH 27339)Разрешить парсинг
PeriodDtypeстолбцов при использованииread_csv()(GH 26934)
Построение графиков#
Исправлена ошибка, где
api.extensions.ExtensionArrayне могли использоваться в построении графиков matplotlib (GH 25587)Ошибка в сообщении об ошибке в
DataFrame.plot(). Улучшено сообщение об ошибке, если вDataFrame.plot()(GH 25481)Ошибка в неправильных позициях меток делений при построении индекса, который не является числовым/не является датой и временем (GH 7612, GH 15912, GH 22334)
Исправлена ошибка, вызывающая построение графиков
PeriodIndexвременных рядов ошибку, если частота кратна коду правила частоты (GH 14763)Исправлена ошибка при построении графика
DatetimeIndexсdatetime.timezone.utctimezone (GH 17173)
GroupBy/resample/rolling#
Ошибка в
Resampler.agg()с индексом, учитывающим часовой пояс, гдеOverflowErrorвызывало ошибку при передаче списка функций (GH 22660)Ошибка в
DataFrameGroupBy.nunique()в котором были потеряны имена уровней столбцов (GH 23222)Ошибка в
GroupBy.agg()при применении агрегирующей функции к данным с учетом часового пояса (GH 23683)Ошибка в
GroupBy.first()иGroupBy.last()где информация о часовом поясе будет удалена (GH 21603)Ошибка в
GroupBy.size()при группировке только значений NA (GH 23050)Ошибка в
Series.groupby()гдеobservedkwarg ранее игнорировался (GH 24880)Ошибка в
Series.groupby()где использованиеgroupbyсMultiIndexSeries со списком меток, равным длине серии, вызывал некорректную группировку (GH 25704)Обеспечено, что порядок вывода в
groupbyфункции агрегации согласованы во всех версиях Python (GH 25692)Обеспечено, что порядок групп результата корректен при группировке по упорядоченному
Categoricalи указаниеobserved=True(GH 25871, GH 25167)Ошибка в
Rolling.min()иRolling.max()который вызывал утечку памяти (GH 25893)Ошибка в
Rolling.count()и.Expanding.countранее игнорировалaxisключевое слово (GH 13503)Ошибка в
GroupBy.idxmax()иGroupBy.idxmin()с datetime столбцом возвращал неправильный тип данных (GH 25444, GH 15306)Ошибка в
GroupBy.cumsum(),GroupBy.cumprod(),GroupBy.cummin()иGroupBy.cummax()с категориальной колонкой, имеющей отсутствующие категории, возвращал неверный результат или вызывал segfault (GH 16771)Ошибка в
GroupBy.nth()где NA-значения в группировке возвращали бы некорректные результаты (GH 26011)Ошибка в
SeriesGroupBy.transform()где преобразование пустой группы вызвало быValueError(GH 26208)Ошибка в
DataFrame.groupby()где передачаGrouperвернёт некорректные группы при использовании.groupsаксессор (GH 26326)Ошибка в
GroupBy.agg()где возвращаются некорректные результаты для столбцов uint64. (GH 26310)Ошибка в
Rolling.median()иRolling.quantile()где MemoryError возникает с пустым окном (GH 26005)Ошибка в
Rolling.median()иRolling.quantile()где возвращаются некорректные результаты сclosed='left'иclosed='neither'(GH 26005)Улучшено
Rolling,WindowиExponentialMovingWindowфункции для исключения нежелательных столбцов из результатов вместо вызова ошибок и вызываютDataErrorтолько если все столбцы являются несущественными (GH 12537)Ошибка в
Rolling.max()иRolling.min()где возвращаются некорректные результаты с пустым переменным окном (GH 26005)Выдать полезное исключение, когда неподдерживаемая взвешенная оконная функция используется в качестве аргумента
Window.aggregate()(GH 26597)
Изменение формы#
Ошибка в
pandas.merge()добавляет строкуNone, еслиNoneназначается в суффиксах вместо сохранения имени столбца как есть (GH 24782).Ошибка в
merge()при слиянии по имени индекса иногда приводило к некорректно пронумерованному индексу (пропущенные значения индекса теперь присваиваются NA) (GH 24212, GH 25009)to_records()теперь принимает dtypes в свойcolumn_dtypesпараметр (GH 24895)Ошибка в
concat()где порядокOrderedDict(иdictв Python 3.6+) не соблюдается, когда передается какobjsаргумент (GH 21510)Ошибка в
pivot_table()где столбцы сNaNзначения удаляются, даже еслиdropnaаргумент являетсяFalse, когдаaggfuncаргумент содержитlist(GH 22159)Ошибка в
concat()где результирующийfreqиз двухDatetimeIndexс тем жеfreqбудут удалены (GH 3232).Ошибка в
merge()где слияние с эквивалентными категориальными типами данных вызывало ошибку (GH 22501)ошибка в
DataFrameсоздание экземпляра со словарем итераторов или генераторов (например,pd.DataFrame({'A': reversed(range(3))})) вызывал ошибку (GH 26349).Ошибка в
DataFrameсоздание экземпляра сrange(например,pd.DataFrame(range(3))) вызывал ошибку (GH 26342).Ошибка в
DataFrameконструкторе при передаче непустых кортежей, что вызывало ошибку сегментации (GH 25691)Ошибка в
Series.apply()не удалось, когда серия учитывает часовой поясDatetimeIndex(GH 25959)Ошибка в
pandas.cut()где большие интервалы могли некорректно вызывать ошибку из-за переполнения целого числа (GH 26045)Ошибка в
DataFrame.sort_index()где возникает ошибка при работе с мультииндексированнымDataFrameсортируется по всем уровням с начальным уровнем, отсортированным последним (GH 26053)Ошибка в
Series.nlargest()обрабатываетTrueкак меньший, чемFalse(GH 26154)Ошибка в
DataFrame.pivot_table()сIntervalIndexкак индекс сводной таблицы вызывал быTypeError(GH 25814)Ошибка, при которой
DataFrame.from_dict()игнорировал порядокOrderedDictкогдаorient='index'(GH 8425).Ошибка в
DataFrame.transpose()где транспонирование DataFrame со столбцом datetime с учётом часового пояса некорректно вызывало ошибкуValueError(GH 26825)Ошибка в
pivot_table()при сводной таблице столбца с учетом часового пояса какvaluesудалит информацию о часовом поясе (GH 14948)Ошибка в
merge_asof()при указании несколькихbyстолбцы, где один являетсяdatetime64[ns, tz]тип данных (GH 26649)
Разреженный#
Значительное ускорение в
SparseArrayинициализации, которая приносит пользу большинству операций, исправляя регрессию производительности, введённую в v0.20.0 (GH 24985)Ошибка в
SparseFrameконструктор, где передачаNoneкак данные вызвали быdefault_fill_valueигнорируется (GH 16807)Ошибка в
SparseDataFrameпри добавлении столбца, в котором длина значений не соответствует длине индекса,AssertionErrorвызывается вместо вызоваValueError(GH 25484)Ввести более понятное сообщение об ошибке в
Series.sparse.from_coo()так что возвращаетTypeErrorдля входных данных, которые не являются матрицами coo (GH 26554)Ошибка в
numpy.modf()наSparseArray. Теперь кортеж изSparseArrayвозвращается (GH 26946).
Изменения сборки#
Исправлена ошибка установки с PyPy на macOS (GH 26536)
ExtensionArray#
Ошибка в
factorize()при передачеExtensionArrayс пользовательскимna_sentinel(GH 25696).Series.count()неправильно подсчитывает значения NA в ExtensionArrays (GH 26835)Добавлен
Series.__array_ufunc__для лучшей обработки NumPy ufuncs, применённых к Series, поддерживаемым массивами расширений (GH 23293).Ключевой аргумент
deepбыл удален изExtensionArray.copy()(GH 27083)
Другие#
Удалены неиспользуемые C-функции из вендорной реализации UltraJSON (GH 26198)
Разрешить
IndexиRangeIndexдля передачи в numpyminиmaxфункции (GH 26125)Используйте фактическое имя класса в repr пустых объектов
Seriesподкласс (GH 27001).Ошибка в
DataFrameгде передача массива объектов с учетом часового поясаdatetimeобъекты некорректно вызывалиValueError(GH 13287)
Участники#
Всего 231 человек внесли патчи в этот релиз. Люди со знаком «+» рядом с именами внесли патч впервые.
1_x7 +
Abdullah İhsan Seçer +
Adam Bull +
Adam Hooper
Albert Villanova del Moral
Alex Watt +
AlexTereshenkov +
Alexander Buchkovsky
Александр Хендорф +
Александр Нордин +
Alexander Ponomaroff
Александр Батисс +
Александр Декан +
Allen Downey +
Alyssa Fu Ward +
Эндрю Гаспари +
Andrew Wood +
Antoine Viscardi +
Antonio Gutierrez +
Arno Veenstra +
ArtinSarraf
Batalex +
Baurzhan Muftakhidinov
Benjamin Rowell
Бхарат Рагхунатан +
Бхавани Рави +
Big Head +
Brett Randall +
Bryan Cutler +
C John Klehm +
Caleb Braun +
Cecilia +
Chris Bertinato +
Chris Stadler +
Christian Haege +
Christian Hudon
Кристофер Уилан
Chuanzhu Xu +
Clemens Brunner
Damian Kula +
Daniel Hrisca +
Daniel Luis Costa +
Daniel Saxton
DanielFEvans +
David Liu +
Дипьяман Датта +
Denis Belavin +
Devin Petersohn +
Diane Trout +
EdAbati +
Enrico Rotundo +
EternalLearner42 +
Evan +
Evan Livelo +
Fabian Rost +
Flavien Lambert +
Florian Rathgeber +
Frank Hoang +
Gaibo Zhang +
Gioia Ballin
Giuseppe Romagnuolo +
Гордон Блэкэддер +
Gregory Rome +
Guillaume Gay
HHest +
Hielke Walinga +
Как Си Вэй +
Hubert
Huize Wang +
Hyukjin Kwon +
Ian Dunn +
Inevitable-Marzipan +
Ирв Ластиг
JElfner +
Jacob Bundgaard +
Джеймс Кобон-Керр +
Ян-Филипп Герке +
Jarrod Millman +
Jayanth Katuri +
Jeff Reback
Jeremy Schendel
Jiang Yue +
Joel Ostblom
Johan von Forstner +
Johnny Chiu +
Jonas +
Jonathon Vandezande +
Jop Vermeer +
Joris Van den Bossche
Josh
GH 15670
Джастин Чжэн
Kaiqi Dong
Кейн +
Kapil Patel +
Kara de la Marck +
Кэтрин Сурта +
Katrin Leinweber +
Kendall Masse
Кевин Шеппард
Kyle Kosic +
Lorenzo Stella +
Maarten Rietbergen +
Mak Sze Chun
Марк Гарсия
Mateusz Woś
Matias Heikkilä
Mats Maiwald +
Мэтью Рёшке
Max Bolingbroke +
Макс Ковалёвс +
Max van Deursen +
Майкл
Michael Davis +
Michael P. Moran +
Mike Cramblett +
Min ho Kim +
Misha Veldhoen +
Mukul Ashwath Ram +
MusTheDataGuy +
Nanda H Krishna +
Nicholas Musolino
Ноам Херштиг +
Noora Husseini +
Paul
Пол Риди
Pauli Virtanen
Pav A +
Peter Leimbigler +
Philippe Ombredanne +
Пьетро Баттистон
Richard Eames +
Roman Yurchak
Ruijing Li
Ryan
Ryan Joyce +
Ryan Nazareth
Ryan Rehman +
Sakar Panta +
Samuel Sinayoko
Сандип Патхак +
Sangwoong Yoon
Saurav Chakravorty
Scott Talbert +
Sergey Kopylov +
Shantanu Gontia +
Shivam Rana +
Shorokhov Sergey +
Simon Hawkins
Soyoun(Rose) Kim
Stephan Hoyer
Stephen Cowley +
Stephen Rauch
Sterling Paramore +
Steven +
Stijn Van Hoey
Sumanau Sareen +
Takuya N +
Тан Тран +
Tao He +
Tarbo Fukazawa
Terji Petersen +
Тейн У
ThibTrip +
Thijs Damsma +
Thiviyan Thanapalasingam
Thomas A Caswell
Thomas Kluiters +
Tilen Kusterle +
Tim Gates +
Tim Hoffmann
Tim Swast
Tom Augspurger
Tom Neep +
Tomáš Chvátal +
Tyler Reddy
Вайбхав Вишал +
Vasily Litvinov +
Vibhu Agarwal +
Викрамджит Дас +
Vladislav +
Víctor Moron Tejero +
Wenhuan
Will Ayd +
William Ayd
Wouter De Coster +
Yoann Goular +
Zach Angell +
alimcmaster1
anmyachev +
chris-b1
danielplawrence +
endenis +
enisnazif +
ezcitron +
fjetter
froessler
gfyoung
gwrome +
h-vetinari
haison +
hannah-c +
heckeop +
iamshwin +
jamesoliverh +
jbrockmendel
jkovacevic +
killerontherun1 +
knuu +
kpapdac +
kpflugshaupt +
krsnik93 +
leerssej +
lrjball +
mazayo +
nathalier +
nrebena +
nullptr +
pilkibun +
pmaxey83 +
rbenes +
robbuckley
shawnbrown +
sudhir mohanraj +
tadeja +
tamuhey +
thatneat
topper-123
willweil +
yehia67 +
yhaque1213 +