Версия 0.19.0 (2 октября 2016)#
Это основной выпуск с версии 0.18.1 и включает ряд изменений API, несколько новых функций, улучшений и оптимизаций производительности вместе с большим количеством исправлений ошибок. Мы рекомендуем всем пользователям обновиться до этой версии.
Основные моменты включают:
merge_asof()для соединения временных рядов в стиле asof, см. здесь.rolling()теперь учитывает временные ряды, см. здесьread_csv()теперь поддерживает парсингCategoricalданные, см. здесьФункция
union_categorical()был добавлен для объединения категориальных переменных, см. здесьPeriodIndexтеперь имеет свой собственныйperiodтип данных и изменён для большей согласованности с другимиIndexклассы. См. здесьРазреженные структуры данных получили улучшенную поддержку
intиboolтипы данных, см. здесьОперации сравнения с
Seriesбольше не игнорирует индекс, см. здесь для обзора изменений в API.Введение API разработки pandas для служебных функций, см. здесь.
Устаревание
Panel4DиPanelND. Мы рекомендуем представлять такие типы n-мерных данных с помощью пакет xarray.Удаление ранее устаревших модулей
pandas.io.data,pandas.io.wb,pandas.tools.rplot.
Предупреждение
pandas >= 0.19.0 больше не будет подавлять предупреждения numpy ufunc при импорте, см. здесь.
Что нового в v0.19.0
Новые возможности#
Функция merge_asof для объединения временных рядов в стиле asof#
Долгожданная функция была добавлена через merge_asof() функция для поддержки соединения временных рядов в стиле asof (GH 1870, GH 13695, GH 13709, GH 13902). Полная документация
здесь.
The merge_asof() выполняет слияние asof, которое похоже на левое соединение,
за исключением того, что мы сопоставляем по ближайшему ключу, а не по равным ключам.
In [1]: left = pd.DataFrame({"a": [1, 5, 10], "left_val": ["a", "b", "c"]})
In [2]: right = pd.DataFrame({"a": [1, 2, 3, 6, 7], "right_val": [1, 2, 3, 6, 7]})
In [3]: left
Out[3]:
a left_val
0 1 a
1 5 b
2 10 c
[3 rows x 2 columns]
In [4]: right
Out[4]:
a right_val
0 1 1
1 2 2
2 3 3
3 6 6
4 7 7
[5 rows x 2 columns]
Обычно мы хотим точно сопоставлять, когда это возможно, и использовать наиболее недавнее значение в противном случае.
In [5]: pd.merge_asof(left, right, on="a")
Out[5]:
a left_val right_val
0 1 a 1
1 5 b 3
2 10 c 7
[3 rows x 3 columns]
Мы также можем сопоставлять строки ТОЛЬКО с предыдущими данными, а не точное совпадение.
In [6]: pd.merge_asof(left, right, on="a", allow_exact_matches=False)
Out[6]:
a left_val right_val
0 1 a NaN
1 5 b 3.0
2 10 c 7.0
[3 rows x 3 columns]
В типичном примере временного ряда у нас есть trades и quotes и мы хотим asof-join их.
Это также иллюстрирует использование by параметр для группировки данных перед слиянием.
In [7]: trades = pd.DataFrame(
...: {
...: "time": pd.to_datetime(
...: [
...: "20160525 13:30:00.023",
...: "20160525 13:30:00.038",
...: "20160525 13:30:00.048",
...: "20160525 13:30:00.048",
...: "20160525 13:30:00.048",
...: ]
...: ),
...: "ticker": ["MSFT", "MSFT", "GOOG", "GOOG", "AAPL"],
...: "price": [51.95, 51.95, 720.77, 720.92, 98.00],
...: "quantity": [75, 155, 100, 100, 100],
...: },
...: columns=["time", "ticker", "price", "quantity"],
...: )
...:
In [8]: quotes = pd.DataFrame(
...: {
...: "time": pd.to_datetime(
...: [
...: "20160525 13:30:00.023",
...: "20160525 13:30:00.023",
...: "20160525 13:30:00.030",
...: "20160525 13:30:00.041",
...: "20160525 13:30:00.048",
...: "20160525 13:30:00.049",
...: "20160525 13:30:00.072",
...: "20160525 13:30:00.075",
...: ]
...: ),
...: "ticker": ["GOOG", "MSFT", "MSFT", "MSFT", "GOOG", "AAPL", "GOOG", "MSFT"],
...: "bid": [720.50, 51.95, 51.97, 51.99, 720.50, 97.99, 720.50, 52.01],
...: "ask": [720.93, 51.96, 51.98, 52.00, 720.93, 98.01, 720.88, 52.03],
...: },
...: columns=["time", "ticker", "bid", "ask"],
...: )
...:
In [9]: trades
Out[9]:
time ticker price quantity
0 2016-05-25 13:30:00.023 MSFT 51.95 75
1 2016-05-25 13:30:00.038 MSFT 51.95 155
2 2016-05-25 13:30:00.048 GOOG 720.77 100
3 2016-05-25 13:30:00.048 GOOG 720.92 100
4 2016-05-25 13:30:00.048 AAPL 98.00 100
[5 rows x 4 columns]
In [10]: quotes
Out[10]:
time ticker bid ask
0 2016-05-25 13:30:00.023 GOOG 720.50 720.93
1 2016-05-25 13:30:00.023 MSFT 51.95 51.96
2 2016-05-25 13:30:00.030 MSFT 51.97 51.98
3 2016-05-25 13:30:00.041 MSFT 51.99 52.00
4 2016-05-25 13:30:00.048 GOOG 720.50 720.93
5 2016-05-25 13:30:00.049 AAPL 97.99 98.01
6 2016-05-25 13:30:00.072 GOOG 720.50 720.88
7 2016-05-25 13:30:00.075 MSFT 52.01 52.03
[8 rows x 4 columns]
Объединение asof соединяет по on, обычно поле типа даты-времени, которое упорядочено, и в этом случае мы используем группировщик в by поля. Это похоже на левое внешнее соединение, за исключением того, что прямое заполнение происходит автоматически, беря самое последнее не-NaN значение.
In [11]: pd.merge_asof(trades, quotes, on="time", by="ticker")
Out[11]:
time ticker price quantity bid ask
0 2016-05-25 13:30:00.023 MSFT 51.95 75 51.95 51.96
1 2016-05-25 13:30:00.038 MSFT 51.95 155 51.97 51.98
2 2016-05-25 13:30:00.048 GOOG 720.77 100 720.50 720.93
3 2016-05-25 13:30:00.048 GOOG 720.92 100 720.50 720.93
4 2016-05-25 13:30:00.048 AAPL 98.00 100 NaN NaN
[5 rows x 6 columns]
Это возвращает объединенный DataFrame с записями в том же порядке, что и исходный переданный левый DataFrame (trades в этом случае), с полями quotes объединено.
Метод .rolling() теперь учитывает временные ряды#
.rolling() объекты теперь учитывают временные ряды и могут принимать смещение временного ряда (или конвертируемое) для window аргумент (GH 13327, GH 12995).
См. полную документацию здесь.
In [12]: dft = pd.DataFrame(
....: {"B": [0, 1, 2, np.nan, 4]},
....: index=pd.date_range("20130101 09:00:00", periods=5, freq="s"),
....: )
....:
In [13]: dft
Out[13]:
B
2013-01-01 09:00:00 0.0
2013-01-01 09:00:01 1.0
2013-01-01 09:00:02 2.0
2013-01-01 09:00:03 NaN
2013-01-01 09:00:04 4.0
[5 rows x 1 columns]
Это обычный индекс частоты. Использование целочисленного параметра окна работает для скольжения по частоте окна.
In [14]: dft.rolling(2).sum()
Out[14]:
B
2013-01-01 09:00:00 NaN
2013-01-01 09:00:01 1.0
2013-01-01 09:00:02 3.0
2013-01-01 09:00:03 NaN
2013-01-01 09:00:04 NaN
[5 rows x 1 columns]
In [15]: dft.rolling(2, min_periods=1).sum()
Out[15]:
B
2013-01-01 09:00:00 0.0
2013-01-01 09:00:01 1.0
2013-01-01 09:00:02 3.0
2013-01-01 09:00:03 2.0
2013-01-01 09:00:04 4.0
[5 rows x 1 columns]
Указание смещения позволяет более интуитивно задавать частоту скользящего окна.
In [16]: dft.rolling("2s").sum()
Out[16]:
B
2013-01-01 09:00:00 0.0
2013-01-01 09:00:01 1.0
2013-01-01 09:00:02 3.0
2013-01-01 09:00:03 2.0
2013-01-01 09:00:04 4.0
[5 rows x 1 columns]
Использование нерегулярного, но всё же монотонного индекса с целочисленным окном при скользящих операциях не даёт особых преимуществ в вычислениях.
In [17]: dft = pd.DataFrame(
....: {"B": [0, 1, 2, np.nan, 4]},
....: index=pd.Index(
....: [
....: pd.Timestamp("20130101 09:00:00"),
....: pd.Timestamp("20130101 09:00:02"),
....: pd.Timestamp("20130101 09:00:03"),
....: pd.Timestamp("20130101 09:00:05"),
....: pd.Timestamp("20130101 09:00:06"),
....: ],
....: name="foo",
....: ),
....: )
....:
In [18]: dft
Out[18]:
B
foo
2013-01-01 09:00:00 0.0
2013-01-01 09:00:02 1.0
2013-01-01 09:00:03 2.0
2013-01-01 09:00:05 NaN
2013-01-01 09:00:06 4.0
[5 rows x 1 columns]
In [19]: dft.rolling(2).sum()
Out[19]:
B
foo
2013-01-01 09:00:00 NaN
2013-01-01 09:00:02 1.0
2013-01-01 09:00:03 3.0
2013-01-01 09:00:05 NaN
2013-01-01 09:00:06 NaN
[5 rows x 1 columns]
Использование спецификации времени генерирует переменные окна для этих разреженных данных.
In [20]: dft.rolling("2s").sum()
Out[20]:
B
foo
2013-01-01 09:00:00 0.0
2013-01-01 09:00:02 1.0
2013-01-01 09:00:03 3.0
2013-01-01 09:00:05 NaN
2013-01-01 09:00:06 4.0
[5 rows x 1 columns]
Кроме того, теперь мы разрешаем необязательный on параметр для указания столбца (вместо
индекса по умолчанию) в DataFrame.
In [21]: dft = dft.reset_index()
In [22]: dft
Out[22]:
foo B
0 2013-01-01 09:00:00 0.0
1 2013-01-01 09:00:02 1.0
2 2013-01-01 09:00:03 2.0
3 2013-01-01 09:00:05 NaN
4 2013-01-01 09:00:06 4.0
[5 rows x 2 columns]
In [23]: dft.rolling("2s", on="foo").sum()
Out[23]:
foo B
0 2013-01-01 09:00:00 0.0
1 2013-01-01 09:00:02 1.0
2 2013-01-01 09:00:03 3.0
3 2013-01-01 09:00:05 NaN
4 2013-01-01 09:00:06 4.0
[5 rows x 2 columns]
Метод read_csv имеет улучшенную поддержку дублирующихся имён столбцов#
Дублирующиеся имена столбцов теперь поддерживаются в read_csv() находятся ли
они в файле или переданы как names параметр (GH 7160, GH 9424)
In [24]: data = "0,1,2\n3,4,5"
In [25]: names = ["a", "b", "a"]
Предыдущее поведение:
In [2]: pd.read_csv(StringIO(data), names=names)
Out[2]:
a b a
0 2 1 2
1 5 4 5
Первый a столбец содержал те же данные, что и второй a столбец, когда он должен был
содержать значения [0, 3].
Новое поведение:
In [26]: pd.read_csv(StringIO(data), names=names)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[26], line 1
----> 1 pd.read_csv(StringIO(data), names=names)
File ~/work/pandas/pandas/pandas/io/parsers/readers.py:1026, in read_csv(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, date_format, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, encoding_errors, dialect, on_bad_lines, delim_whitespace, low_memory, memory_map, float_precision, storage_options, dtype_backend)
1013 kwds_defaults = _refine_defaults_read(
1014 dialect,
1015 delimiter,
(...)
1022 dtype_backend=dtype_backend,
1023 )
1024 kwds.update(kwds_defaults)
-> 1026 return _read(filepath_or_buffer, kwds)
File ~/work/pandas/pandas/pandas/io/parsers/readers.py:617, in _read(filepath_or_buffer, kwds)
614 nrows = kwds.get("nrows", None)
616 # Check for duplicates in names.
--> 617 _validate_names(kwds.get("names", None))
619 # Create the parser.
620 parser = TextFileReader(filepath_or_buffer, **kwds)
File ~/work/pandas/pandas/pandas/io/parsers/readers.py:576, in _validate_names(names)
574 if names is not None:
575 if len(names) != len(set(names)):
--> 576 raise ValueError("Duplicate names are not allowed.")
577 if not (
578 is_list_like(names, allow_sets=False) or isinstance(names, abc.KeysView)
579 ):
580 raise ValueError("Names should be an ordered collection.")
ValueError: Duplicate names are not allowed.
Метод read_csv поддерживает разбор Categorical напрямую#
The read_csv() функция теперь поддерживает парсинг Categorical столбец, когда
указан как тип данных (GH 10153). В зависимости от структуры данных это может привести к более быстрому времени разбора и меньшему использованию памяти по сравнению с преобразованием в Categorical после парсинга. См. модуль io документация здесь.
In [27]: data = """
....: col1,col2,col3
....: a,b,1
....: a,b,2
....: c,d,3
....: """
....:
In [28]: pd.read_csv(StringIO(data))
Out[28]:
col1 col2 col3
0 a b 1
1 a b 2
2 c d 3
[3 rows x 3 columns]
In [29]: pd.read_csv(StringIO(data)).dtypes
Out[29]:
col1 object
col2 object
col3 int64
Length: 3, dtype: object
In [30]: pd.read_csv(StringIO(data), dtype="category").dtypes
Out[30]:
col1 category
col2 category
col3 category
Length: 3, dtype: object
Отдельные столбцы могут быть разобраны как Categorical используя спецификацию словаря
In [31]: pd.read_csv(StringIO(data), dtype={"col1": "category"}).dtypes
Out[31]:
col1 category
col2 object
col3 int64
Length: 3, dtype: object
Примечание
Результирующие категории всегда будут парситься как строки (тип object).
Если категории числовые, их можно преобразовать с помощью
to_numeric() функция, или, если уместно, другой конвертер
такой как to_datetime().
In [32]: df = pd.read_csv(StringIO(data), dtype="category")
In [33]: df.dtypes
Out[33]:
col1 category
col2 category
col3 category
Length: 3, dtype: object
In [34]: df["col3"]
Out[34]:
0 1
1 2
2 3
Name: col3, Length: 3, dtype: category
Categories (3, object): ['1', '2', '3']
In [35]: new_categories = pd.to_numeric(df["col3"].cat.categories)
In [36]: df["col3"] = df["col3"].cat.rename_categories(new_categories)
In [37]: df["col3"]
Out[37]:
0 1
1 2
2 3
Name: col3, Length: 3, dtype: category
Categories (3, int64): [1, 2, 3]
Конкатенация категориальных переменных#
Функция
union_categoricals()был добавлен для объединения категориальных переменных, см. Объединение категориальных переменных (GH 13361, GH 13763, GH 13846, GH 14173)In [38]: from pandas.api.types import union_categoricals In [39]: a = pd.Categorical(["b", "c"]) In [40]: b = pd.Categorical(["a", "b"]) In [41]: union_categoricals([a, b]) Out[41]: ['b', 'c', 'a', 'b'] Categories (3, object): ['b', 'c', 'a']
concatиappendтеперь может объединятьcategoryтипы данных с разнымиcategoriesкакobjectтип данных (GH 13524)In [42]: s1 = pd.Series(["a", "b"], dtype="category") In [43]: s2 = pd.Series(["b", "c"], dtype="category")
Предыдущее поведение:
In [1]: pd.concat([s1, s2])
ValueError: incompatible categories in categorical concat
Новое поведение:
In [44]: pd.concat([s1, s2])
Out[44]:
0 a
1 b
0 b
1 c
Length: 4, dtype: object
Полумесячные смещения#
pandas получил новые частотные смещения, SemiMonthEnd ('SM') и SemiMonthBegin (‘SMS’).
Они предоставляют смещения дат, привязанные (по умолчанию) к 15-му и концу месяца, а также к 15-му и 1-му числу месяца соответственно.
(GH 1543)
In [45]: from pandas.tseries.offsets import SemiMonthEnd, SemiMonthBegin
SemiMonthEnd:
In [46]: pd.Timestamp("2016-01-01") + SemiMonthEnd()
Out[46]: Timestamp('2016-01-15 00:00:00')
In [47]: pd.date_range("2015-01-01", freq="SM", periods=4)
Out[47]: DatetimeIndex(['2015-01-15', '2015-01-31', '2015-02-15', '2015-02-28'], dtype='datetime64[ns]', freq='SM-15')
SemiMonthBegin:
In [46]: pd.Timestamp("2016-01-01") + SemiMonthBegin()
Out[46]: Timestamp('2016-01-15 00:00:00')
In [47]: pd.date_range("2015-01-01", freq="SMS", periods=4)
Out[47]: DatetimeIndex(['2015-01-01', '2015-01-15', '2015-02-01', '2015-02-15'], dtype='datetime64[ns]', freq='SMS-15')
Используя суффикс привязки, вы также можете указать день месяца для использования вместо 15-го.
In [50]: pd.date_range("2015-01-01", freq="SMS-16", periods=4)
Out[50]: DatetimeIndex(['2015-01-01', '2015-01-16', '2015-02-01', '2015-02-16'], dtype='datetime64[ns]', freq='SMS-16')
In [51]: pd.date_range("2015-01-01", freq="SM-14", periods=4)
Out[51]: DatetimeIndex(['2015-01-14', '2015-01-31', '2015-02-14', '2015-02-28'], dtype='datetime64[ns]', freq='SM-14')
Новые методы Index#
Следующие методы и опции добавлены в Index, чтобы быть более согласованными с Series и DataFrame API.
Index теперь поддерживает .where() функция для индексации с одинаковой формой (GH 13170)
In [48]: idx = pd.Index(["a", "b", "c"])
In [49]: idx.where([True, False, True])
Out[49]: Index(['a', None, 'c'], dtype='object')
Index теперь поддерживает .dropna() чтобы исключить пропущенные значения (GH 6194)
In [50]: idx = pd.Index([1, 2, np.nan, 4])
In [51]: idx.dropna()
Out[51]: Index([1.0, 2.0, 4.0], dtype='float64')
Для MultiIndex, значения удаляются, если любой уровень отсутствует по умолчанию. Указание
how='all' удаляет только значения, где отсутствуют все уровни.
In [52]: midx = pd.MultiIndex.from_arrays([[1, 2, np.nan, 4], [1, 2, np.nan, np.nan]])
In [53]: midx
Out[53]:
MultiIndex([(1.0, 1.0),
(2.0, 2.0),
(nan, nan),
(4.0, nan)],
)
In [54]: midx.dropna()
Out[54]:
MultiIndex([(1, 1),
(2, 2)],
)
In [55]: midx.dropna(how="all")
Out[55]:
MultiIndex([(1, 1.0),
(2, 2.0),
(4, nan)],
)
Index теперь поддерживает .str.extractall() который возвращает DataFrame, см. документация здесь (GH 10008, GH 13156)
In [56]: idx = pd.Index(["a1a2", "b1", "c1"])
In [57]: idx.str.extractall(r"[ab](?P\d)" )
Out[57]:
digit
match
0 0 1
1 2
1 0 1
[3 rows x 1 columns]
Index.astype() теперь принимает необязательный булев аргумент copy, что позволяет опциональное копирование, если требования к типу данных удовлетворены (GH 13209)
Улучшения Google BigQuery#
The
read_gbq()метод получилdialectMie~~~ + документация для дополнительных деталей (GH 13615).The
to_gbq()метод теперь позволяет порядку столбцов DataFrame отличаться от схемы таблицы назначения (GH 11359).
Детализированный NumPy errstate#
Предыдущие версии pandas постоянно отключали обработку ошибок ufunc numpy, когда pandas был импортирован. pandas делал это, чтобы заглушить предупреждения, возникающие при использовании numpy ufuncs на пропущенных данных, которые обычно представлены как NaN s. К сожалению, это заглушало законные предупреждения, возникающие в не-pandas коде приложения. Начиная с 0.19.0, pandas будет использовать numpy.errstate контекстный менеджер для подавления этих предупреждений более детальным образом, только вокруг тех мест, где эти операции фактически используются в кодовой базе pandas. (GH 13109, GH 13145)
После обновления pandas вы можете увидеть новый RuntimeWarnings выдаваемые из вашего кода. Вероятно, они законны, и основная причина, вероятно, существовала в коде при использовании предыдущих версий pandas, которые просто подавляли предупреждение. Используйте numpy.errstate вокруг источника RuntimeWarning для управления обработкой этих условий.
Метод get_dummies теперь возвращает целочисленные dtypes#
The pd.get_dummies функция теперь возвращает фиктивно-кодированные столбцы как маленькие целые числа, а не числа с плавающей точкой (GH 8725). Это должно обеспечить улучшенное использование памяти.
Предыдущее поведение:
In [1]: pd.get_dummies(['a', 'b', 'a', 'c']).dtypes
Out[1]:
a float64
b float64
c float64
dtype: object
Новое поведение:
In [58]: pd.get_dummies(["a", "b", "a", "c"]).dtypes
Out[58]:
a bool
b bool
c bool
Length: 3, dtype: object
Понизить значения до наименьшего возможного типа данных в to_numeric#
pd.to_numeric() теперь принимает downcast параметр, который понизит тип данных, если возможно, до наименьшего указанного числового типа данных (GH 13352)
In [59]: s = ["1", 2, 3]
In [60]: pd.to_numeric(s, downcast="unsigned")
Out[60]: array([1, 2, 3], dtype=uint8)
In [61]: pd.to_numeric(s, downcast="integer")
Out[61]: array([1, 2, 3], dtype=int8)
API разработки pandas#
В рамках будущей унификации и повышения доступности API pandas мы создали стандартный
подпакет pandas, pandas.api для хранения публичных API. Мы начинаем с раскрытия функций интроспекции типов в pandas.api.types. Дополнительные подпакеты и официально утверждённые API
будут опубликованы в будущих версиях pandas (GH 13147, GH 13634)
Следующие элементы теперь являются частью этого API:
In [62]: import pprint
In [63]: from pandas.api import types
In [64]: funcs = [f for f in dir(types) if not f.startswith("_")]
In [65]: pprint.pprint(funcs)
['CategoricalDtype',
'DatetimeTZDtype',
'IntervalDtype',
'PeriodDtype',
'infer_dtype',
'is_any_real_numeric_dtype',
'is_array_like',
'is_bool',
'is_bool_dtype',
'is_categorical_dtype',
'is_complex',
'is_complex_dtype',
'is_datetime64_any_dtype',
'is_datetime64_dtype',
'is_datetime64_ns_dtype',
'is_datetime64tz_dtype',
'is_dict_like',
'is_dtype_equal',
'is_extension_array_dtype',
'is_file_like',
'is_float',
'is_float_dtype',
'is_hashable',
'is_int64_dtype',
'is_integer',
'is_integer_dtype',
'is_interval',
'is_interval_dtype',
'is_iterator',
'is_list_like',
'is_named_tuple',
'is_number',
'is_numeric_dtype',
'is_object_dtype',
'is_period_dtype',
'is_re',
'is_re_compilable',
'is_scalar',
'is_signed_integer_dtype',
'is_sparse',
'is_string_dtype',
'is_timedelta64_dtype',
'is_timedelta64_ns_dtype',
'is_unsigned_integer_dtype',
'pandas_dtype',
'union_categoricals']
Примечание
Вызов этих функций из внутреннего модуля pandas.core.common теперь будет показывать DeprecationWarning (GH 13990)
Другие улучшения#
Timestampтеперь может принимать позиционные и ключевые параметры, аналогичныеdatetime.datetime()(GH 10758, GH 11630)In [66]: pd.Timestamp(2012, 1, 1) Out[66]: Timestamp('2012-01-01 00:00:00') In [67]: pd.Timestamp(year=2012, month=1, day=1, hour=8, minute=30) Out[67]: Timestamp('2012-01-01 08:30:00')
The
.resample()функция теперь принимаетon=илиlevel=параметр для ресемплинга по столбцу типа datetime илиMultiIndexуровень (GH 13500)In [68]: df = pd.DataFrame( ....: {"date": pd.date_range("2015-01-01", freq="W", periods=5), "a": np.arange(5)}, ....: index=pd.MultiIndex.from_arrays( ....: [[1, 2, 3, 4, 5], pd.date_range("2015-01-01", freq="W", periods=5)], ....: names=["v", "d"], ....: ), ....: ) ....: In [69]: df Out[69]: date a v d 1 2015-01-04 2015-01-04 0 2 2015-01-11 2015-01-11 1 3 2015-01-18 2015-01-18 2 4 2015-01-25 2015-01-25 3 5 2015-02-01 2015-02-01 4 [5 rows x 2 columns]
In [74]: df.resample("M", on="date")[["a"]].sum() Out[74]: a date 2015-01-31 6 2015-02-28 4 [2 rows x 1 columns] In [75]: df.resample("M", level="d")[["a"]].sum() Out[75]: a d 2015-01-31 6 2015-02-28 4 [2 rows x 1 columns]
The
.get_credentials()методGbqConnectorтеперь может сначала попытаться получить учётные данные приложения по умолчанию. Подробнее см. в документации (GH 13577).The
.tz_localize()методDatetimeIndexиTimestampполучилerrorsключевое слово, поэтому вы можете потенциально преобразовать несуществующие временные метки вNaT. Поведение по умолчанию остается вызовом исключенияNonExistentTimeError(GH 13057).to_hdf/read_hdf()теперь принимают объекты пути (например,pathlib.Path,py.path.local) для пути к файлу (GH 11773)The
pd.read_csv()сengine='python'получил поддержку дляdecimal(GH 12933),na_filter(GH 13321) иmemory_mapопция (GH 13381).В соответствии с Python API,
pd.read_csv()теперь будет интерпретировать+infкак положительная бесконечность (GH 13274)The
pd.read_html()получил поддержку дляna_values,converters,keep_default_naопции (GH 13461)Categorical.astype()теперь принимает необязательный булев аргументcopy, действует, когда тип данных является категориальным (GH 13209)DataFrameполучил.asof()метод для возврата последних не-NaN значений в соответствии с выбранным подмножеством (GH 13358)The
DataFrameконструктор теперь будет учитывать порядок ключей, если передан списокOrderedDictобъекты передаются (GH 13304)pd.read_html()получил поддержку дляdecimalопция (GH 12907)Seriesполучил свойства.is_monotonic,.is_monotonic_increasing,.is_monotonic_decreasing, аналогичноIndex(GH 13336)DataFrame.to_sql()теперь позволяет использовать одно значение в качестве типа SQL для всех столбцов (GH 11886).Series.appendтеперь поддерживаетignore_indexопция (GH 13677).to_stata()иStataWriterтеперь можно записывать метки переменных в файлы Stata dta, используя словарь для сопоставления имен столбцов с метками (GH 13535, GH 13536).to_stata()иStataWriterбудет автоматически конвертироватьdatetime64[ns]столбцы в формат Stata%tc, а не вызовValueError(GH 12259)read_stata()иStataReaderвыдавать более явное сообщение об ошибке при чтении файлов Stata с повторяющимися метками значений, когдаconvert_categoricals=True(GH 13923)DataFrame.styleтеперь будет отображать разреженные MultiIndexes (GH 11655)DataFrame.styleтеперь будет показывать имена уровней столбцов (например,DataFrame.columns.names) (GH 13775)DataFrameполучил поддержку переупорядочивания столбцов на основе значений в строке с использованиемdf.sort_values(by='...', axis=1)(GH 10806)In [70]: df = pd.DataFrame({"A": [2, 7], "B": [3, 5], "C": [4, 8]}, index=["row1", "row2"]) In [71]: df Out[71]: A B C row1 2 3 4 row2 7 5 8 [2 rows x 3 columns] In [72]: df.sort_values(by="row2", axis=1) Out[72]: B A C row1 3 2 4 row2 5 7 8 [2 rows x 3 columns]
Добавлена документация к I/O о рисках чтения столбцов со смешанными dtypes и как с этим справиться (GH 13746)
to_html()теперь имеетborderаргумент для управления значением в открывающемтег. По умолчанию используется значение
html.borderопции, которая по умолчанию равна 1. Это также влияет на HTML-представление в блокноте, но поскольку CSS Jupyter включает атрибут border-width, визуальный эффект одинаков. (GH 11563).Вызвать
ImportErrorв функциях sql, когдаsqlalchemyне установлен и используется строка подключения (GH 11920).Совместимость с matplotlib 2.0. Более старые версии pandas также должны работать с matplotlib 2.0 (GH 13333)
Timestamp,Period,DatetimeIndex,PeriodIndexи.dtаксессор получил.is_leap_yearсвойство для проверки, принадлежит ли дата високосному году. (GH 13727)astype()теперь принимает словарь отображения имени столбца на типы данных какdtypeаргумент. (GH 12086)The
pd.read_jsonиDataFrame.to_jsonтеперь поддерживает чтение и запись json lines сlinesопцию см. JSON с разделителями строк (GH 9180)read_excel()теперь поддерживает аргументы ключевых слов true_values и false_values (GH 13347)groupby()теперь принимает скаляр и список из одного элемента для указанияlevelна не-MultiIndexгруппировщик. (GH 13907)Неконвертируемые даты в столбце дат Excel будут возвращены без преобразования, и столбец будет
objectтип данных, а не вызов исключения (GH 10001).pd.Timedelta(None)теперь принимается и будет возвращатьNaT, зеркально отражаяpd.Timestamp(GH 13687)pd.read_stata()теперь может обрабатывать некоторые файлы формата 111, которые создаются SAS при генерации файлов Stata dta (GH 11526)SeriesиIndexтеперь поддерживаетdivmodкоторый вернёт кортеж из серий или индексов. Это ведёт себя как стандартный бинарный оператор в отношении правил трансляции (GH 14208).Изменения API#
Series.tolist()теперь будет возвращать типы Python#Series.tolist()теперь будет возвращать типы Python в выводе, имитируя NumPy.tolist()поведение (GH 10904)In [73]: s = pd.Series([1, 2, 3])
Предыдущее поведение:
In [7]: type(s.tolist()[0]) Out[7]:
Новое поведение:
In [74]: type(s.tolist()[0]) Out[74]: int
Seriesоператоры для различных индексов#Следуя
Seriesоператоры были изменены для обеспечения согласованности всех операторов, включаяDataFrame(GH 1134, GH 4581, GH 13538)Seriesоператоры сравнения теперь вызываютValueErrorкогдаindexразличаются.Seriesлогические операторы выравнивают обаindexлевой и правой стороны.
Предупреждение
До версии 0.18.1, сравнение
Seriesс той же длиной, будет успешным, даже если.indexразличны (результат игнорирует.index). Начиная с версии 0.19.0, это вызоветValueErrorбыть более строгим. Этот раздел также описывает, как сохранить предыдущее поведение или выровнять разные индексы, используя гибкие методы сравнения, такие как.eq.В результате,
SeriesиDataFrameоператоры ведут себя следующим образом:Арифметические операторы#
Арифметические операторы выравнивают оба
index(без изменений).In [75]: s1 = pd.Series([1, 2, 3], index=list("ABC")) In [76]: s2 = pd.Series([2, 2, 2], index=list("ABD")) In [77]: s1 + s2 Out[77]: A 3.0 B 4.0 C NaN D NaN Length: 4, dtype: float64 In [78]: df1 = pd.DataFrame([1, 2, 3], index=list("ABC")) In [79]: df2 = pd.DataFrame([2, 2, 2], index=list("ABD")) In [80]: df1 + df2 Out[80]: 0 A 3.0 B 4.0 C NaN D NaN [4 rows x 1 columns]
Операторы сравнения#
Операторы сравнения вызывают
ValueErrorкогда.indexразличаются.Предыдущее поведение (
Series):Seriesсравниваемые значения, игнорируя.indexпри условии, что оба имели одинаковую длину:In [1]: s1 == s2 Out[1]: A False B True C False dtype: bool
Новое поведение (
Series):In [2]: s1 == s2 Out[2]: ValueError: Can only compare identically-labeled Series objects
Примечание
Чтобы достичь того же результата, что и в предыдущих версиях (сравнивать значения на основе местоположений, игнорируя
.index), сравните оба.values.In [81]: s1.values == s2.values Out[81]: array([False, True, False])
Если вы хотите сравнить
Seriesвыравнивая его.index, см. раздел гибких методов сравнения ниже:In [82]: s1.eq(s2) Out[82]: A False B True C False D False Length: 4, dtype: bool
Текущее поведение (
DataFrame, без изменений):In [3]: df1 == df2 Out[3]: ValueError: Can only compare identically-labeled DataFrame objects
Логические операторы#
Логические операторы выравнивают оба
.indexлевой и правой стороны.Предыдущее поведение (
Series), только левая сторонаindexбыло сохранено:In [4]: s1 = pd.Series([True, False, True], index=list('ABC')) In [5]: s2 = pd.Series([True, True, True], index=list('ABD')) In [6]: s1 & s2 Out[6]: A True B False C False dtype: bool
Новое поведение (
Series):In [83]: s1 = pd.Series([True, False, True], index=list("ABC")) In [84]: s2 = pd.Series([True, True, True], index=list("ABD")) In [85]: s1 & s2 Out[85]: A True B False C False D False Length: 4, dtype: bool
Примечание
Seriesлогические операторы заполняютNaNрезультат сFalse.Примечание
Чтобы достичь того же результата, что и в предыдущих версиях (сравнивать значения только по левому индексу), можно использовать
reindex_like:In [86]: s1 & s2.reindex_like(s1) Out[86]: A True B False C False Length: 3, dtype: bool
Текущее поведение (
DataFrame, без изменений):In [87]: df1 = pd.DataFrame([True, False, True], index=list("ABC")) In [88]: df2 = pd.DataFrame([True, True, True], index=list("ABD")) In [89]: df1 & df2 Out[89]: 0 A True B False C False D False [4 rows x 1 columns]
Гибкие методы сравнения#
Seriesгибкие методы сравнения, такие какeq,ne,le,lt,geиgtтеперь выравнивать обаindex. Используйте эти операторы, если хотите сравнить дваSeriesкоторый имеет другойindex.In [90]: s1 = pd.Series([1, 2, 3], index=["a", "b", "c"]) In [91]: s2 = pd.Series([2, 2, 2], index=["b", "c", "d"]) In [92]: s1.eq(s2) Out[92]: a False b True c False d False Length: 4, dtype: bool In [93]: s1.ge(s2) Out[93]: a False b True c True d False Length: 4, dtype: bool
Ранее это работало так же, как операторы сравнения (см. выше).
Seriesповышение типа при присваивании#A
Seriesтеперь будет правильно повышать свой dtype при присваивании несовместимых значений к текущему dtype (GH 13234)In [94]: s = pd.Series()
Предыдущее поведение:
In [2]: s["a"] = pd.Timestamp("2016-01-01") In [3]: s["b"] = 3.0 TypeError: invalid type promotion
Новое поведение:
In [95]: s["a"] = pd.Timestamp("2016-01-01") In [96]: s["b"] = 3.0 In [97]: s Out[97]: a 2016-01-01 00:00:00 b 3.0 Length: 2, dtype: object In [98]: s.dtype Out[98]: dtype('O')
Функция
.to_datetime()изменения#Ранее если
.to_datetime()встречались смешанные целые числа/дроби и строки, но без дат и времени сerrors='coerce'это преобразует все вNaT.Предыдущее поведение:
In [2]: pd.to_datetime([1, 'foo'], errors='coerce') Out[2]: DatetimeIndex(['NaT', 'NaT'], dtype='datetime64[ns]', freq=None)
Текущее поведение:
Теперь это будет преобразовывать целые числа/числа с плавающей точкой с единицей измерения по умолчанию
ns.In [99]: pd.to_datetime([1, "foo"], errors="coerce") Out[99]: DatetimeIndex(['1970-01-01 00:00:00.000000001', 'NaT'], dtype='datetime64[ns]', freq=None)
Исправления ошибок, связанные с
.to_datetime():Ошибка в
pd.to_datetime()при передаче целых чисел или чисел с плавающей точкой, и нетunitиerrors='coerce'(GH 13180).Ошибка в
pd.to_datetime()при передаче недопустимых типов данных (например, bool); теперь будет учитыватьerrorsключевое слово (GH 13176)Ошибка в
pd.to_datetime()который переполнялся наint8, иint16типы данных (GH 13451)Ошибка в
pd.to_datetime()raiseAttributeErrorсNaNи другая строка недействительна, когдаerrors='ignore'(GH 12424)Ошибка в
pd.to_datetime()не преобразовывал числа с плавающей точкой корректно, когдаunitбыл указан, что привело к усечению даты и времени (GH 13834)
Объединение изменений#
Слияние теперь будет сохранять тип данных ключей соединения (GH 8596)
In [100]: df1 = pd.DataFrame({"key": [1], "v1": [10]}) In [101]: df1 Out[101]: key v1 0 1 10 [1 rows x 2 columns] In [102]: df2 = pd.DataFrame({"key": [1, 2], "v1": [20, 30]}) In [103]: df2 Out[103]: key v1 0 1 20 1 2 30 [2 rows x 2 columns]
Предыдущее поведение:
In [5]: pd.merge(df1, df2, how='outer') Out[5]: key v1 0 1.0 10.0 1 1.0 20.0 2 2.0 30.0 In [6]: pd.merge(df1, df2, how='outer').dtypes Out[6]: key float64 v1 float64 dtype: object
Новое поведение:
Мы можем сохранить ключи соединения
In [104]: pd.merge(df1, df2, how="outer") Out[104]: key v1 0 1 10 1 1 20 2 2 30 [3 rows x 2 columns] In [105]: pd.merge(df1, df2, how="outer").dtypes Out[105]: key int64 v1 int64 Length: 2, dtype: object
Конечно, если у вас есть пропущенные значения, которые вводятся, то результирующий тип данных будет повышен, что не изменилось по сравнению с предыдущими версиями.
In [106]: pd.merge(df1, df2, how="outer", on="key") Out[106]: key v1_x v1_y 0 1 10.0 20 1 2 NaN 30 [2 rows x 3 columns] In [107]: pd.merge(df1, df2, how="outer", on="key").dtypes Out[107]: key int64 v1_x float64 v1_y int64 Length: 3, dtype: object
Метод
.describe()изменения#Идентификаторы процентилей в индексе
.describe()вывод теперь будет округляться до наименьшей точности, сохраняющей их различия (GH 13104)In [108]: s = pd.Series([0, 1, 2, 3, 4]) In [109]: df = pd.DataFrame([0, 1, 2, 3, 4])
Предыдущее поведение:
Процентили округлялись максимум до одного десятичного знака, что могло вызвать
ValueErrorдля data frame, если процентили были дублированы.In [3]: s.describe(percentiles=[0.0001, 0.0005, 0.001, 0.999, 0.9995, 0.9999]) Out[3]: count 5.000000 mean 2.000000 std 1.581139 min 0.000000 0.0% 0.000400 0.1% 0.002000 0.1% 0.004000 50% 2.000000 99.9% 3.996000 100.0% 3.998000 100.0% 3.999600 max 4.000000 dtype: float64 In [4]: df.describe(percentiles=[0.0001, 0.0005, 0.001, 0.999, 0.9995, 0.9999]) Out[4]: ... ValueError: cannot reindex from a duplicate axis
Новое поведение:
In [110]: s.describe(percentiles=[0.0001, 0.0005, 0.001, 0.999, 0.9995, 0.9999]) Out[110]: count 5.000000 mean 2.000000 std 1.581139 min 0.000000 0.01% 0.000400 0.05% 0.002000 0.1% 0.004000 50% 2.000000 99.9% 3.996000 99.95% 3.998000 99.99% 3.999600 max 4.000000 Length: 12, dtype: float64 In [111]: df.describe(percentiles=[0.0001, 0.0005, 0.001, 0.999, 0.9995, 0.9999]) Out[111]: 0 count 5.000000 mean 2.000000 std 1.581139 min 0.000000 0.01% 0.000400 0.05% 0.002000 0.1% 0.004000 50% 2.000000 99.9% 3.996000 99.95% 3.998000 99.99% 3.999600 max 4.000000 [12 rows x 1 columns]
Кроме того:
Передача дублированных
percentilesтеперь вызоветValueError.Ошибка в
.describe()к DataFrame со смешанным индексом столбцов по типам данных, что ранее вызывалоTypeError(GH 13288)
Periodизменения#The
PeriodIndexтеперь имеетperioddtype#PeriodIndexтеперь имеет свой собственныйperioddtype. Theperioddtype является pandas extension dtype, таким какcategoryили тип данных с учетом часового пояса (datetime64[ns, tz]) (GH 13941). Как следствие этого изменения,PeriodIndexбольше не имеет целочисленного типа данных:Предыдущее поведение:
In [1]: pi = pd.PeriodIndex(['2016-08-01'], freq='D') In [2]: pi Out[2]: PeriodIndex(['2016-08-01'], dtype='int64', freq='D') In [3]: pd.api.types.is_integer_dtype(pi) Out[3]: True In [4]: pi.dtype Out[4]: dtype('int64')
Новое поведение:
In [112]: pi = pd.PeriodIndex(["2016-08-01"], freq="D") In [113]: pi Out[113]: PeriodIndex(['2016-08-01'], dtype='period[D]') In [114]: pd.api.types.is_integer_dtype(pi) Out[114]: False In [115]: pd.api.types.is_period_dtype(pi) Out[115]: True In [116]: pi.dtype Out[116]: period[D] In [117]: type(pi.dtype) Out[117]: pandas.core.dtypes.dtypes.PeriodDtype
Period('NaT')теперь возвращаетpd.NaT#Ранее,
Periodимеет свой собственныйPeriod('NaT')представление, отличное отpd.NaT. ТеперьPeriod('NaT')было изменено для возвратаpd.NaT. (GH 12759, GH 13582)Предыдущее поведение:
In [5]: pd.Period('NaT', freq='D') Out[5]: Period('NaT', 'D')
Новое поведение:
Это приводит к
pd.NaTбез предоставленияfreqопция.In [118]: pd.Period("NaT") Out[118]: NaT In [119]: pd.Period(None) Out[119]: NaT
Для совместимости с
Periodсложение и вычитание,pd.NaTтеперь поддерживает сложение и вычитание сint. Ранее вызывалось исключениеValueError.Предыдущее поведение:
In [5]: pd.NaT + 1 ... ValueError: Cannot add integral value to Timestamp without freq.
Новое поведение:
In [120]: pd.NaT + 1 Out[120]: NaT In [121]: pd.NaT - 1 Out[121]: NaT
PeriodIndex.valuesтеперь возвращает массивPeriodobject#.valuesизменён на возврат массиваPeriodобъектов, а не массив целых чисел (GH 13988).Предыдущее поведение:
In [6]: pi = pd.PeriodIndex(['2011-01', '2011-02'], freq='M') In [7]: pi.values Out[7]: array([492, 493])
Новое поведение:
In [122]: pi = pd.PeriodIndex(["2011-01", "2011-02"], freq="M") In [123]: pi.values Out[123]: array([Period('2011-01', 'M'), Period('2011-02', 'M')], dtype=object)
Index
+/-больше не используется для операций над множествами#Сложение и вычитание базового типа Index и DatetimeIndex (не числовых типов индексов) ранее выполняли операции над множествами (объединение и разность множеств). Это поведение уже было устаревшим с версии 0.15.0 (в пользу использования конкретных
.union()и.difference()методы), и теперь отключен. Когда возможно,+и-теперь используются для поэлементных операций, например, для конкатенации строк или вычитания дат (GH 8227, GH 14127).Предыдущее поведение:
In [1]: pd.Index(['a', 'b']) + pd.Index(['a', 'c']) FutureWarning: using '+' to provide set union with Indexes is deprecated, use '|' or .union() Out[1]: Index(['a', 'b', 'c'], dtype='object')
Новое поведение: та же операция теперь будет выполнять поэлементное сложение:
In [124]: pd.Index(["a", "b"]) + pd.Index(["a", "c"]) Out[124]: Index(['aa', 'bc'], dtype='object')
Обратите внимание, что числовые объекты Index уже выполняли поэлементные операции. Например, поведение сложения двух целочисленных Index осталось неизменным. Базовый
Indexтеперь согласован с этим поведением.In [125]: pd.Index([1, 2, 3]) + pd.Index([2, 3, 4]) Out[125]: Index([3, 5, 7], dtype='int64')
Кроме того, из-за этого изменения теперь возможно вычитать два объекта DatetimeIndex, получая TimedeltaIndex:
Предыдущее поведение:
In [1]: (pd.DatetimeIndex(['2016-01-01', '2016-01-02']) ...: - pd.DatetimeIndex(['2016-01-02', '2016-01-03'])) FutureWarning: using '-' to provide set differences with datetimelike Indexes is deprecated, use .difference() Out[1]: DatetimeIndex(['2016-01-01'], dtype='datetime64[ns]', freq=None)
Новое поведение:
In [126]: ( .....: pd.DatetimeIndex(["2016-01-01", "2016-01-02"]) .....: - pd.DatetimeIndex(["2016-01-02", "2016-01-03"]) .....: ) .....: Out[126]: TimedeltaIndex(['-1 days', '-1 days'], dtype='timedelta64[ns]', freq=None)
Index.differenceи.symmetric_differenceизменения#Index.differenceиIndex.symmetric_differenceтеперь будет более последовательно обрабатыватьNaNзначения как любые другие значения. (GH 13514)In [127]: idx1 = pd.Index([1, 2, 3, np.nan]) In [128]: idx2 = pd.Index([0, 1, np.nan])
Предыдущее поведение:
In [3]: idx1.difference(idx2) Out[3]: Float64Index([nan, 2.0, 3.0], dtype='float64') In [4]: idx1.symmetric_difference(idx2) Out[4]: Float64Index([0.0, nan, 2.0, 3.0], dtype='float64')
Новое поведение:
In [129]: idx1.difference(idx2) Out[129]: Index([2.0, 3.0], dtype='float64') In [130]: idx1.symmetric_difference(idx2) Out[130]: Index([0.0, 2.0, 3.0], dtype='float64')
Index.uniqueпоследовательно возвращаетIndex#Index.unique()теперь возвращает уникальные значения какIndexсоответствующегоdtype. (GH 13395). Ранее большинствоIndexклассы, возвращённыеnp.ndarray, иDatetimeIndex,TimedeltaIndexиPeriodIndexвозвращёнIndexдля сохранения метаданных, таких как часовой пояс.Предыдущее поведение:
In [1]: pd.Index([1, 2, 3]).unique() Out[1]: array([1, 2, 3]) In [2]: pd.DatetimeIndex(['2011-01-01', '2011-01-02', ...: '2011-01-03'], tz='Asia/Tokyo').unique() Out[2]: DatetimeIndex(['2011-01-01 00:00:00+09:00', '2011-01-02 00:00:00+09:00', '2011-01-03 00:00:00+09:00'], dtype='datetime64[ns, Asia/Tokyo]', freq=None)
Новое поведение:
In [131]: pd.Index([1, 2, 3]).unique() Out[131]: Index([1, 2, 3], dtype='int64') In [132]: pd.DatetimeIndex( .....: ["2011-01-01", "2011-01-02", "2011-01-03"], tz="Asia/Tokyo" .....: ).unique() .....: Out[132]: DatetimeIndex(['2011-01-01 00:00:00+09:00', '2011-01-02 00:00:00+09:00', '2011-01-03 00:00:00+09:00'], dtype='datetime64[ns, Asia/Tokyo]', freq=None)
MultiIndexконструкторы,groupbyиset_indexсохранять категориальные типы данных#MultiIndex.from_arraysиMultiIndex.from_productтеперь будет сохранять категориальный тип данных вMultiIndexуровни (GH 13743, GH 13854).In [133]: cat = pd.Categorical(["a", "b"], categories=list("bac")) In [134]: lvl1 = ["foo", "bar"] In [135]: midx = pd.MultiIndex.from_arrays([cat, lvl1]) In [136]: midx Out[136]: MultiIndex([('a', 'foo'), ('b', 'bar')], )
Предыдущее поведение:
In [4]: midx.levels[0] Out[4]: Index(['b', 'a', 'c'], dtype='object') In [5]: midx.get_level_values[0] Out[5]: Index(['a', 'b'], dtype='object')
Новое поведение: одиночный уровень теперь является
CategoricalIndex:In [137]: midx.levels[0] Out[137]: CategoricalIndex(['b', 'a', 'c'], categories=['b', 'a', 'c'], ordered=False, dtype='category') In [138]: midx.get_level_values(0) Out[138]: CategoricalIndex(['a', 'b'], categories=['b', 'a', 'c'], ordered=False, dtype='category')
Аналогичное изменение было сделано для
MultiIndex.from_product. Как следствие,groupbyиset_indexтакже сохраняют категориальные типы данных в индексахIn [139]: df = pd.DataFrame({"A": [0, 1], "B": [10, 11], "C": cat}) In [140]: df_grouped = df.groupby(by=["A", "C"], observed=False).first() In [141]: df_set_idx = df.set_index(["A", "C"])
Предыдущее поведение:
In [11]: df_grouped.index.levels[1] Out[11]: Index(['b', 'a', 'c'], dtype='object', name='C') In [12]: df_grouped.reset_index().dtypes Out[12]: A int64 C object B float64 dtype: object In [13]: df_set_idx.index.levels[1] Out[13]: Index(['b', 'a', 'c'], dtype='object', name='C') In [14]: df_set_idx.reset_index().dtypes Out[14]: A int64 C object B int64 dtype: object
Новое поведение:
In [142]: df_grouped.index.levels[1] Out[142]: CategoricalIndex(['b', 'a', 'c'], categories=['b', 'a', 'c'], ordered=False, dtype='category', name='C') In [143]: df_grouped.reset_index().dtypes Out[143]: A int64 C category B float64 Length: 3, dtype: object In [144]: df_set_idx.index.levels[1] Out[144]: CategoricalIndex(['b', 'a', 'c'], categories=['b', 'a', 'c'], ordered=False, dtype='category', name='C') In [145]: df_set_idx.reset_index().dtypes Out[145]: A int64 C category B int64 Length: 3, dtype: object
Функция
read_csvбудет последовательно перечислять блоки#Когда
read_csv()вызывается сchunksize=nи без указания индекса, каждый блок имел независимо сгенерированный индекс из0ton-1. Теперь им вместо этого присваивается прогрессивный индекс, начиная с0для первого фрагмента, отnдля второго и так далее, так что при объединении они идентичны результату вызоваread_csv()безchunksize=аргумент (GH 12185).In [146]: data = "A,B\n0,1\n2,3\n4,5\n6,7"
Предыдущее поведение:
In [2]: pd.concat(pd.read_csv(StringIO(data), chunksize=2)) Out[2]: A B 0 0 1 1 2 3 0 4 5 1 6 7
Новое поведение:
In [147]: pd.concat(pd.read_csv(StringIO(data), chunksize=2)) Out[147]: A B 0 0 1 1 2 3 2 4 5 3 6 7 [4 rows x 2 columns]
Изменения в Sparse#
Эти изменения позволяют pandas работать с разреженными данными с большим количеством типов данных и способствуют более плавной работе с обработкой данных.
Типы
int64иboolулучшения поддержки#Разреженные структуры данных теперь получили расширенную поддержку
int64иbooldtype(GH 667, GH 13849).Ранее разреженные данные были
float64dtype по умолчанию, даже если все входные данные были типаintилиbooldtype. Вы должны были указатьdtypeявно для создания разреженных данных сint64тип данных. Также,fill_valueдолжно было быть указано явно, потому что значение по умолчанию былоnp.nanкоторый не появляется вint64илиbooldata.In [1]: pd.SparseArray([1, 2, 0, 0]) Out[1]: [1.0, 2.0, 0.0, 0.0] Fill: nan IntIndex Indices: array([0, 1, 2, 3], dtype=int32) # specifying int64 dtype, but all values are stored in sp_values because # fill_value default is np.nan In [2]: pd.SparseArray([1, 2, 0, 0], dtype=np.int64) Out[2]: [1, 2, 0, 0] Fill: nan IntIndex Indices: array([0, 1, 2, 3], dtype=int32) In [3]: pd.SparseArray([1, 2, 0, 0], dtype=np.int64, fill_value=0) Out[3]: [1, 2, 0, 0] Fill: 0 IntIndex Indices: array([0, 1], dtype=int32)
Начиная с v0.19.0, разреженные данные сохраняют входной тип данных и используют более подходящие
fill_valueзначения по умолчанию (0дляint64dtype,Falseдляbooldtype).In [148]: pd.arrays.SparseArray([1, 2, 0, 0], dtype=np.int64) Out[148]: [1, 2, 0, 0] Fill: 0 IntIndex Indices: array([0, 1], dtype=int32) In [149]: pd.arrays.SparseArray([True, False, False, False]) Out[149]: [True, False, False, False] Fill: False IntIndex Indices: array([0], dtype=int32)
См. документация для получения дополнительной информации.
Операторы теперь сохраняют типы данных#
Разреженная структура данных теперь может сохранять
dtypeпосле арифметических операций (GH 13848)
s = pd.SparseSeries([0, 2, 0, 1], fill_value=0, dtype=np.int64) s.dtype s + 1
Разреженные структуры данных теперь поддерживают
astypeдля преобразования внутреннихdtype(GH 13900)
s = pd.SparseSeries([1.0, 0.0, 2.0, 0.0], fill_value=0) s s.astype(np.int64)
astypeзавершается ошибкой, если данные содержат значения, которые нельзя преобразовать в указанныеdtype. Обратите внимание, что ограничение применяется кfill_valueкоторый по умолчаниюnp.nan.In [7]: pd.SparseSeries([1., np.nan, 2., np.nan], fill_value=np.nan).astype(np.int64) Out[7]: ValueError: unable to coerce current fill_value nan to int64 dtype
Другие исправления для разреженных данных#
Подкласс
SparseDataFrameиSparseSeriesтеперь сохраняет типы классов при срезе или транспонировании. (GH 13787)SparseArrayсbooldtype теперь поддерживает логические (bool) операторы (GH 14000)Ошибка в
SparseSeriesсMultiIndex[]индексирование может вызватьIndexError(GH 13144)Ошибка в
SparseSeriesсMultiIndex[]результат индексации может иметь нормальныйIndex(GH 13144)Ошибка в
SparseDataFrameв которомaxis=Noneне использовал по умолчаниюaxis=0(GH 13048)Ошибка в
SparseSeriesиSparseDataFrameсоздание сobjectтип данных может вызыватьTypeError(GH 11633)Ошибка в
SparseDataFrameне учитывает переданныйSparseArrayилиSparseSeriesтип данных иfill_value(GH 13866)Ошибка в
SparseArrayиSparseSeriesне применяйте ufunc кfill_value(GH 13853)Ошибка в
SparseSeries.absнеправильно сохраняет отрицательныеfill_value(GH 13853)Ошибка в срезе одной строки для мультитипа
SparseDataFrames, типы ранее принудительно преобразовывались в float (GH 13917)Ошибка в
SparseSeriesсрезы изменяют целочисленный тип данных на float (GH 8292)Ошибка в
SparseDataFarmeоперации сравнения могут вызыватьTypeError(GH 13001)Ошибка в
SparseDataFarme.isnullвызываетValueError(GH 8276)Ошибка в
SparseSeriesпредставление сboolтип данных может вызыватьIndexError(GH 13110)Ошибка в
SparseSeriesиSparseDataFrameofboolилиint64dtype может отображать свои значения какfloat64тип данных (GH 13110)Ошибка в разреженном индексировании с использованием
SparseArrayсbooldtype может возвращать неверный результат (GH 13985)Ошибка в
SparseArrayсозданный изSparseSeriesможет потерятьdtype(GH 13999)Ошибка в
SparseSeriesсравнение с dense возвращает нормальныйSeriesвместоSparseSeries(GH 13999)
Изменения типа данных индексатора#
Примечание
Это изменение затрагивает только 64-битный Python, работающий на Windows, и только относительно сложные операции индексирования
Методы, такие как
Index.get_indexerкоторые возвращают массив индексатора, приводят этот массив к "платформенному целому числу", чтобы его можно было непосредственно использовать в операциях сторонних библиотек, таких какnumpy.take. Ранее платформенный int определялся какnp.int_что соответствует целому числу C, но правильный тип, и тот, который используется сейчас, этоnp.intp, что соответствует размеру целого числа C, который может содержать указатель (GH 3033, GH 13972).Эти типы одинаковы на многих платформах, но для 64-битного Python на Windows,
np.int_составляет 32 бита, иnp.intpсоставляет 64 бита. Изменение этого поведения улучшает производительность для многих операций на этой платформе.Предыдущее поведение:
In [1]: i = pd.Index(['a', 'b', 'c']) In [2]: i.get_indexer(['b', 'b', 'c']).dtype Out[2]: dtype('int32')
Новое поведение:
In [1]: i = pd.Index(['a', 'b', 'c']) In [2]: i.get_indexer(['b', 'b', 'c']).dtype Out[2]: dtype('int64')
Другие изменения API#
Timestamp.to_pydatetimeвыдастUserWarningкогдаwarn=True, и экземпляр имеет ненулевое количество наносекунд, ранее это выводило сообщение в stdout (GH 14101).Series.unique()с datetime и часовым поясом теперь возвращает массивTimestampс часовым поясом (GH 13565).Panel.to_sparse()вызоветNotImplementedErrorисключение при вызове (GH 13778).Index.reshape()вызоветNotImplementedErrorисключение при вызове (GH 12882)..filter()обеспечивает взаимное исключение аргументов ключевых слов (GH 12399).evalправила повышения типа данных дляfloat32типы были обновлены для большей согласованности с правилами NumPy. Новое поведение не будет повышать тип доfloat64если умножить pandasfloat32объект на скаляр float64 (GH 12388).An
UnsupportedFunctionCallтеперь вызывается ошибка, если функции NumPy, такие какnp.meanвызываются на объектах groupby или resample (GH 12811).__setitem__больше не будет применять вызываемый rhs как функцию вместо его сохранения. Вызовитеwhereнапрямую для получения предыдущего поведения (GH 13299).Вызовы
.sample()будет учитывать случайное зерно, установленное черезnumpy.random.seed(n)(GH 13161)Styler.applyтеперь более строг к выводам, которые должна возвращать ваша функция. Дляaxis=0илиaxis=1форма вывода должна быть идентичной. Дляaxis=None, вывод должен быть DataFrame с идентичными столбцами и метками индекса (GH 13222).Float64Index.astype(int)теперь будет вызыватьValueErrorifFloat64IndexсодержитNaNзначения (GH 13149)TimedeltaIndex.astype(int)иDatetimeIndex.astype(int)теперь вернетInt64Indexвместоnp.array(GH 13209)Передача
Periodс несколькими частотами в обычныйIndexтеперь возвращаетIndexсobjectтип данных (GH 13664)PeriodIndex.fillnaсPeriodимеет другую частоту, теперь приводится кobjectтип данных (GH 13664)Фасетные boxplot из
DataFrame.boxplot(by=col)теперь возвращаетSeriesкогдаreturn_typeне является None. Ранее они возвращалиOrderedDict. Обратите внимание, что когдаreturn_type=None, по умолчанию, они всё равно возвращают 2-D массив NumPy (GH 12216, GH 7096).pd.read_hdfтеперь вызоветValueErrorвместоKeyError, если режим отличен отr,r+иaпредоставляется. (GH 13623)pd.read_csv(),pd.read_table(), иpd.read_hdf()вызвать встроенноеFileNotFoundErrorисключение для Python 3.x при вызове на несуществующем файле; это обратно портировано какIOErrorв Python 2.x (GH 14086)Более информативные исключения передаются через csv-парсер. Тип исключения теперь будет исходным типом исключения вместо
CParserError(GH 13652).pd.read_csv()в движке C теперь будет выдаватьParserWarningили вызватьValueErrorкогдаsepзакодировано более чем одним символом (GH 14065)DataFrame.valuesтеперь вернетfloat64сDataFrameсмешанныхint64иuint64типы данных, соответствующиеnp.find_common_type(GH 10364, GH 13917).groupby.groupsтеперь вернет словарьIndexобъектов, а не словарьnp.ndarrayилиlists(GH 14293)
Устаревшие функции#
Series.reshapeиCategorical.reshapeбыли устаревшими и будут удалены в последующем выпуске (GH 12882, GH 12882)PeriodIndex.to_datetimeбыл объявлен устаревшим в пользуPeriodIndex.to_timestamp(GH 8254)Timestamp.to_datetimeбыл объявлен устаревшим в пользуTimestamp.to_pydatetime(GH 8254)Index.to_datetimeиDatetimeIndex.to_datetimeустарели в пользуpd.to_datetime(GH 8254)pandas.core.datetoolsмодуль устарел и будет удален в последующем выпуске (GH 14094)SparseListустарел и будет удален в будущей версии (GH 13784)DataFrame.to_html()иDataFrame.to_latex()удалилиcolSpaceпараметр в пользуcol_space(GH 13857)DataFrame.to_sql()устарелflavorпараметр, так как он избыточен, когда SQLAlchemy не установлен (GH 13611)Устаревший
read_csvключевые слова:compact_intsиuse_unsignedбыли устаревшими и будут удалены в будущей версии (GH 13320)buffer_linesустарел и будет удален в будущей версии (GH 13360)as_recarrayустарел и будет удален в будущей версии (GH 13373)skip_footerбыл объявлен устаревшим в пользуskipfooterи будет удалена в будущей версии (GH 13349)
верхний уровень
pd.ordered_merge()был переименован вpd.merge_ordered()и исходное имя будет удалено в будущей версии (GH 13358)Timestamp.offsetсвойства (и именованного аргумента в конструкторе), устарели в пользуfreq(GH 12160)pd.tseries.util.pivot_annualустарел. Используйтеpivot_tableв качестве альтернативы, примером является здесь (GH 736)pd.tseries.util.isleapyearбыл устаревшим и будет удален в последующем выпуске. Объекты, подобные дате и времени, теперь имеют.is_leap_yearсвойство (GH 13727)Panel4DиPanelNDКонструкторы устарели и будут удалены в будущей версии. Рекомендуемый способ представления этих типов n-мерных данных - с помощью пакет xarray. pandas предоставляетto_xarray()метод для автоматизации этого преобразования (GH 13564).pandas.tseries.frequencies.get_standard_freqустарел. Используйтеpandas.tseries.frequencies.to_offset(freq).rule_codeвместо (GH 13874)pandas.tseries.frequencies.to_offset’sfreqstrключевое слово устарело в пользуfreq(GH 13874)Categorical.from_arrayустарел и будет удален в будущей версии (GH 13854)
Удаление устаревших функций/изменений предыдущих версий#
The
SparsePanelкласс был удален (GH 13778)The
pd.sandboxмодуль был удалён в пользу внешней библиотекиpandas-qt(GH 13670)The
pandas.io.dataиpandas.io.wbмодули удалены в пользу пакет pandas-datareader (GH 13724).The
pandas.tools.rplotмодуль был удален в пользу пакет seaborn (GH 13855)DataFrame.to_csv()удалилengineпараметра, который был объявлен устаревшим в версии 0.17.1 (GH 11274, GH 13419)DataFrame.to_dict()удалилouttypeпараметр в пользуorient(GH 13627, 0.170972)pd.Categoricalпрекратило установкуorderedатрибут напрямую в пользуset_orderedметод (GH 13671)pd.Categoricalудалилlevelsатрибут в пользуcategories(GH 8376)DataFrame.to_sql()удалилmysqlопция дляflavorпараметр (GH 13611)Panel.shift()удалилlagsпараметр в пользуperiods(GH 14041)pd.Indexудалилdiffметод в пользуdifference(GH 13669)pd.DataFrameудалилto_wideметод в пользуto_panel(GH 14039)Series.to_csvудалилnanRepпараметр в пользуna_rep(GH 13804)Series.xs,DataFrame.xs,Panel.xs,Panel.major_xs, иPanel.minor_xsудалилиcopyпараметр (GH 13781)str.splitудалилreturn_typeпараметр в пользуexpand(GH 13701)Удаление устаревших временных правил (псевдонимов смещений), устаревших с версии 0.17.0 (это было псевдонимом с версии 0.8.0) (GH 13590, GH 13868). Теперь устаревшие правила времени вызывают
ValueError. Для списка поддерживаемых смещений см. здесь.Значение по умолчанию для
return_typeпараметр дляDataFrame.plot.boxиDataFrame.boxplotизменено сNoneto"axes". Эти методы теперь по умолчанию возвращают объект matplotlib axes вместо словаря художников. См. здесь (GH 6581).The
tqueryиuqueryфункции вpandas.io.sqlмодуль удалены (GH 5950).
Улучшения производительности#
Улучшена производительность разреженных
IntIndex.intersect(GH 13082)Улучшена производительность разреженной арифметики с
BlockIndexкогда количество блоков велико, хотя рекомендуется использоватьIntIndexв таких случаях (GH 13082)Улучшена производительность
DataFrame.quantile()поскольку теперь он работает поблочно (GH 11623)Улучшена производительность операций с хэш-таблицами float64, исправлены некоторые очень медленные операции индексирования и группировки в python 3 (GH 13166, GH 13334)
Улучшена производительность
DataFrameGroupBy.transform(GH 12737)Улучшена производительность
IndexиSeries.duplicated(GH 10235)Улучшена производительность
Index.difference(GH 12044)Улучшена производительность
RangeIndex.is_monotonic_increasingиis_monotonic_decreasing(GH 13749)Улучшена производительность разбора строк даты и времени в
DatetimeIndex(GH 13692)Улучшенная производительность хеширования
Period(GH 12817)Улучшена производительность
factorizedatetime с часовым поясом (GH 13750)Улучшена производительность за счёт ленивого создания хэш-таблиц индексирования для больших индексов (GH 14266)
Улучшена производительность
groupby.groups(GH 14293)Ненужное материализование MultiIndex при интроспекции использования памяти (GH 14308)
Исправления ошибок#
Ошибка в
groupby().shift(), что могло вызвать ошибку сегментации или повреждение в редких случаях при группировке по столбцам с пропущенными значениями (GH 13813)Ошибка в
groupby().cumsum()вычислениеcumprodкогдаaxis=1. (GH 13994)Ошибка в
pd.to_timedelta()в которомerrorsпараметр не учитывался (GH 13613)Ошибка в
io.json.json_normalize(), где не-ASCII ключи вызывали исключение (GH 13213)Ошибка при передаче временного ряда с нестандартным индексом
Seriesкакxerrилиyerrв.plot()(GH 11858)Ошибка в построении графика area: легенда рисуется некорректно, если включен подграфик или легенда перемещена после построения (требуется matplotlib 1.5.0 для правильного отображения легенды графика area) (GH 9161, GH 13544)
Ошибка в
DataFrameприсваивание с объектным типом данныхIndexгде результирующий столбец изменяем для исходного объекта. (GH 13522)Ошибка в matplotlib
AutoDataFormatter; это восстанавливает второе масштабированное форматирование и повторно добавляет микросекундное масштабированное форматирование (GH 13131)Ошибка при выборе из
HDFStoreс фиксированным форматом иstartи/илиstopуказанный теперь вернет выбранный диапазон (GH 8287)Ошибка в
Categorical.from_codes()где возникала бесполезная ошибка при недопустимомorderedпараметр был передан (GH 14058)Ошибка в
Seriesсоздание из кортежа целых чисел в Windows не возвращает тип данных по умолчанию (int64) (GH 13646)Ошибка в
TimedeltaIndexсложение с объектом типа Datetime, где переполнение при сложении не перехватывалось (GH 14068)Ошибка в
.groupby(..).resample(..)когда один и тот же объект вызывается несколько раз (GH 13174)Ошибка в
.to_records()когда имя индекса является строкой Unicode (GH 13172)Ошибка при вызове
.memory_usage()на объекте, который не реализует (GH 12924)Регрессия в
Series.quantileс nan (также появляется в.median()и.describe()); кроме того, теперь называетSeriesс квантилем (GH 13098, GH 13146)Ошибка в
SeriesGroupBy.transformсо значениями datetime и отсутствующими группами (GH 13191)Ошибка, когда пустой
Seriesнекорректно преобразовывались в операциях с датами/временем и числами (GH 13844)Ошибка в
Categoricalконструктору при передачеCategoricalсодержащие даты и время с часовыми поясами (GH 14190)Ошибка в
Series.str.extractall()сstrиндекс вызываетValueError(GH 13156)Ошибка в
Series.str.extractall()с одной группой и квантификатором (GH 13382)Ошибка в
DatetimeIndexиPeriodвычитание вызываетValueErrorилиAttributeErrorвместоTypeError(GH 13078)Ошибка в
IndexиSeriesсоздан с помощьюNaNиNaTсмешанные данные могут не иметьdatetime64dtype (GH 13324)Ошибка в
IndexиSeriesможет игнорироватьnp.datetime64('nat')иnp.timdelta64('nat')для определения типа данных (GH 13324)Ошибка в
PeriodIndexиPeriodвычитание вызываетAttributeError(GH 13071)Ошибка в
PeriodIndexконструкция, возвращающаяfloat64индекс в некоторых обстоятельствах (GH 13067)Ошибка в
.resample(..)сPeriodIndexне изменяя егоfreqсоответствующим образом, когда пусто (GH 13067)Ошибка в
.resample(..)сPeriodIndexне сохраняя свой тип или имя с пустымDataFrameсоответствующим образом, когда пусто (GH 13212)Ошибка в
groupby(..).apply(..)когда переданная функция возвращает скалярные значения для каждой группы (GH 13468).Ошибка в
groupby(..).resample(..)где передача некоторых ключевых слов вызовет исключение (GH 13235)Ошибка в
.tz_convertдля объектов с информацией о часовом поясеDateTimeIndexкоторый полагался на отсортированный индекс для корректных результатов (GH 13306)Ошибка в
.tz_localizeсdateutil.tz.tzlocalможет возвращать некорректный результат (GH 13583)Ошибка в
DatetimeTZDtypedtype сdateutil.tz.tzlocalне может считаться допустимым dtype (GH 13583)Ошибка в
pd.read_hdf()где попытка загрузить HDF-файл с одним набором данных, содержащим один или несколько категориальных столбцов, завершалась неудачей, если аргумент key не был установлен в имя набора данных. (GH 13231)Ошибка в
.rolling()который позволял использовать отрицательное целое окно при построенииRolling()объект, но позже завершится ошибкой при агрегации (GH 13383)Ошибка в
Seriesиндексирование с данными в виде кортежей и числовым индексом (GH 13509)Ошибка при печати
pd.DataFrameгде необычные элементы сobjectdtype вызывали ошибки сегментации (GH 13717)Ошибка в ранжировании
Seriesчто могло привести к ошибкам сегментации (GH 13445)Ошибка в различных типах индексов, которые не передавали имя переданного индекса (GH 12309)
Ошибка в
DatetimeIndex, который не учитывалcopy=True(GH 13205)Ошибка в
DatetimeIndex.is_normalizedвозвращает некорректно для нормализованного date_range в случае локальных часовых поясов (GH 13459)Ошибка в
pd.concatи.appendможет приводить к преобразованию типовdatetime64иtimedeltatoobjectтип данных, содержащий встроенные объекты PythondatetimeилиtimedeltaвместоTimestampилиTimedelta(GH 13626)Ошибка в
PeriodIndex.appendможет вызыватьAttributeErrorкогда результатobjectтип данных (GH 13221)Ошибка в
CategoricalIndex.appendможет принимать обычныеlist(GH 13626)Ошибка в
pd.concatи.appendс тем же часовым поясом сбрасываются в UTC (GH 7795)Ошибка в
SeriesиDataFrame.appendвызываетAmbiguousTimeErrorесли данные содержат дату и время около границы перехода на летнее время (GH 13626)Ошибка в
DataFrame.to_csv()в котором значения с плавающей точкой заключались в кавычки, хотя кавычки были указаны только для нечисловых значений (GH 12922, GH 13259)Ошибка в
DataFrame.describe()вызовValueErrorтолько с булевыми столбцами (GH 13898)Ошибка в
MultiIndexсрезы, где возвращались лишние элементы, когда уровень не уникален (GH 12896)Ошибка в
.str.replaceне вызываетTypeErrorдля недопустимой замены (GH 13438)Ошибка в
MultiIndex.from_arraysкоторый не проверял соответствие длин входных массивов (GH 13599)Ошибка в
cartesian_productиMultiIndex.from_productчто может вызвать ошибку с пустыми входными массивами (GH 12258)Ошибка в
pd.read_csv()что может вызвать ошибку сегментации или повреждение при итерации большими блоками по потоку/файлу в редких обстоятельствах (GH 13703)Ошибка в
pd.read_csv()что вызывало ошибки при передаче словаря, содержащего скаляры, дляna_values(GH 12224)Ошибка в
pd.read_csv()что приводило к некорректному парсингу файлов BOM из-за игнорирования BOM (GH 4793)Ошибка в
pd.read_csv()сengine='python'который вызывал ошибки, когда передавался массив numpy дляusecols(GH 12546)Ошибка в
pd.read_csv()где столбцы индекса неправильно парсились при парсинге как даты сthousandsпараметр (GH 14066)Ошибка в
pd.read_csv()сengine='python'в которомNaNзначения не обнаруживались после преобразования данных в числовые значения (GH 13314)Ошибка в
pd.read_csv()в которомnrowsаргумент не был должным образом проверен для обоих движков (GH 10476)Ошибка в
pd.read_csv()сengine='python'в котором бесконечности смешанного регистра не интерпретировались правильно (GH 13274)Ошибка в
pd.read_csv()сengine='python'в котором завершающиеNaNзначения не парсились (GH 13320)Ошибка в
pd.read_csv()сengine='python'при чтении изtempfile.TemporaryFileв Windows с Python 3 (GH 13398)Ошибка в
pd.read_csv()что предотвращаетusecolskwarg больше не принимает однобайтовые строки Unicode (GH 13219)Ошибка в
pd.read_csv()что предотвращаетusecolsот того, чтобы быть пустым множеством (GH 13402)Ошибка в
pd.read_csv()в движке C, где символ NULL не парсился как NULL (GH 14012)Ошибка в
pd.read_csv()сengine='c'в котором NULLquotecharне принимался, хотяquotingбыл указан какNone(GH 13411)Ошибка в
pd.read_csv()сengine='c'в котором поля не были правильно приведены к float, когда кавычки указывались как нечисловые (GH 13411)Ошибка в
pd.read_csv()в Python 2.x с данными, закодированными не в UTF8, разделенными несколькими символами (GH 3404)Ошибка в
pd.read_csv(), где псевдонимы для utf-xx (например, UTF-xx, UTF_xx, utf_xx) вызывали UnicodeDecodeError (GH 13549)Ошибка в
pd.read_csv,pd.read_table,pd.read_fwf,pd.read_stataиpd.read_sasгде файлы были открыты парсерами, но не закрыты, если обаchunksizeиiteratorбылиNone. (GH 13940)Ошибка в
StataReader,StataWriter,XportReaderиSAS7BDATReaderгде файл не был правильно закрыт при возникновении ошибки. (GH 13940)Ошибка в
pd.pivot_table()гдеmargins_nameигнорируется, когдаaggfuncявляется списком (GH 13354)Ошибка в
pd.Series.str.zfill,center,ljust,rjust, иpadпри передаче нецелых чисел не вызывалTypeError(GH 13598)Ошибка при проверке наличия нулевых объектов в
TimedeltaIndex, который всегда возвращалTrue(GH 13603)Ошибка в
Seriesарифметические операции вызываютTypeErrorесли оно содержит дату-время какobjectтип данных (GH 13043)Ошибка
Series.isnull()иSeries.notnull()ignorePeriod('NaT')(GH 13737)Ошибка
Series.fillna()иSeries.dropna()не влияют наPeriod('NaT')(GH 13737Ошибка в
.fillna(value=np.nan)неправильно вызываетKeyErrorнаcategoryтипизированныйSeries(GH 14021)Ошибка при создании типа данных расширения, где созданные типы не были is/идентичными (GH 13285)
Ошибка в
.resample(..)где некорректные предупреждения были вызваны интроспекцией IPython (GH 13618)Ошибка в
NaT-PeriodвызываетAttributeError(GH 13071)Ошибка в
Seriesсравнение может выдать некорректный результат, если правая часть содержитNaT(GH 9005)Ошибка в
SeriesиIndexсравнение может выдать некорректный результат, если содержитNaTсobjectтип данных (GH 13592)Ошибка в
Periodсложение вызываетTypeErrorifPeriodнаходится в правой части (GH 13069)Ошибка в
PeriodиSeriesилиIndexсравнение вызываетTypeError(GH 13200)Ошибка в
pd.set_eng_float_format()что предотвращало форматирование NaN и Inf (GH 11981)Ошибка в
.unstackсCategoricalсброс dtype.orderedtoTrue(GH 13249)Очистка некоторых предупреждений времени компиляции при парсинге даты и времени (GH 13607)
Ошибка в
factorizeвызываетAmbiguousTimeErrorесли данные содержат дату и время около границы перехода на летнее время (GH 13750)Ошибка в
.set_indexвызываетAmbiguousTimeErrorесли новый индекс содержит границу перехода на летнее время и несколько уровней (GH 12920)Ошибка в
.shiftвызываетAmbiguousTimeErrorесли данные содержат дату и время около границы перехода на летнее время (GH 13926)Ошибка в
pd.read_hdf()возвращает некорректный результат, когдаDataFrameсcategoricalстолбец и запрос, который не соответствует ни одному значению (GH 13792)Ошибка в
.ilocпри индексации с не лексически отсортированным MultiIndex (GH 13797)Ошибка в
.locпри индексировании строк дат в обратно отсортированномDatetimeIndex(GH 14316)Ошибка в
Seriesоператоры сравнения при работе с нульмерными массивами NumPy (GH 13006)Ошибка в
.combine_firstможет возвращать некорректныйdtype(GH 7630, GH 10567)Ошибка в
groupbyгдеapplyвозвращает разный результат в зависимости от того, является ли первый результатNoneили нет (GH 12824)Ошибка в
groupby(..).nth()где групповой ключ включается непоследовательно, если вызывается после.head()/.tail()(GH 12839)Ошибка в
.to_html,.to_latexи.to_stringмолча игнорирует пользовательский форматтер даты и времени, переданный черезformattersключевое слово (GH 10690)Ошибка в
DataFrame.iterrows(), не даваяSeriesподкласс, если определен (GH 13977)Ошибка в
pd.to_numericкогдаerrors='coerce'и вход содержит нехешируемые объекты (GH 13324)Ошибка в недопустимом
Timedeltaарифметические и сравнительные операции могут вызыватьValueErrorвместоTypeError(GH 13624)Ошибка в некорректном парсинге даты и времени в
to_datetimeиDatetimeIndexможет вызыватьTypeErrorвместоValueError(GH 11169, GH 11287)Ошибка в
Indexсоздан с учетом часового поясаTimestampи несоответствующиеtzопция некорректно преобразует часовой пояс (GH 13692)Ошибка в
DatetimeIndexс наносекундной частотой не включает временную метку, указанную сend(GH 13672)Ошибка в
Seriesпри установке среза сnp.timedelta64(GH 14155)Ошибка в
IndexвызываетOutOfBoundsDatetimeifdatetimeпревышаетdatetime64[ns]границы, а не принудительное преобразование кobjectтип данных (GH 13663)Ошибка в
Indexможет игнорировать указанныйdatetime64илиtimedelta64передан какdtype(GH 13981)Ошибка в
RangeIndexможет быть создан без аргументов, а не вызывает ошибкуTypeError(GH 13793)Ошибка в
.value_counts()вызываетOutOfBoundsDatetimeесли данные превышаютdatetime64[ns]bounds (GH 13663)Ошибка в
DatetimeIndexможет вызыватьOutOfBoundsDatetimeесли входные данныеnp.datetime64имеет другую единицу измерения, чемns(GH 9114)Ошибка в
Seriesсоздание сnp.datetime64который имеет другую единицу измерения, чемnsкакobjectdtype приводит к некорректным значениям (GH 13876)Ошибка в
resampleс данными timedelta, где данные были приведены к типу float (GH 13119).Ошибка в
pd.isnull()pd.notnull()raiseTypeErrorесли входные данные datetime-like имеют другую единицу измерения, чемns(GH 13389)Ошибка в
pd.merge()может вызыватьTypeErrorесли входные данные datetime-like имеют другую единицу измерения, чемns(GH 13389)Ошибка в
HDFStore/read_hdf()отброшенDatetimeIndex.nameiftzбыл установлен (GH 13884)Ошибка в
Categorical.remove_unused_categories()изменения.codesdtype в платформенный int (GH 13261)Ошибка в
groupbyсas_index=Falseвозвращает все NaN при группировке по нескольким столбцам, включая категориальный (GH 13204)Ошибка в
df.groupby(...)[...]где использование getitem сInt64Indexвызывало ошибку (GH 13731)Ошибка в CSS-классах, назначенных
DataFrame.styleдля имен индексов. Ранее они назначались"col_heading levelгдеcol " nбыло количество уровней + 1. Теперь они назначаются"index_name level, где" nявляется правильным уровнем для этого MultiIndex.Ошибка, где
pd.read_gbq()могло вызыватьImportError: No module named discoveryв результате конфликта имен с другим пакетом Python под названием apiclient (GH 13454)Ошибка в
Index.unionвозвращает некорректный результат с именованным пустым индексом (GH 13432)Ошибки в
Index.differenceиDataFrame.joinвызов исключения в Python3 при использовании смешанных целочисленных индексов (GH 13432, GH 12814)Ошибка в вычитании с учетом часового пояса
datetime.datetimeиз данных с учетом часового поясаdatetime64серия (GH 14088)Ошибка в
.to_excel()когда DataFrame содержит MultiIndex, который содержит метку со значением NaN (GH 13511)Ошибка в недопустимой строке смещения частоты, такой как "D1", "-2-3H", может не вызывать
ValueError(GH 13930)Ошибка в
concatиgroupbyдля иерархических фреймов сRangeIndexуровни (GH 13542).Ошибка в
Series.str.contains()для Series, содержащих толькоNaNзначенияobjectтип данных (GH 14171)Ошибка в
agg()функция на группированном датафрейме изменяет тип данныхdatetime64[ns]столбец вfloat64(GH 12821)Ошибка при использовании NumPy ufunc с
PeriodIndexдля добавления или вычитания целого числа вызываетIncompatibleFrequency. Обратите внимание, что использование стандартных операторов, таких как+или-рекомендуется, потому что стандартные операторы используют более эффективный путь (GH 13980)Ошибка в операциях над
NaTвозвращаяfloatвместоdatetime64[ns](GH 12941)Ошибка в
Seriesгибкие арифметические методы (например.add()) вызываетValueErrorкогдаaxis=None(GH 13894)Ошибка в
DataFrame.to_csv()сMultiIndexстолбцы, в которых была добавлена случайная пустая строка (GH 6618)Ошибка в
DatetimeIndex,TimedeltaIndexиPeriodIndex.equals()может возвращатьTrueкогда входные данные неIndexно содержит те же значения (GH 13107)Ошибка в присвоении для datetime с часовым поясом может не работать, если оно содержит datetime около границы перехода на летнее время (GH 14146)
Ошибка в
pd.eval()иHDFStoreзапрос обрезает длинные литералы с плавающей точкой в python 2 (GH 14241)Ошибка в
IndexвызываетKeyErrorотображение некорректного столбца, когда столбец не в df и столбцы содержат дублирующиеся значения (GH 13822)Ошибка в
PeriodиPeriodIndexсоздание неправильных дат, когда частота имеет комбинированные псевдонимы смещений (GH 13874)Ошибка в
.to_string()при вызове с целым числомline_widthиindex=Falseвызывает исключение UnboundLocalError, потому чтоidxссылка до присваивания.Ошибка в
eval()гдеresolversаргумент не принимал список (GH 14095)Ошибки в
stack,get_dummies,make_axis_dummiesкоторые не сохраняют категориальные типы данных в (много)индексах (GH 13854)PeriodIndexтеперь может приниматьlistиarrayкоторый содержитpd.NaT(GH 13430)Ошибка в
df.groupbyгде.median()возвращает произвольные значения, если сгруппированный датафрейм содержит пустые бины (GH 13629)Ошибка в
Index.copy()гдеnameпараметр игнорировался (GH 14302)
Участники#
Всего 117 человек внесли патчи в этот релиз. Люди со знаком «+» рядом с именами внесли патч впервые.
Adrien Emery +
Alex Alekseyev
Alex Vig +
Allen Riddell +
Amol +
Amol Agrawal +
Andy R. Terrel +
Anthonios Partheniou
Бен Кандел +
Боб Баксли +
Brett Rosen +
Camilo Cota +
Chris
Chris Grinolds
Chris Warth
Christian Hudon
Christopher C. Aycock
Daniel Siladji +
Дуглас МакНил
Дрюри Лутон +
Eduardo Blancas Reyes +
Elliot Marsden +
Evan Wright
Felix Marczinowski +
Фрэнсис Т. О’Донован
Geraint Duck +
Giacomo Ferroni +
Грант Роч +
Gábor Lipták
Haleemur Ali +
Hassan Shamim +
Iulius Curt +
Иван Назаров +
Jeff Reback
Jeffrey Gerard +
Jenn Olsen +
Jim Crist
Joe Jevnik
John Evans +
John Freeman
John Liekezer +
John W. O’Brien
John Zwinck +
Johnny Gill +
Jordan Erenrich +
Joris Van den Bossche
Josh Howes +
Jozef Brandys +
Ka Wo Chen
Камиль Синди +
Керби Шедден
Kernc +
Кевин Шеппард
Маттье Брюше +
Maximilian Roos
Michael Scherer +
Mike Graham +
Mortada Mehyar
Muhammad Haseeb Tariq +
Nate George +
Neil Parley +
Nicolas Bonnotte
OXPHOS
Pan Deng / Zora +
Paul +
Paul Mestemaker +
Pauli Virtanen
Pawel Kordek +
Пьетро Баттистон
Пётр Юха +
Ravi Kumar Nimmi +
Robert Gieseke
Роберт Керн +
Roger Thomas
Roy Keyes +
Russell Smith +
Сахил Дуа +
Санджив Лобо +
Sašo Stanovnik +
Shawn Heide +
Sinhrks
Stephen Kappel +
Стив Чой +
Stewart Henderson +
Sudarshan Konge +
Thomas A Caswell
Tom Augspurger
Tom Bird +
Uwe Hoffmann +
WillAyd +
Xiang Zhang +
YG-Riku +
Yadunandan +
Yaroslav Halchenko
Юичиро Канэко +
adneu
agraboso +
babakkeyvani +
c123w +
chris-b1
cmazzullo +
conquistador1492 +
cr3 +
dsm054
gfyoung
harshul1610 +
iamsimha +
jackieleng +
mpuels +
pijucha +
priyankjain +
sinhrks
wcwagner +
yui-knk +
zhangjinjie +
znmean +
Янь Фацай (Yan Facai) +