Версия 0.15.0 (18 октября 2014)#
Это основной выпуск с версии 0.14.1 и включает небольшое количество изменений API, несколько новых функций, улучшений и оптимизаций производительности, а также большое количество исправлений ошибок. Мы рекомендуем всем пользователям обновиться до этой версии.
Предупреждение
pandas >= 0.15.0 больше не будет поддерживать совместимость с версиями NumPy < 1.7.0. Если вы хотите использовать последние версии pandas, пожалуйста, обновитесь до NumPy >= 1.7.0 (GH 7711)
Основные моменты включают:
The
Categoricalтип был интегрирован как полноценный тип pandas, см. здесьНовый скалярный тип
Timedelta, и новый тип индексаTimedeltaIndex, см. здесьНовый аксессор свойств, подобных дате и времени
.dtдля Series, см. Свойства DatetimelikeНовое отображение DataFrame по умолчанию для
df.info()чтобы включить использование памяти, см. Использование памятиread_csvтеперь по умолчанию игнорирует пустые строки при парсинге, см. здесьИзменение API при использовании индексов в операциях над множествами, см. здесь
Улучшения в обработке часовых поясов, см. здесь
Много улучшений в функциях скользящих и расширяющихся моментов, см. здесь
Внутренний рефакторинг
Indexкласс больше не наследуетndarray, см. Внутренний рефакторингудаление поддержки для
PyTablesменьше версии 3.0.0, иnumexprменьше версии 2.1 (GH 7990)Разделить документацию по индексации на Индексирование и выбор данных и MultiIndex / Расширенное индексирование
Выделение документации по строковым методам в Работа с текстовыми данными
Проверьте Изменения API и устаревшие возможности перед обновлением
Предупреждение
В версии 0.15.0 Index был внутренне переработан, чтобы больше не наследовать от ndarray
но вместо этого подкласс PandasObject, аналогично остальным объектам pandas. Это изменение позволяет очень просто создавать подклассы и новые типы индексов. Это должно быть
прозрачным изменением с очень ограниченными последствиями для API (см. Внутренний рефакторинг)
Предупреждение
Рефакторинг в Categorical изменил конструктор с двумя аргументами с
"коды/метки и уровни" на "значения и уровни (теперь называемые 'категориями')". Это может привести к тонким ошибкам. Если вы используете
Categorical напрямую, пожалуйста, проверьте свой код перед обновлением до этой версии pandas и измените его, чтобы использовать from_codes() конструктор. Подробнее см. Categorical здесь
Новые возможности#
Категориальные данные в Series/DataFrame#
Categorical теперь может быть включён в Series и DataFrames и получил новые
методы для манипуляции. Спасибо Jan Schulz за большую часть этого API/реализации. (GH 3943, GH 5313, GH 5314,
GH 7444, GH 7839, GH 7848, GH 7864, GH 7914, GH 7768, GH 8006, GH 3678,
GH 8075, GH 8076, GH 8143, GH 8453, GH 8518).
Полную документацию см. в введение в категориальные данные и документация API.
In [1]: df = pd.DataFrame({"id": [1, 2, 3, 4, 5, 6],
...: "raw_grade": ['a', 'b', 'b', 'a', 'a', 'e']})
...:
In [2]: df["grade"] = df["raw_grade"].astype("category")
In [3]: df["grade"]
Out[3]:
0 a
1 b
2 b
3 a
4 a
5 e
Name: grade, Length: 6, dtype: category
Categories (3, object): ['a', 'b', 'e']
# Rename the categories
In [4]: df["grade"] = df["grade"].cat.rename_categories(["very good", "good", "very bad"])
# Reorder the categories and simultaneously add the missing categories
In [5]: df["grade"] = df["grade"].cat.set_categories(["very bad", "bad",
...: "medium", "good", "very good"])
...:
In [6]: df["grade"]
Out[6]:
0 very good
1 good
2 good
3 very good
4 very good
5 very bad
Name: grade, Length: 6, dtype: category
Categories (5, object): ['very bad', 'bad', 'medium', 'good', 'very good']
In [7]: df.sort_values("grade")
Out[7]:
id raw_grade grade
5 6 e very bad
1 2 b good
2 3 b good
0 1 a very good
3 4 a very good
4 5 a very good
[6 rows x 3 columns]
In [8]: df.groupby("grade", observed=False).size()
Out[8]:
grade
very bad 1
bad 0
medium 0
good 2
very good 3
Length: 5, dtype: int64
pandas.core.group_aggиpandas.core.factor_aggбыли удалены. В качестве альтернативы создайте датафрейм и используйтеdf.groupby(.).agg( ) Предоставление "кодов/меток и уровней" в
Categoricalконструктор больше не поддерживается. Передача двух аргументов в конструктор теперь интерпретируется как "значения и уровни (теперь называемые 'категориями')". Пожалуйста, измените свой код, чтобы использоватьfrom_codes()конструктор.The
Categorical.labelsатрибут был переименован вCategorical.codesи доступен только для чтения. Если вы хотите манипулировать кодами, используйте один из API методы на Categoricals.The
Categorical.levelsатрибут переименован вCategorical.categories.
TimedeltaIndex/скаляр#
Мы вводим новый скалярный тип Timedelta, который является подклассом datetime.timedelta, и ведет себя аналогичным образом, но обеспечивает совместимость с np.timedelta64 типов, а также множество пользовательских представлений, парсинга и атрибутов.
Этот тип очень похож на то, как Timestamp работает для datetimes. Это удобный API-контейнер для типа. См. документация.
(GH 3009, GH 4533, GH 8209, GH 8187, GH 8190, GH 7869, GH 7661, GH 8345, GH 8471)
Предупреждение
Timedelta скаляры (и TimedeltaIndex) компонентные поля являются не тот же как компонентные поля на datetime.timedelta объект. Например, .seconds на datetime.timedelta объект возвращает общее количество секунд, объединенных между hours, minutes и seconds. В отличие от этого, pandas Timedelta разделяет часы, минуты, микросекунды и наносекунды отдельно.
# Timedelta accessor
In [9]: tds = pd.Timedelta('31 days 5 min 3 sec')
In [10]: tds.minutes
Out[10]: 5L
In [11]: tds.seconds
Out[11]: 3L
# datetime.timedelta accessor
# this is 5 minutes * 60 + 3 seconds
In [12]: tds.to_pytimedelta().seconds
Out[12]: 303
Примечание: это больше не верно, начиная с v0.16.0, где полная
совместимость с datetime.timedelta вводится. См.
запись whatsnew для версии 0.16.0
Предупреждение
До версии 0.15.0 pd.to_timedelta вернет Series для ввода, похожего на список/Series, и np.timedelta64 для скалярного ввода.
Теперь будет возвращаться TimedeltaIndex для ввода в виде списка, Series для ввода Series, и Timedelta для скалярного ввода.
Аргументы для pd.to_timedelta теперь (arg,unit='ns',box=True,coerce=False), ранее были (arg,box=True,unit='ns') так как они более логичны.
Создать скаляр
In [9]: pd.Timedelta('1 days 06:05:01.00003')
Out[9]: Timedelta('1 days 06:05:01.000030')
In [10]: pd.Timedelta('15.5us')
Out[10]: Timedelta('0 days 00:00:00.000015500')
In [11]: pd.Timedelta('1 hour 15.5us')
Out[11]: Timedelta('0 days 01:00:00.000015500')
# negative Timedeltas have this string repr
# to be more consistent with datetime.timedelta conventions
In [12]: pd.Timedelta('-1us')
Out[12]: Timedelta('-1 days +23:59:59.999999')
# a NaT
In [13]: pd.Timedelta('nan')
Out[13]: NaT
Доступ к полям для Timedelta
In [14]: td = pd.Timedelta('1 hour 3m 15.5us')
In [15]: td.seconds
Out[15]: 3780
In [16]: td.microseconds
Out[16]: 15
In [17]: td.nanoseconds
Out[17]: 500
Создать TimedeltaIndex
In [18]: pd.TimedeltaIndex(['1 days', '1 days, 00:00:05',
....: np.timedelta64(2, 'D'),
....: datetime.timedelta(days=2, seconds=2)])
....:
Out[18]:
TimedeltaIndex(['1 days 00:00:00', '1 days 00:00:05', '2 days 00:00:00',
'2 days 00:00:02'],
dtype='timedelta64[ns]', freq=None)
Создание TimedeltaIndex с обычным диапазоном
In [19]: pd.timedelta_range('1 days', periods=5, freq='D')
Out[19]: TimedeltaIndex(['1 days', '2 days', '3 days', '4 days', '5 days'], dtype='timedelta64[ns]', freq='D')
In [20]: pd.timedelta_range(start='1 days', end='2 days', freq='30T')
Out[20]:
TimedeltaIndex(['1 days 00:00:00', '1 days 00:30:00', '1 days 01:00:00',
'1 days 01:30:00', '1 days 02:00:00', '1 days 02:30:00',
'1 days 03:00:00', '1 days 03:30:00', '1 days 04:00:00',
'1 days 04:30:00', '1 days 05:00:00', '1 days 05:30:00',
'1 days 06:00:00', '1 days 06:30:00', '1 days 07:00:00',
'1 days 07:30:00', '1 days 08:00:00', '1 days 08:30:00',
'1 days 09:00:00', '1 days 09:30:00', '1 days 10:00:00',
'1 days 10:30:00', '1 days 11:00:00', '1 days 11:30:00',
'1 days 12:00:00', '1 days 12:30:00', '1 days 13:00:00',
'1 days 13:30:00', '1 days 14:00:00', '1 days 14:30:00',
'1 days 15:00:00', '1 days 15:30:00', '1 days 16:00:00',
'1 days 16:30:00', '1 days 17:00:00', '1 days 17:30:00',
'1 days 18:00:00', '1 days 18:30:00', '1 days 19:00:00',
'1 days 19:30:00', '1 days 20:00:00', '1 days 20:30:00',
'1 days 21:00:00', '1 days 21:30:00', '1 days 22:00:00',
'1 days 22:30:00', '1 days 23:00:00', '1 days 23:30:00',
'2 days 00:00:00'],
dtype='timedelta64[ns]', freq='30T')
Теперь вы можете использовать TimedeltaIndex в качестве индекса объекта pandas
In [20]: s = pd.Series(np.arange(5),
....: index=pd.timedelta_range('1 days', periods=5, freq='s'))
....:
In [21]: s
Out[21]:
1 days 00:00:00 0
1 days 00:00:01 1
1 days 00:00:02 2
1 days 00:00:03 3
1 days 00:00:04 4
Freq: s, Length: 5, dtype: int64
Вы можете выбирать с частичными строковыми выборками
In [22]: s['1 day 00:00:02']
Out[22]: 2
In [23]: s['1 day':'1 day 00:00:02']
Out[23]:
1 days 00:00:00 0
1 days 00:00:01 1
1 days 00:00:02 2
Freq: s, Length: 3, dtype: int64
Наконец, комбинация TimedeltaIndex с DatetimeIndex позволяют определенные комбинационные операции, которые NaT сохраняя:
In [24]: tdi = pd.TimedeltaIndex(['1 days', pd.NaT, '2 days'])
In [25]: tdi.tolist()
Out[25]: [Timedelta('1 days 00:00:00'), NaT, Timedelta('2 days 00:00:00')]
In [26]: dti = pd.date_range('20130101', periods=3)
In [27]: dti.tolist()
Out[27]:
[Timestamp('2013-01-01 00:00:00'),
Timestamp('2013-01-02 00:00:00'),
Timestamp('2013-01-03 00:00:00')]
In [28]: (dti + tdi).tolist()
Out[28]: [Timestamp('2013-01-02 00:00:00'), NaT, Timestamp('2013-01-05 00:00:00')]
In [29]: (dti - tdi).tolist()
Out[29]: [Timestamp('2012-12-31 00:00:00'), NaT, Timestamp('2013-01-01 00:00:00')]
итерация
Seriesнапример,list(Series(...))oftimedelta64[ns]до версии 0.15.0 возвращалnp.timedelta64для каждого элемента. Теперь они будут обёрнуты вTimedelta.
Использование памяти#
Реализованы методы для определения использования памяти DataFrame. См. Часто задаваемые вопросы для получения дополнительной информации. (GH 6852).
Новая опция отображения display.memory_usage (см. Опции и настройки) устанавливает поведение по умолчанию для memory_usage аргумент в df.info() метод. По умолчанию display.memory_usage является True.
In [30]: dtypes = ['int64', 'float64', 'datetime64[ns]', 'timedelta64[ns]',
....: 'complex128', 'object', 'bool']
....:
In [31]: n = 5000
In [32]: data = {t: np.random.randint(100, size=n).astype(t) for t in dtypes}
In [33]: df = pd.DataFrame(data)
In [34]: df['categorical'] = df['object'].astype('category')
In [35]: df.info()
RangeIndex: 5000 entries, 0 to 4999
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 int64 5000 non-null int64
1 float64 5000 non-null float64
2 datetime64[ns] 5000 non-null datetime64[ns]
3 timedelta64[ns] 5000 non-null timedelta64[ns]
4 complex128 5000 non-null complex128
5 object 5000 non-null object
6 bool 5000 non-null bool
7 categorical 5000 non-null category
dtypes: bool(1), category(1), complex128(1), datetime64[ns](1), float64(1), int64(1), object(1), timedelta64[ns](1)
memory usage: 288.2+ KB
Кроме того memory_usage() является доступным методом для объекта dataframe, который возвращает использование памяти каждого столбца.
In [36]: df.memory_usage(index=True)
Out[36]:
Index 128
int64 40000
float64 40000
datetime64[ns] 40000
timedelta64[ns] 40000
complex128 80000
object 40000
bool 5000
categorical 9968
Length: 9, dtype: int64
аксессор Series.dt#
Series получил аксессор для краткого возврата свойств, подобных datetime, для values Series, если это Series типа datetime/period. (GH 7207)
Это вернет Series, индексированный как существующий Series. См. документация
# datetime
In [37]: s = pd.Series(pd.date_range('20130101 09:10:12', periods=4))
In [38]: s
Out[38]:
0 2013-01-01 09:10:12
1 2013-01-02 09:10:12
2 2013-01-03 09:10:12
3 2013-01-04 09:10:12
Length: 4, dtype: datetime64[ns]
In [39]: s.dt.hour
Out[39]:
0 9
1 9
2 9
3 9
Length: 4, dtype: int32
In [40]: s.dt.second
Out[40]:
0 12
1 12
2 12
3 12
Length: 4, dtype: int32
In [41]: s.dt.day
Out[41]:
0 1
1 2
2 3
3 4
Length: 4, dtype: int32
In [42]: s.dt.freq
Out[42]: 'D'
Это позволяет использовать удобные выражения, такие как:
In [43]: s[s.dt.day == 2]
Out[43]:
1 2013-01-02 09:10:12
Length: 1, dtype: datetime64[ns]
Вы можете легко создавать преобразования с учетом часового пояса:
In [44]: stz = s.dt.tz_localize('US/Eastern')
In [45]: stz
Out[45]:
0 2013-01-01 09:10:12-05:00
1 2013-01-02 09:10:12-05:00
2 2013-01-03 09:10:12-05:00
3 2013-01-04 09:10:12-05:00
Length: 4, dtype: datetime64[ns, US/Eastern]
In [46]: stz.dt.tz
Out[46]:
Вы также можете объединять такие операции в цепочку:
In [47]: s.dt.tz_localize('UTC').dt.tz_convert('US/Eastern')
Out[47]:
0 2013-01-01 04:10:12-05:00
1 2013-01-02 04:10:12-05:00
2 2013-01-03 04:10:12-05:00
3 2013-01-04 04:10:12-05:00
Length: 4, dtype: datetime64[ns, US/Eastern]
The .dt аксессор работает для типов period и timedelta.
# period
In [48]: s = pd.Series(pd.period_range('20130101', periods=4, freq='D'))
In [49]: s
Out[49]:
0 2013-01-01
1 2013-01-02
2 2013-01-03
3 2013-01-04
Length: 4, dtype: period[D]
In [50]: s.dt.year
Out[50]:
0 2013
1 2013
2 2013
3 2013
Length: 4, dtype: int64
In [51]: s.dt.day
Out[51]:
0 1
1 2
2 3
3 4
Length: 4, dtype: int64
# timedelta
In [52]: s = pd.Series(pd.timedelta_range('1 day 00:00:05', periods=4, freq='s'))
In [53]: s
Out[53]:
0 1 days 00:00:05
1 1 days 00:00:06
2 1 days 00:00:07
3 1 days 00:00:08
Length: 4, dtype: timedelta64[ns]
In [54]: s.dt.days
Out[54]:
0 1
1 1
2 1
3 1
Length: 4, dtype: int64
In [55]: s.dt.seconds
Out[55]:
0 5
1 6
2 7
3 8
Length: 4, dtype: int32
In [56]: s.dt.components
Out[56]:
days hours minutes seconds milliseconds microseconds nanoseconds
0 1 0 0 5 0 0 0
1 1 0 0 6 0 0 0
2 1 0 0 7 0 0 0
3 1 0 0 8 0 0 0
[4 rows x 7 columns]
Улучшения обработки часовых поясов#
tz_localize(None)для учитывающих часовой поясTimestampиDatetimeIndexтеперь удаляет часовой пояс, содержащий местное время, ранее это приводило кExceptionилиTypeError(GH 7812)In [58]: ts = pd.Timestamp('2014-08-01 09:00', tz='US/Eastern') In[59]: ts Out[59]: Timestamp('2014-08-01 09:00:00-0400', tz='US/Eastern') In [60]: ts.tz_localize(None) Out[60]: Timestamp('2014-08-01 09:00:00') In [61]: didx = pd.date_range(start='2014-08-01 09:00', freq='H', ....: periods=10, tz='US/Eastern') ....: In [62]: didx Out[62]: DatetimeIndex(['2014-08-01 09:00:00-04:00', '2014-08-01 10:00:00-04:00', '2014-08-01 11:00:00-04:00', '2014-08-01 12:00:00-04:00', '2014-08-01 13:00:00-04:00', '2014-08-01 14:00:00-04:00', '2014-08-01 15:00:00-04:00', '2014-08-01 16:00:00-04:00', '2014-08-01 17:00:00-04:00', '2014-08-01 18:00:00-04:00'], dtype='datetime64[ns, US/Eastern]', freq='H') In [63]: didx.tz_localize(None) Out[63]: DatetimeIndex(['2014-08-01 09:00:00', '2014-08-01 10:00:00', '2014-08-01 11:00:00', '2014-08-01 12:00:00', '2014-08-01 13:00:00', '2014-08-01 14:00:00', '2014-08-01 15:00:00', '2014-08-01 16:00:00', '2014-08-01 17:00:00', '2014-08-01 18:00:00'], dtype='datetime64[ns]', freq=None)
tz_localizeтеперь принимаетambiguousключевое слово, которое позволяет передавать массив булевых значений, указывающих, относится ли дата к летнему времени или нет, 'NaT' для установки времени перехода в NaT, 'infer' для определения летнего/нелетнего времени и 'raise' (по умолчанию) дляAmbiguousTimeErrorбудет вызвано. См. документация для дополнительных деталей (GH 7943)DataFrame.tz_localizeиDataFrame.tz_convertтеперь принимает необязательныйlevelаргумент для локализации конкретного уровня MultiIndex (GH 7846)Timestamp.tz_localizeиTimestamp.tz_convertтеперь вызываютTypeErrorв случаях ошибок, а неException(GH 8025)временной ряд/индекс, локализованный в UTC, при вставке в Series/DataFrame сохранит часовой пояс UTC (а не будет наивным)
datetime64[ns]) какobjectтип данных (GH 8411)Timestamp.__repr__отображаетdateutil.tz.tzoffsetinfo (GH 7907)
Улучшения моментов скользящих/расширяющихся окон#
rolling_min(),rolling_max(),rolling_cov(), иrolling_corr()теперь возвращают объекты со всемиNaNкогдаlen(arg) < min_periods <= windowвместо вызова исключения. (Это делает все скользящие функции согласованными в этом поведении). (GH 7766)До версии 0.15.0
In [57]: s = pd.Series([10, 11, 12, 13])
In [15]: pd.rolling_min(s, window=10, min_periods=5) ValueError: min_periods (5) must be <= window (4)
Новое поведение
In [4]: pd.rolling_min(s, window=10, min_periods=5) Out[4]: 0 NaN 1 NaN 2 NaN 3 NaN dtype: float64
rolling_max(),rolling_min(),rolling_sum(),rolling_mean(),rolling_median(),rolling_std(),rolling_var(),rolling_skew(),rolling_kurt(),rolling_quantile(),rolling_cov(),rolling_corr(),rolling_corr_pairwise(),rolling_window(), иrolling_apply()сcenter=Trueранее возвращал результат той же структуры, что и входные данныеargсNaNв конечном(window-1)/2записей.Теперь окончательный
(window-1)/2элементы результата вычисляются так, как если бы входные данныеargследовали за(window-1)/2NaNзначения (или с уменьшающимися окнами, в случаеrolling_apply()). (GH 7925, GH 8269)Предыдущее поведение (обратите внимание, что конечное значение
NaN):In [7]: pd.rolling_sum(Series(range(4)), window=3, min_periods=0, center=True) Out[7]: 0 1 1 3 2 6 3 NaN dtype: float64
Новое поведение (обратите внимание, что конечное значение
5 = sum([2, 3, NaN])):In [7]: pd.rolling_sum(pd.Series(range(4)), window=3, ....: min_periods=0, center=True) Out[7]: 0 1 1 3 2 6 3 5 dtype: float64
rolling_window()теперь правильно нормализует веса в режиме скользящего среднего (mean=True) так, чтобы вычисленные взвешенные средние (например, 'triang', 'gaussian') распределялись вокруг тех же средних, что и вычисленные без взвешивания (т.е. 'boxcar'). См. примечание о нормализации для получения дополнительных сведений. (GH 7618)In [58]: s = pd.Series([10.5, 8.8, 11.4, 9.7, 9.3])
Поведение до версии 0.15.0:
In [39]: pd.rolling_window(s, window=3, win_type='triang', center=True) Out[39]: 0 NaN 1 6.583333 2 6.883333 3 6.683333 4 NaN dtype: float64
Новое поведение
In [10]: pd.rolling_window(s, window=3, win_type='triang', center=True) Out[10]: 0 NaN 1 9.875 2 10.325 3 10.025 4 NaN dtype: float64
Удалено
centerаргумент из всехexpanding_функции (см. list), как результаты, полученные приcenter=Trueне имело особого смысла. (GH 7925)Добавлен опциональный
ddofаргумент дляexpanding_cov()иrolling_cov(). Значение по умолчанию для1обратно совместим. (GH 8279)Документировано
ddofаргумент дляexpanding_var(),expanding_std(),rolling_var(), иrolling_std(). Поддержка этих функций дляddofаргумент (со значением по умолчанию1) ранее не был задокументирован. (GH 8064)ewma(),ewmstd(),ewmvol(),ewmvar(),ewmcov(), иewmcorr()теперь интерпретируютmin_periodsтаким же образом, какrolling_*()иexpanding_*()функции делают: данная запись результата будетNaNесли (расширяющееся, в данном случае) окно не содержит по крайней мереmin_periodsзначения. Предыдущее поведение было установлено вNaNthemin_periodsзаписи, начиная с первой не-NaNзначение. (GH 7977)Предыдущее поведение (обратите внимание, что значения начинаются с индекса
2, что являетсяmin_periodsпосле индекса0(индекс первого непустого значения):In [59]: s = pd.Series([1, None, None, None, 2, 3])
In [51]: pd.ewma(s, com=3., min_periods=2) Out[51]: 0 NaN 1 NaN 2 1.000000 3 1.000000 4 1.571429 5 2.189189 dtype: float64
Новое поведение (обратите внимание, что значения начинаются с индекса
4, расположение 2-го (посколькуmin_periods=2) непустое значение):In [2]: pd.ewma(s, com=3., min_periods=2) Out[2]: 0 NaN 1 NaN 2 NaN 3 NaN 4 1.759644 5 2.383784 dtype: float64
ewmstd(),ewmvol(),ewmvar(),ewmcov(), иewmcorr()теперь имеют необязательныйadjustаргумент, так же какewma()делает, влияя на то, как рассчитываются веса. Значение по умолчанию дляadjustявляетсяTrue, что обратно совместимо. См. Функции экспоненциально взвешенных моментов для подробностей. (GH 7911)ewma(),ewmstd(),ewmvol(),ewmvar(),ewmcov(), иewmcorr()теперь имеют необязательныйignore_naаргумент. Когдаignore_na=False(по умолчанию), пропущенные значения учитываются в расчёте весов. Когдаignore_na=True(что воспроизводит поведение до версии 0.15.0), пропущенные значения игнорируются в расчёте весов. (GH 7543)In [7]: pd.ewma(pd.Series([None, 1., 8.]), com=2.) Out[7]: 0 NaN 1 1.0 2 5.2 dtype: float64 In [8]: pd.ewma(pd.Series([1., None, 8.]), com=2., ....: ignore_na=True) # pre-0.15.0 behavior Out[8]: 0 1.0 1 1.0 2 5.2 dtype: float64 In [9]: pd.ewma(pd.Series([1., None, 8.]), com=2., ....: ignore_na=False) # new default Out[9]: 0 1.000000 1 1.000000 2 5.846154 dtype: float64
Предупреждение
По умолчанию (
ignore_na=False)ewm*()расчёт весов функций при наличии пропущенных значений отличается от версий до 0.15.0. Для воспроизведения расчёта весов до версии 0.15.0 при наличии пропущенных значений необходимо явно указатьignore_na=True.Ошибка в
expanding_cov(),expanding_corr(),rolling_cov(),rolling_cor(),ewmcov(), иewmcorr()возвращение результатов с колонками, отсортированными по имени, и выдача ошибки для неуникальных колонок; теперь обрабатывает неуникальные колонки и возвращает колонки в исходном порядке (за исключением случая двух DataFrame сpairwise=False, где поведение не изменилось) (GH 7542)Ошибка в
rolling_count()иexpanding_*()функции, ненужно выдающие сообщение об ошибке для данных нулевой длины (GH 8056)Ошибка в
rolling_apply()иexpanding_apply()интерпретацияmin_periods=0какmin_periods=1(GH 8080)Ошибка в
expanding_std()иexpanding_var()для одного значения, вызывая запутанное сообщение об ошибке (GH 7900)Ошибка в
rolling_std()иrolling_var()для одного значения, производя0вместоNaN(GH 7900)Ошибка в
ewmstd(),ewmvol(),ewmvar(), иewmcov()расчет факторов устранения смещения приbias=False(по умолчанию). Ранее использовался неправильный постоянный множитель, основанный наadjust=True,ignore_na=Trueи бесконечного числа наблюдений. Теперь используется другой коэффициент для каждой записи, основанный на фактических весах (аналогично обычномуN/(N-1)фактор). В частности, для одной точки значениеNaNвозвращается, когдаbias=False, тогда как ранее значение (приблизительно)0был возвращен.Например, рассмотрим следующие результаты до версии 0.15.0 для
ewmvar(..., bias=False), и соответствующие корректирующие коэффициенты:In [60]: s = pd.Series([1., 2., 0., 4.])
In [89]: pd.ewmvar(s, com=2., bias=False) Out[89]: 0 -2.775558e-16 1 3.000000e-01 2 9.556787e-01 3 3.585799e+00 dtype: float64 In [90]: pd.ewmvar(s, com=2., bias=False) / pd.ewmvar(s, com=2., bias=True) Out[90]: 0 1.25 1 1.25 2 1.25 3 1.25 dtype: float64
Обратите внимание, что запись
0приблизительно равно 0, а коэффициенты устранения смещения являются константой 1.25. Для сравнения, следующие результаты 0.15.0 имеютNaNдля записи0, и коэффициенты устранения смещения уменьшаются (к 1.25):In [14]: pd.ewmvar(s, com=2., bias=False) Out[14]: 0 NaN 1 0.500000 2 1.210526 3 4.089069 dtype: float64 In [15]: pd.ewmvar(s, com=2., bias=False) / pd.ewmvar(s, com=2., bias=True) Out[15]: 0 NaN 1 2.083333 2 1.583333 3 1.425439 dtype: float64
См. Функции экспоненциально взвешенных моментов для подробностей. (GH 7912)
Улучшения в модуле SQL IO#
Добавлена поддержка для
chunksizeпараметр дляto_sqlфункция. Это позволяет записывать DataFrame частями и избегать ошибок переполнения размера пакета (GH 8062).Добавлена поддержка для
chunksizeпараметр дляread_sqlфункция. Указание этого аргумента вернет итератор по частям результата запроса (GH 2908).Добавлена поддержка записи
datetime.dateиdatetime.timeстолбцы типа object сto_sql(GH 6932).Добавлена поддержка указания
schemaдля чтения/записи сread_sql_tableиto_sql(GH 7441, GH 7952). Например:df.to_sql('table', engine, schema='other_schema') # noqa F821 pd.read_sql_table('table', engine, schema='other_schema') # noqa F821
Добавлена поддержка записи
NaNзначения сto_sql(GH 2754).Добавлена поддержка записи столбцов datetime64 с
to_sqlдля всех типов баз данных (GH 7103).
Обратно несовместимые изменения API#
Критические изменения#
Изменения API, связанные с Categorical (см. здесь
подробнее):
The
Categoricalконструктор с двумя аргументами изменился с «коды/метки и уровни» на «значения и уровни (теперь называемые 'категориями')». Это может привести к скрытым ошибкам. Если вы используетеCategoricalнапрямую, пожалуйста, проверьте свой код, изменив его на использованиеfrom_codes()конструктор.Старый вызов функции (до 0.15.0):
pd.Categorical([0,1,0,2,1], levels=['a', 'b', 'c'])
придётся адаптировать к следующему, чтобы сохранить то же поведение:
In [2]: pd.Categorical.from_codes([0,1,0,2,1], categories=['a', 'b', 'c']) Out[2]: [a, b, a, c, b] Categories (3, object): [a, b, c]
Изменения API, связанные с введением Timedelta скаляр (см.
выше подробнее):
До версии 0.15.0
to_timedelta()вернетSeriesдля ввода в виде списка/Series, иnp.timedelta64для скалярного ввода. Теперь он будет возвращатьTimedeltaIndexдля ввода в виде списка,Seriesдля ввода Series, иTimedeltaдля скалярного ввода.
Об изменениях API, связанных с функциями rolling и expanding, см. подробный обзор выше.
Другие заметные изменения API:
Согласованность при индексировании с
.locи списокоподобный индексатор, когда значения не найдены.In [61]: df = pd.DataFrame([['a'], ['b']], index=[1, 2]) In [62]: df Out[62]: 0 1 a 2 b [2 rows x 1 columns]
В предыдущих версиях была разница между этими двумя конструкциями:
df.loc[[3]]вернет фрейм, переиндексированный на 3 (со всемиnp.nanзначения)df.loc[[3],:]вызоветKeyError.
Оба теперь будут вызывать
KeyError. Правило заключается в том, что как минимум 1 индексатор должен быть найден при использовании данных, подобных списку, и.loc(GH 7999)Кроме того, в предыдущих версиях они также различались:
df.loc[[1,3]]вернет фрейм, переиндексированный по [1,3]df.loc[[1,3],:]вызоветKeyError.
Оба теперь вернут фрейм, переиндексированный по [1,3]. Например,
In [3]: df.loc[[1, 3]] Out[3]: 0 1 a 3 NaN In [4]: df.loc[[1, 3], :] Out[4]: 0 1 a 3 NaN
Это также можно увидеть при индексации по нескольким осям с
Panel.>>> p = pd.Panel(np.arange(2 * 3 * 4).reshape(2, 3, 4), ... items=['ItemA', 'ItemB'], ... major_axis=[1, 2, 3], ... minor_axis=['A', 'B', 'C', 'D']) >>> p
Dimensions: 2 (items) x 3 (major_axis) x 4 (minor_axis) Items axis: ItemA to ItemB Major_axis axis: 1 to 3 Minor_axis axis: A to D Следующее вызовет ошибку
KeyErrorдо версии 0.15.0:In [5]: Out[5]: ItemA ItemD 1 3 NaN 2 7 NaN 3 11 NaN
Кроме того,
.locвызовет исключение Если в MultiIndex с индексом в виде списка не найдены значения:In [63]: s = pd.Series(np.arange(3, dtype='int64'), ....: index=pd.MultiIndex.from_product([['A'], ....: ['foo', 'bar', 'baz']], ....: names=['one', 'two']) ....: ).sort_index() ....: In [64]: s Out[64]: one two A bar 1 baz 2 foo 0 Length: 3, dtype: int64 In [65]: try: ....: s.loc[['D']] ....: except KeyError as e: ....: print("KeyError: " + str(e)) ....: KeyError: "['D'] not in index"
Присвоение значений
Noneтеперь учитывает тип данных при выборе 'пустого' значения (GH 7941).Ранее присваивание
Noneв числовых контейнерах изменял dtype на object (или вызывал ошибку, в зависимости от вызова). Теперь используетсяNaN:In [66]: s = pd.Series([1., 2., 3.]) In [67]: s.loc[0] = None In [68]: s Out[68]: 0 NaN 1 2.0 2 3.0 Length: 3, dtype: float64
NaTтеперь используется аналогично для контейнеров datetime.Для объектных контейнеров мы теперь сохраняем
Noneзначения (ранее они преобразовывались вNaNзначений).In [69]: s = pd.Series(["a", "b", "c"]) In [70]: s.loc[0] = None In [71]: s Out[71]: 0 None 1 b 2 c Length: 3, dtype: object
Чтобы вставить
NaN, вы должны явно использоватьnp.nan. См. документация.В предыдущих версиях обновление объекта pandas на месте не отражалось в других ссылках Python на этот объект. (GH 8511, GH 5104)
In [72]: s = pd.Series([1, 2, 3]) In [73]: s2 = s In [74]: s += 1.5
Поведение до версии v0.15.0
# the original object In [5]: s Out[5]: 0 2.5 1 3.5 2 4.5 dtype: float64 # a reference to the original object In [7]: s2 Out[7]: 0 1 1 2 2 3 dtype: int64
Теперь это правильное поведение
# the original object In [75]: s Out[75]: 0 2.5 1 3.5 2 4.5 Length: 3, dtype: float64 # a reference to the original object In [76]: s2 Out[76]: 0 2.5 1 3.5 2 4.5 Length: 3, dtype: float64
Сделаны как C-основанные, так и Python-движки для
read_csvиread_tableигнорировать пустые строки во входных данных, а также строки, заполненные пробелами, при условии, чтоsepне является пробелом. Это изменение API, которое можно контролировать с помощью параметра ключевого словаskip_blank_lines. См. документация (GH 4466)Временной ряд/индекс, локализованный в UTC при вставке в Series/DataFrame, сохранит часовой пояс UTC и будет вставлен как
objectdtype, а не преобразуется в наивныйdatetime64[ns](GH 8411).Ошибка при передаче
DatetimeIndexс часовым поясом, который не сохранялся при построении DataFrame из словаря (GH 7822)В предыдущих версиях это удаляло часовой пояс, теперь он сохраняет часовой пояс, но дает столбец
objectdtype:In [77]: i = pd.date_range('1/1/2011', periods=3, freq='10s', tz='US/Eastern') In [78]: i Out[78]: DatetimeIndex(['2011-01-01 00:00:00-05:00', '2011-01-01 00:00:10-05:00', '2011-01-01 00:00:20-05:00'], dtype='datetime64[ns, US/Eastern]', freq='10s') In [79]: df = pd.DataFrame({'a': i}) In [80]: df Out[80]: a 0 2011-01-01 00:00:00-05:00 1 2011-01-01 00:00:10-05:00 2 2011-01-01 00:00:20-05:00 [3 rows x 1 columns] In [81]: df.dtypes Out[81]: a datetime64[ns, US/Eastern] Length: 1, dtype: object
Ранее это приводило бы к столбцу
datetime64dtype, но без информации о часовом поясе.Поведение присвоения столбца существующему датафрейму как
df['a'] = iостается неизменным (это уже возвращалоobjectстолбец с часовым поясом).При передаче нескольких уровней в
stack(), теперь будет вызыватьValueErrorкогда уровни не являются всеми именами уровней или всеми номерами уровней (GH 7660). См. Изменение формы путем укладки и разложения.Вызвать
ValueErrorвdf.to_hdfс 'фиксированным' форматом, еслиdfимеет неуникальные колонки, так как результирующий файл будет поврежден (GH 7761)SettingWithCopyвызывать/предупреждения (в соответствии с опциейmode.chained_assignment) теперь будет выдаваться при установке значения на срезанном DataFrame со смешанными типами данных с использованием цепочечного присваивания. (GH 7845, GH 7950)In [1]: df = pd.DataFrame(np.arange(0, 9), columns=['count']) In [2]: df['group'] = 'b' In [3]: df.iloc[0:5]['group'] = 'a' /usr/local/bin/ipython:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
merge,DataFrame.merge, иordered_mergeтеперь возвращают тот же тип какleftаргумент (GH 7737).Ранее расширение фрейма смешанных типов данных вело себя иначе
.appendчто сохранит типы данных (связано GH 2578, GH 8176):In [82]: df = pd.DataFrame([[True, 1], [False, 2]], ....: columns=["female", "fitness"]) ....: In [83]: df Out[83]: female fitness 0 True 1 1 False 2 [2 rows x 2 columns] In [84]: df.dtypes Out[84]: female bool fitness int64 Length: 2, dtype: object # dtypes are now preserved In [85]: df.loc[2] = df.loc[1] In [86]: df Out[86]: female fitness 0 True 1 1 False 2 2 False 2 [3 rows x 2 columns] In [87]: df.dtypes Out[87]: female bool fitness int64 Length: 2, dtype: object
Series.to_csv()теперь возвращает строку, когдаpath=None, соответствуя поведениюDataFrame.to_csv()(GH 8215).read_hdfтеперь вызываетIOErrorкогда передается файл, который не существует. Ранее создавался новый пустой файл, иKeyErrorвызвано (GH 7715).DataFrame.info()теперь завершает вывод символом новой строки (GH 8114)Конкатенация без объектов теперь вызовет
ValueErrorвместо простогоException.Ошибки слияния теперь будут подклассами
ValueErrorвместо сырыхException(GH 8501)DataFrame.plotиSeries.plotключевые слова теперь имеют согласованный порядок (GH 8037)
Внутренний рефакторинг#
В версии 0.15.0 Index был внутренне переработан, чтобы больше не наследовать от ndarray
но вместо этого подкласс PandasObject, аналогично остальным объектам pandas. Это изменение позволяет очень простое наследование и создание новых типов индексов. Это должно быть прозрачным изменением с очень ограниченными последствиями для API (GH 5080, GH 7439, GH 7796, GH 8024, GH 8367, GH 7997, GH 8522):
вам может потребоваться распаковать pickle-файлы pandas версии < 0.15.0 с помощью
pd.read_pickleвместоpickle.load. См. документация по pickleпри построении графика с
PeriodIndex, внутренние оси matplotlib теперь будут массивамиPeriodа неPeriodIndex(это похоже на то, какDatetimeIndexпередает массивыdatetimesтеперь)MultiIndex теперь будет вызывать исключения аналогично другим объектам pandas в отношении проверки истинности, см. здесь (GH 7897).
При построении графика DatetimeIndex напрямую с помощью
plotфункции, метки осей больше не будут форматироваться как даты, а как целые числа (внутреннее представлениеdatetime64). UPDATE Это исправлено в версии 0.15.1, см. здесь.
Устаревшие функции#
Атрибуты
Categoricallabelsиlevelsатрибуты устарели и переименованы вcodesиcategories.The
outtypeаргумент дляpd.DataFrame.to_dictбыл объявлен устаревшим в пользуorient. (GH 7840)The
convert_dummiesметод устарел в пользуget_dummies(GH 8140)The
infer_dstаргумент вtz_localizeбудет устаревшим в пользуambiguousдля большей гибкости при работе с переходами на летнее время. Заменитьinfer_dst=Trueсambiguous='infer'для того же поведения (GH 7943). См. документация для получения дополнительной информации.Верхнеуровневый
pd.value_rangeбыл устаревшим и может быть заменен на.describe()(GH 8481)
The
Indexоперации над множествами+и-были устаревшими, чтобы предоставить их для операций с числовыми типами на определенных типах индексов.+может быть заменен на.union()или|, и-by.difference(). Кроме того, имя методаIndex.diff()устарел и может быть заменён наIndex.difference()(GH 8226)# + pd.Index(['a', 'b', 'c']) + pd.Index(['b', 'c', 'd']) # should be replaced by pd.Index(['a', 'b', 'c']).union(pd.Index(['b', 'c', 'd']))
# - pd.Index(['a', 'b', 'c']) - pd.Index(['b', 'c', 'd']) # should be replaced by pd.Index(['a', 'b', 'c']).difference(pd.Index(['b', 'c', 'd']))
The
infer_typesаргумент дляread_html()теперь не имеет эффекта и объявлен устаревшим (GH 7762, GH 7032).
Удаление устаревших функций/изменений предыдущих версий#
Удалить
DataFrame.delevelметод в пользуDataFrame.reset_index
Улучшения#
Улучшения в импорте/экспорте файлов Stata:
Добавлена поддержка типов данных bool, uint8, uint16 и uint32 в
to_stata(GH 7097, GH 7365)Добавлена опция преобразования при импорте файлов Stata (GH 8527)
DataFrame.to_stataиStataWriterпроверять длину строки на совместимость с ограничениями, накладываемыми в файлах dta, где строки фиксированной длины должны содержать 244 или меньше символов. Попытка записи файлов Stata dta со строками длиннее 244 символов вызываетValueError. (GH 7858)read_stataиStataReaderможет импортировать информацию о пропущенных данных вDataFrameустановив аргументconvert_missingtoTrue. При использовании этой опции пропущенные значения возвращаются какStataMissingValueобъекты и столбцы, содержащие пропущенные значения, имеютobjectтип данных. (GH 8045)
Улучшения в функциях построения графиков:
Добавлен
layoutключевое слово дляDataFrame.plot. Вы можете передать кортеж из(rows, columns), один из которых может быть-1для автоматического вывода (GH 6667, GH 8071).Разрешить передачу нескольких осей в
DataFrame.plot,histиboxplot(GH 5353, GH 6970, GH 7069)Добавлена поддержка для
c,colormapиcolorbarаргументы дляDataFrame.plotсkind='scatter'(GH 7780)Гистограмма из
DataFrame.plotсkind='hist'(GH 7809), См. документация.Boxplot из
DataFrame.plotсkind='box'(GH 7998), См. документация.
Другие:
read_csvтеперь имеет параметр ключевого словаfloat_precisionкоторый указывает, какой преобразователь чисел с плавающей запятой должен использовать C-движок при разборе, см. здесь (GH 8002, GH 8044)Добавлен
searchsortedметод дляSeriesобъекты (GH 7447)describe()на DataFrame со смешанными типами более гибкий. Фильтрация столбцов по типу теперь возможна черезinclude/excludeаргументы. См. документация (GH 8164).In [88]: df = pd.DataFrame({'catA': ['foo', 'foo', 'bar'] * 8, ....: 'catB': ['a', 'b', 'c', 'd'] * 6, ....: 'numC': np.arange(24), ....: 'numD': np.arange(24.) + .5}) ....: In [89]: df.describe(include=["object"]) Out[89]: catA catB count 24 24 unique 2 4 top foo a freq 16 6 [4 rows x 2 columns] In [90]: df.describe(include=["number", "object"], exclude=["float"]) Out[90]: catA catB numC count 24 24 24.000000 unique 2 4 NaN top foo a NaN freq 16 6 NaN mean NaN NaN 11.500000 std NaN NaN 7.071068 min NaN NaN 0.000000 25% NaN NaN 5.750000 50% NaN NaN 11.500000 75% NaN NaN 17.250000 max NaN NaN 23.000000 [11 rows x 3 columns]
Запрос всех столбцов возможен с использованием сокращения 'all'
In [91]: df.describe(include='all') Out[91]: catA catB numC numD count 24 24 24.000000 24.000000 unique 2 4 NaN NaN top foo a NaN NaN freq 16 6 NaN NaN mean NaN NaN 11.500000 12.000000 std NaN NaN 7.071068 7.071068 min NaN NaN 0.000000 0.500000 25% NaN NaN 5.750000 6.250000 50% NaN NaN 11.500000 12.000000 75% NaN NaN 17.250000 17.750000 max NaN NaN 23.000000 23.500000 [11 rows x 4 columns]
Без этих аргументов,
describeбудет вести себя как раньше, включая только числовые столбцы или, если их нет, только категориальные столбцы. См. также документацияДобавлен
splitв качестве опции дляorientаргумент вpd.DataFrame.to_dict. (GH 7840)The
get_dummiesметод теперь можно использовать на DataFrames. По умолчанию только категориальные столбцы кодируются как 0 и 1, в то время как другие столбцы остаются без изменений.In [92]: df = pd.DataFrame({'A': ['a', 'b', 'a'], 'B': ['c', 'c', 'b'], ....: 'C': [1, 2, 3]}) ....: In [93]: pd.get_dummies(df) Out[93]: C A_a A_b B_b B_c 0 1 True False False True 1 2 False True False True 2 3 True False True False [3 rows x 5 columns]
PeriodIndexподдерживаетresolutionтакой же, какDatetimeIndex(GH 7708)pandas.tseries.holidayдобавлена поддержка дополнительных праздников и способов их соблюдения (GH 7070)pandas.tseries.holiday.Holidayтеперь поддерживает список смещений в Python3 (GH 7070)pandas.tseries.holiday.Holidayтеперь поддерживает параметр days_of_week (GH 7070)GroupBy.nth()теперь поддерживает выбор нескольких n-х значений (GH 7910)In [94]: business_dates = pd.date_range(start='4/1/2014', end='6/30/2014', freq='B') In [95]: df = pd.DataFrame(1, index=business_dates, columns=['a', 'b']) # get the first, 4th, and last date index for each month In [96]: df.groupby([df.index.year, df.index.month]).nth([0, 3, -1]) Out[96]: a b 2014-04-01 1 1 2014-04-04 1 1 2014-04-30 1 1 2014-05-01 1 1 2014-05-06 1 1 2014-05-30 1 1 2014-06-02 1 1 2014-06-05 1 1 2014-06-30 1 1 [9 rows x 2 columns]
PeriodиPeriodIndexподдерживает сложение/вычитание сtimedelta-подобные (GH 7966)Если
Periodчастота равнаD,H,T,S,L,U,N,Timedelta-подобное может быть добавлено, если результат может иметь ту же частоту. В противном случае только то же самоеoffsetsможет быть добавлен.In [104]: idx = pd.period_range('2014-07-01 09:00', periods=5, freq='H') In [105]: idx Out[105]: PeriodIndex(['2014-07-01 09:00', '2014-07-01 10:00', '2014-07-01 11:00', '2014-07-01 12:00', '2014-07-01 13:00'], dtype='period[H]') In [106]: idx + pd.offsets.Hour(2) Out[106]: PeriodIndex(['2014-07-01 11:00', '2014-07-01 12:00', '2014-07-01 13:00', '2014-07-01 14:00', '2014-07-01 15:00'], dtype='period[H]') In [107]: idx + pd.Timedelta('120m') Out[107]: PeriodIndex(['2014-07-01 11:00', '2014-07-01 12:00', '2014-07-01 13:00', '2014-07-01 14:00', '2014-07-01 15:00'], dtype='period[H]') In [108]: idx = pd.period_range('2014-07', periods=5, freq='M') In [109]: idx Out[109]: PeriodIndex(['2014-07', '2014-08', '2014-09', '2014-10', '2014-11'], dtype='period[M]') In [110]: idx + pd.offsets.MonthEnd(3) Out[110]: PeriodIndex(['2014-10', '2014-11', '2014-12', '2015-01', '2015-02'], dtype='period[M]')
Добавлена экспериментальная совместимость с
openpyxlдля версий >= 2.0. TheDataFrame.to_excelметодengineключевое слово теперь распознаетopenpyxl1иopenpyxl2которые будут явно требовать openpyxl v1 и v2 соответственно, завершаясь ошибкой, если запрашиваемая версия недоступна. Параметрopenpyxlengine теперь является мета-движком, который автоматически использует любую установленную версию openpyxl. (GH 7177)DataFrame.fillnaтеперь может приниматьDataFrameв качестве значения заполнения (GH 8377)Передача нескольких уровней в
stack()теперь будет работать при передаче нескольких номеров уровней (GH 7660). См. Изменение формы путем укладки и разложения.set_names(),set_labels(), иset_levels()методы теперь принимают необязательныйlevelаргумент ключевого слова для всех модификаций определенного уровня(ей) MultiIndex. Кроме того,set_names()теперь принимает скалярное строковое значение при работе сIndexили на определенном уровнеMultiIndex(GH 7792)In [97]: idx = pd.MultiIndex.from_product([['a'], range(3), list("pqr")], ....: names=['foo', 'bar', 'baz']) ....: In [98]: idx.set_names('qux', level=0) Out[98]: MultiIndex([('a', 0, 'p'), ('a', 0, 'q'), ('a', 0, 'r'), ('a', 1, 'p'), ('a', 1, 'q'), ('a', 1, 'r'), ('a', 2, 'p'), ('a', 2, 'q'), ('a', 2, 'r')], names=['qux', 'bar', 'baz']) In [99]: idx.set_names(['qux', 'corge'], level=[0, 1]) Out[99]: MultiIndex([('a', 0, 'p'), ('a', 0, 'q'), ('a', 0, 'r'), ('a', 1, 'p'), ('a', 1, 'q'), ('a', 1, 'r'), ('a', 2, 'p'), ('a', 2, 'q'), ('a', 2, 'r')], names=['qux', 'corge', 'baz']) In [100]: idx.set_levels(['a', 'b', 'c'], level='bar') Out[100]: MultiIndex([('a', 'a', 'p'), ('a', 'a', 'q'), ('a', 'a', 'r'), ('a', 'b', 'p'), ('a', 'b', 'q'), ('a', 'b', 'r'), ('a', 'c', 'p'), ('a', 'c', 'q'), ('a', 'c', 'r')], names=['foo', 'bar', 'baz']) In [101]: idx.set_levels([['a', 'b', 'c'], [1, 2, 3]], level=[1, 2]) Out[101]: MultiIndex([('a', 'a', 1), ('a', 'a', 2), ('a', 'a', 3), ('a', 'b', 1), ('a', 'b', 2), ('a', 'b', 3), ('a', 'c', 1), ('a', 'c', 2), ('a', 'c', 3)], names=['foo', 'bar', 'baz'])
Index.isinтеперь поддерживаетlevelаргумент для указания, какой уровень индекса использовать для проверки принадлежности (GH 7892, GH 7890)In [1]: idx = pd.MultiIndex.from_product([[0, 1], ['a', 'b', 'c']]) In [2]: idx.values Out[2]: array([(0, 'a'), (0, 'b'), (0, 'c'), (1, 'a'), (1, 'b'), (1, 'c')], dtype=object) In [3]: idx.isin(['a', 'c', 'e'], level=1) Out[3]: array([ True, False, True, True, False, True], dtype=bool)
Indexтеперь поддерживаетduplicatedиdrop_duplicates. (GH 4060)In [102]: idx = pd.Index([1, 2, 3, 4, 1, 2]) In [103]: idx Out[103]: Index([1, 2, 3, 4, 1, 2], dtype='int64') In [104]: idx.duplicated() Out[104]: array([False, False, False, False, True, True]) In [105]: idx.drop_duplicates() Out[105]: Index([1, 2, 3, 4], dtype='int64')
добавить
copy=Trueаргумент дляpd.concatчтобы включить сквозную передачу полных блоков (GH 8252)Добавлена поддержка типов данных numpy 1.8+ (
bool_,int_,float_,string_) для преобразования в фрейм данных R (GH 8400)
Производительность#
Улучшения производительности в
DatetimeIndex.__iter__для более быстрой итерации (GH 7683)Улучшения производительности в
Periodсоздание (иPeriodIndexsetitem) (GH 5155)Улучшения в Series.transform для значительного повышения производительности (исправлено) (GH 6496)
Улучшения производительности в
StataReaderпри чтении больших файлов (GH 8040, GH 8073)Улучшения производительности в
StataWriterпри записи больших файлов (GH 8079)Улучшения производительности и использования памяти при работе с несколькими ключами
groupby(GH 8128)Улучшения производительности в groupby
.aggи.applyгде встроенные max/min не были сопоставлены с версиями numpy/cython (GH 7722)Улучшение производительности при записи в sql (
to_sql) до 50% (GH 8208).Тестирование производительности groupby для большого значения ngroups (GH 6787)
Улучшение производительности в
CustomBusinessDay,CustomBusinessMonth(GH 8236)Улучшение производительности для
MultiIndex.valuesдля многоуровневых индексов, содержащих даты и время (GH 8543)
Исправления ошибок#
Ошибка в pivot_table при использовании полей итогов и словаря aggfunc (GH 8349)
Ошибка в
read_csvгдеsqueeze=Trueвозвращал бы представление (GH 8217)Ошибка при проверке имени таблицы в
read_sqlв некоторых случаях (GH 7826).Ошибка в
DataFrame.groupbyгдеGrouperне распознает уровень, когда указана частота (GH 7885)Ошибка в типах данных мультииндексов, которые перемешиваются при сохранении DataFrame в таблицу SQL (GH 8021)
Ошибка в
Seriesделение на 0 с операндами типов float и integer (GH 7785)Ошибка в
Series.astype("unicode")не вызываетunicodeна значениях правильно (GH 7758)Ошибка в
DataFrame.as_matrix()со смешаннымиdatetime64[ns]иtimedelta64[ns]типы данных (GH 7778)Ошибка в
HDFStore.select_column()не сохраняет информацию о часовом поясе UTC при выбореDatetimeIndex(GH 7777)Ошибка в
to_datetimeкогдаformat='%Y%m%d'иcoerce=Trueуказаны, тогда как ранее возвращался массив объектов (а не приведенный временной ряд сNaT), (GH 7930)Ошибка в
DatetimeIndexиPeriodIndexдобавление и вычитание на месте дают другой результат, чем обычные (GH 6527)Ошибка при сложении и вычитании
PeriodIndexсPeriodIndexraiseTypeError(GH 7741)Ошибка в
combine_firstсPeriodIndexданные вызываютTypeError(GH 3367)Ошибка в срезе MultiIndex с отсутствующими индексаторами (GH 7866)
с функциями, которые не являютсяGH 8132)
Регрессия в индексации MultiIndex с нескалярным объектом типа (GH 7914)
Ошибка в
Timestampсравнения с==иint64тип данных (GH 8058)Ошибка в pickle содержит
DateOffsetможет вызыватьAttributeErrorкогдаnormalizeатрибут упоминается внутренне (GH 7748)Ошибка в
Panelпри использованииmajor_xsиcopy=Falseпередается (предупреждение об устаревании не срабатывает из-за отсутствияwarnings) (GH 8152).Ошибка в десериализации pickle, которая не срабатывала для контейнеров версии до 0.14.1 с дублирующимися элементами при попытке избежать неоднозначности при сопоставлении элементов блока и менеджера, когда есть только один блок, неоднозначности нет (GH 7794)
Ошибка при размещении
PeriodIndexвSeriesпреобразуется вint64тип данных, а неobjectofPeriods(GH 7932)Ошибка в
HDFStoreитерация при передаче условия where (GH 8014)Ошибка в
DataFrameGroupby.transformпри преобразовании с переданным несортированным ключом (GH 8046, GH 8430)Ошибка в повторяющихся временных рядах при построении линий и областей может привести к
ValueErrorили неправильный тип (GH 7733)Ошибка в выводе в
MultiIndexсdatetime.dateвходные данные (GH 7888)Ошибка в
getгдеIndexErrorне приведет к возврату значения по умолчанию (GH 7725)Ошибка в
offsets.apply,rollforwardиrollbackможет сбросить наносекунды (GH 7697)Ошибка в
offsets.apply,rollforwardиrollbackможет вызыватьAttributeErrorifTimestampимеетdateutiltzinfo (GH 7697)Ошибка при сортировке фрейма с MultiIndex и
Float64Index(GH 8017)Ошибка в несогласованном panel setitem с правой частью
DataFrameдля выравнивания (GH 7763)Ошибка в
is_superperiodиis_subperiodне может обрабатывать частоты выше, чемS(GH 7760, GH 7772, GH 7803)Ошибка на 32-битных платформах с
Series.shift(GH 8129)Ошибка в
PeriodIndex.uniqueвозвращает int64np.ndarray(GH 7540)Ошибка в
groupby.applyс не влияющей на результат мутацией в функции (GH 8467)Ошибка в
DataFrame.reset_indexкоторый имеетMultiIndexсодержитPeriodIndexилиDatetimeIndexс tz вызываетValueError(GH 7746, GH 7793)Ошибка в
DataFrame.plotсsubplots=Trueможет рисовать ненужные второстепенные деления по осям X и Y (GH 7801)Ошибка в
StataReaderкоторый не читал метки переменных в 117 файлах из-за различий между документацией Stata и реализацией (GH 7816)Ошибка в
StataReaderгде строки всегда преобразовывались в фиксированную ширину 244 символов независимо от фактического размера строки (GH 7858)Ошибка в
DataFrame.plotиSeries.plotможет игнорироватьrotиfontsizeключевые слова (GH 7844)Ошибка в
DatetimeIndex.value_countsне сохраняет часовой пояс (GH 7735)Ошибка в
PeriodIndex.value_countsприводит кInt64Index(GH 7735)Ошибка в
DataFrame.joinпри выполнении левого соединения по индексу и наличии нескольких совпадений (GH 5391)Ошибка в
GroupBy.transform()где целочисленные группы с преобразованием, которое не сохраняло индекс, были некорректно обрезаны (GH 7972).Ошибка в
groupbyгде вызываемые объекты без атрибутов имени выбирали неправильный путь, и создавалиDataFrameвместоSeries(GH 7929)Ошибка в
groupbyсообщение об ошибке, когда столбец группировки DataFrame дублируется (GH 7511)Ошибка в
read_htmlгдеinfer_typesаргумент принудительно приводил даты некорректно (GH 7762, GH 7032).Ошибка в
Series.str.catс индексом, который был отфильтрован так, чтобы не включать первый элемент (GH 7857)Ошибка в
Timestampне может разобратьnanosecondиз строки (GH 7878)Ошибка в
Timestampсо строковым смещением иtzрезультаты некорректны (GH 7833)Ошибка в
tslib.tz_convertиtslib.tz_convert_singleможет возвращать разные результаты (GH 7798)Ошибка в
DatetimeIndex.intersectionнепересекающихся временных меток с tz вызываетIndexError(GH 7880)Ошибка в выравнивании с TimeOps и неуникальными индексами (GH 8363)
Ошибка в
GroupBy.filter()где быстрый путь против медленного пути заставлял фильтр возвращать нескалярное значение, которое выглядело допустимым, но не было таковым (GH 7870).Ошибка в
date_range()/DatetimeIndex()когда часовой пояс определялся из входных дат, но возвращались некорректные времена при переходе границ летнего времени (GH 7835, GH 7901).Ошибка в
to_excel()где отрицательный знак добавлялся к положительной бесконечности и отсутствовал для отрицательной бесконечности (GH 7949)Ошибка в построении графика area рисует легенду с некорректным
alphaкогдаstacked=True(GH 8027)PeriodиPeriodIndexсложение/вычитание сnp.timedelta64приводит к некорректным внутренним представлениям (GH 7740)Ошибка в
Holidayбез смещения или соблюдения (GH 7987)Ошибка в
DataFrame.to_latexформатирование, когда столбцы или индекс являютсяMultiIndex(GH 7982).Ошибка в
DateOffsetвокруг перехода на летнее время приводит к неожиданным результатам (GH 5175).Ошибка в
DataFrame.shiftгде пустые столбцы вызывали бы исключениеZeroDivisionErrorна numpy 1.7 (GH 8019)Ошибка при установке, когда
html_encoding/*.htmlне был установлен и поэтому некоторые тесты выполнялись некорректно (GH 7927).Ошибка в
read_htmlгдеbytesобъекты не проверялись на наличие в_read(GH 7927).Ошибка в
DataFrame.stack()когда один из уровней столбцов был похож на дату (GH 8039)Ошибка в трансляции скаляров numpy с
DataFrame(GH 8116)Ошибка в
pivot_tableвыполнено с безымяннымindexиcolumnsвызываетKeyError(GH 8103)Ошибка в
DataFrame.plot(kind='scatter')рисует точки и полосы ошибок разными цветами, когда цвет заданcключевое слово (GH 8081)Ошибка в
Float64Indexгдеiatиatне тестировались и не проходили (GH 8092).Ошибка в
DataFrame.boxplot()где пределы y не были установлены корректно при создании нескольких осей (GH 7528, GH 5517).Ошибка в
read_csvгде строковые комментарии обрабатывались некорректно при заданном пользовательском разделителе строк илиdelim_whitespace=True(GH 8122).Ошибка в
read_htmlгде пустые таблицы вызывалиStopIteration(GH 7575)Ошибка в приведении типов при установке столбца в блоке того же типа данных (GH 7704)
Ошибка при доступе к группам из
GroupByкогда исходный группировщик был кортежем (GH 8121).Ошибка в
.atкоторый принимал бы целочисленные индексаторы на нецелочисленном индексе и выполнял откат (GH 7814)Ошибка с графиком kde и NaN (GH 8182)
Ошибка в
GroupBy.countс типом данных float32, где значения nan не исключались (GH 8169).Ошибка с накопленными столбчатыми диаграммами и NaN (GH 8175).
Ошибка в resample с неравномерно делимыми смещениями (например, '7s') (GH 8371)
Ошибка в методах интерполяции с
limitключевое слово, когда значения не требуют интерполяции (GH 7173).Ошибка, где
col_spaceбыл проигнорирован вDataFrame.to_string()когдаheader=False(GH 8230).Ошибка с
DatetimeIndex.asofнеправильное сопоставление частичных строк и возврат неверной даты (GH 8245).Ошибка в методах построения графиков, изменяющих глобальные rcParams matplotlib (GH 8242).
Ошибка в
DataFrame.__setitem__которая вызывала ошибки при установке столбца датафрейма в разреженный массив (GH 8131)Ошибка, где
Dataframe.boxplot()не удалось, когда весь столбец был пустым (GH 8181).Ошибка с перемешанными переменными в
radvizвизуализация (GH 8199).Ошибка в методах интерполяции с
limitключевое слово, когда значения не требуют интерполяции (GH 7173).Ошибка, где
col_spaceбыл проигнорирован вDataFrame.to_string()когдаheader=False(GH 8230).Ошибка в
to_clipboardчто обрежет длинные данные столбцов (GH 8305)Ошибка в
DataFrameтерминальный вывод: Установка max_column/max_rows в ноль не вызывала автоматического изменения размера dfs для соответствия ширине/высоте терминала (GH 7180).Ошибка в OLS, где запуск с параметрами “cluster” и “nw_lags” работал некорректно, но также не вызывал ошибку (GH 5884).
Ошибка в
DataFrame.dropnaкоторый интерпретировал несуществующие столбцы в аргументе subset как 'последний столбец' (GH 8303)Ошибка в
Index.intersectionна немонотонных неуникальных индексах (GH 8362).Ошибка в присваивании маскированной серии, где несоответствие типов нарушало выравнивание (GH 8387)
Ошибка в
NDFrame.equalsдает ложные отрицания с dtype=object (GH 8437)Исправлена ошибка при присваивании с индексатором, где разнообразие типов нарушало выравнивание (GH 8258)
Ошибка в
NDFrame.locиндексирование, когда имена строк/столбцов терялись, когда целью был список/ndarray (GH 6552)Регрессия в
NDFrame.locиндексирование, когда строки/столбцы были преобразованы в Float64Index, если целью был пустой список/ndarray (GH 7774)Ошибка в
Seriesчто позволяет индексировать его с помощьюDataFrameчто приводит к неожиданным результатам. Такое индексирование больше не разрешено (GH 8444)Ошибка в присваивании элемента
DataFrameс MultiIndex столбцами, где правые столбцы не были выровнены (GH 7655)Подавление FutureWarning, генерируемого NumPy при сравнении объектных массивов, содержащих NaN, на равенство (GH 7065)
Ошибка в
DataFrame.eval()где dtypenotоператор (~) не был корректно определён какbool.
Участники#
Всего 80 человек внесли патчи в этот релиз. Люди со знаком «+» рядом с именами внесли патч впервые.
Aaron Schumacher +
Adam Greenhall
Andy Hayden
Anthony O’Brien +
Artemy Kolchinsky +
Бен Шиллер +
Benedikt Sauer
Benjamin Thyreau +
BorisVerk +
Chris Reynolds +
Chris Stoafer +
DSM
Dav Clark +
FragLegs +
German Gomez-Herrero +
Hsiaoming Yang +
Huan Li +
Hyungtae Kim +
Isaac Slavitt +
Джейкоб Шаер
Jacob Wasserman +
Ян Шульц
Jeff Reback
Jeff Tratner
Jesse Farnham +
Joe Bradish +
Joerg Rittinger +
John W. O’Brien
Joris Van den Bossche
Кевин Шеппард
Кайл Мейер
Max Chang +
Michael Mueller
Michael W Schatzow +
Mike Kelly
Mortada Mehyar
Nathan Sanders +
Nathan Typanski +
Пол Масюрель +
Филлип Клауд
Пьетро Баттистон
RenzoBertocchi +
Росс Петчлер +
Shahul Hameed +
Шашанк Агарвал +
Stephan Hoyer
Tom Augspurger
TomAugspurger
Tony Lorenzo +
Wes Turner
Wilfred Hughes +
Yevgeniy Grechka +
Yoshiki Vázquez Baeza +
Бехазад Нури +
benjamin
bjonen +
dlovell +
dsm054
hunterowens +
immerrr
ischwabacher
jmorris0x0 +
jnmclarty +
jreback
klonuo +
лексический
mcjcode +
mtrbean +
onesandzeroes
rockg
seth-p
sinhrks
someben +
stahlous +
stas-sl +
thatneat +
tom-alcorn +
неизвестный
unutbu
zachcp +