Версия 0.18.0 (13 марта 2016)#
Это основной выпуск с версии 0.17.1 и включает небольшое количество изменений API, несколько новых функций, улучшений и оптимизаций производительности, а также большое количество исправлений ошибок. Мы рекомендуем всем пользователям обновиться до этой версии.
Предупреждение
pandas >= 0.18.0 больше не поддерживает совместимость с версиями Python 2.6 и 3.3 (GH 7718, GH 11273)
Предупреждение
numexpr версия 2.4.4 теперь будет показывать предупреждение и не будет использоваться в качестве вычислительного бэкенда для pandas из-за некоторого ошибочного поведения. Это не затрагивает другие версии (>= 2.1 и >= 2.4.6). (GH 12489)
Основные моменты включают:
Функции скользящего и расширяющегося окон теперь являются методами Series и DataFrame, аналогично
.groupby, см. здесь.Добавлена поддержка
RangeIndexкак специализированная формаInt64Indexдля экономии памяти, см. здесь.Изменение API, нарушающее обратную совместимость, для
.resampleметод, чтобы сделать его более.groupbyнапример, см. здесь.Удаление поддержки позиционного индексирования с плавающими числами, которое было устаревшим с версии 0.14.0. Теперь это будет вызывать
TypeError, см. здесь.The
.to_xarray()функция была добавлена для совместимости с пакет xarray, см. здесь.The
read_sasфункция была улучшена для чтенияsas7bdatфайлы, см. здесь.Добавление метод .str.extractall(), и изменения API в метод .str.extract() и метод .str.cat().
pd.test()доступен тестовый раннер верхнего уровня nose (GH 4327).
Проверьте Изменения API и устаревшие возможности перед обновлением.
Что нового в v0.18.0
Новые возможности#
Оконные функции теперь являются методами#
Оконные функции были переработаны в методы на Series/DataFrame объектов, а не функций верхнего уровня, которые теперь устарели. Это позволяет этим функциям оконного типа иметь API, аналогичный API .groupby. См. полную документацию здесь (GH 11603, GH 12373)
In [1]: np.random.seed(1234)
In [2]: df = pd.DataFrame({'A': range(10), 'B': np.random.randn(10)})
In [3]: df
Out[3]:
A B
0 0 0.471435
1 1 -1.190976
2 2 1.432707
3 3 -0.312652
4 4 -0.720589
5 5 0.887163
6 6 0.859588
7 7 -0.636524
8 8 0.015696
9 9 -2.242685
[10 rows x 2 columns]
Предыдущее поведение:
In [8]: pd.rolling_mean(df, window=3)
FutureWarning: pd.rolling_mean is deprecated for DataFrame and will be removed in a future version, replace with
DataFrame.rolling(window=3,center=False).mean()
Out[8]:
A B
0 NaN NaN
1 NaN NaN
2 1 0.237722
3 2 -0.023640
4 3 0.133155
5 4 -0.048693
6 5 0.342054
7 6 0.370076
8 7 0.079587
9 8 -0.954504
Новое поведение:
In [4]: r = df.rolling(window=3)
Они показывают описательное представление
In [5]: r
Out[5]: Rolling [window=3,center=False,axis=0,method=single]
с автодополнением доступных методов и свойств.
In [9]: r.<TAB> # noqa E225, E999
r.A r.agg r.apply r.count r.exclusions r.max r.median r.name r.skew r.sum
r.B r.aggregate r.corr r.cov r.kurt r.mean r.min r.quantile r.std r.var
Методы работают с Rolling сам объект
In [6]: r.mean()
Out[6]:
A B
0 NaN NaN
1 NaN NaN
2 1.0 0.237722
3 2.0 -0.023640
4 3.0 0.133155
5 4.0 -0.048693
6 5.0 0.342054
7 6.0 0.370076
8 7.0 0.079587
9 8.0 -0.954504
[10 rows x 2 columns]
Они предоставляют доступ через getitem
In [7]: r['A'].mean()
Out[7]:
0 NaN
1 NaN
2 1.0
3 2.0
4 3.0
5 4.0
6 5.0
7 6.0
8 7.0
9 8.0
Name: A, Length: 10, dtype: float64
И множественные агрегации
In [8]: r.agg({'A': ['mean', 'std'],
...: 'B': ['mean', 'std']})
...:
Out[8]:
A B
mean std mean std
0 NaN NaN NaN NaN
1 NaN NaN NaN NaN
2 1.0 1.0 0.237722 1.327364
3 2.0 1.0 -0.023640 1.335505
4 3.0 1.0 0.133155 1.143778
5 4.0 1.0 -0.048693 0.835747
6 5.0 1.0 0.342054 0.920379
7 6.0 1.0 0.370076 0.871850
8 7.0 1.0 0.079587 0.750099
9 8.0 1.0 -0.954504 1.162285
[10 rows x 4 columns]
Изменения для переименования#
Series.rename и NDFrame.rename_axis теперь может принимать скалярное или list-like
значение для изменения Series или оси имя, в дополнение к их старому поведению изменения меток. (GH 9494, GH 11965)
In [9]: s = pd.Series(np.random.randn(5))
In [10]: s.rename('newname')
Out[10]:
0 1.150036
1 0.991946
2 0.953324
3 -2.021255
4 -0.334077
Name: newname, Length: 5, dtype: float64
In [11]: df = pd.DataFrame(np.random.randn(5, 2))
In [12]: (df.rename_axis("indexname")
....: .rename_axis("columns_name", axis="columns"))
....:
Out[12]:
columns_name 0 1
indexname
0 0.002118 0.405453
1 0.289092 1.321158
2 -1.546906 -0.202646
3 -0.655969 0.193421
4 0.553439 1.318152
[5 rows x 2 columns]
Новая функциональность хорошо работает в цепочках методов. Ранее эти методы принимали только функции или словари, отображающие метка на новую метку. Это продолжает работать как раньше для значений функции или словаря.
Range Index#
A RangeIndex был добавлен в Int64Index подклассы для поддержки альтернативы, экономящей память, для распространенных случаев использования. Это имеет аналогичную реализацию с python range объект (xrange в python 2), в том смысле, что он хранит только начальное, конечное и шаговое значения для индекса. Он будет прозрачно взаимодействовать с пользовательским API, преобразуясь в Int64Index при необходимости.
Теперь это будет индекс по умолчанию для NDFrame объекты, а не предыдущий Int64Index. (GH 939, GH 12070, GH 12071, GH 12109, GH 12888)
Предыдущее поведение:
In [3]: s = pd.Series(range(1000))
In [4]: s.index
Out[4]:
Int64Index([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
...
990, 991, 992, 993, 994, 995, 996, 997, 998, 999], dtype='int64', length=1000)
In [6]: s.index.nbytes
Out[6]: 8000
Новое поведение:
In [13]: s = pd.Series(range(1000))
In [14]: s.index
Out[14]: RangeIndex(start=0, stop=1000, step=1)
In [15]: s.index.nbytes
Out[15]: 128
Изменения в str.extract#
The .str.extract метод принимает регулярное выражение с группами захвата, находит первое совпадение в каждой строке-субъекте и возвращает содержимое групп захватаGH 11386).
В версии 0.18.0, expand аргумент был добавлен в
extract.
expand=False: возвращаетSeries,Index, илиDataFrame, в зависимости от объекта и шаблона регулярного выражения (то же поведение, что и до версии 0.18.0).expand=True: всегда возвращаетDataFrame, что более последовательно и менее запутанно с точки зрения пользователя.
В настоящее время по умолчанию используется expand=None который дает FutureWarning и использует expand=FalseЧтобы избежать этого предупреждения, явно укажите expand.
In [1]: pd.Series(['a1', 'b2', 'c3']).str.extract(r'[ab](\d)', expand=None)
FutureWarning: currently extract(expand=None) means expand=False (return Index/Series/DataFrame)
but in a future version of pandas this will be changed to expand=True (return DataFrame)
Out[1]:
0 1
1 2
2 NaN
dtype: object
Извлечение регулярного выражения с одной группой возвращает Series, если
expand=False.
In [16]: pd.Series(['a1', 'b2', 'c3']).str.extract(r'[ab](\d)', expand=False)
Out[16]:
0 1
1 2
2 NaN
Length: 3, dtype: object
Возвращает DataFrame с одним столбцом, если expand=True.
In [17]: pd.Series(['a1', 'b2', 'c3']).str.extract(r'[ab](\d)', expand=True)
Out[17]:
0
0 1
1 2
2 NaN
[3 rows x 1 columns]
Вызов на Index с регулярным выражением, содержащим ровно одну захватывающую группу,
возвращает Index if expand=False.
In [18]: s = pd.Series(["a1", "b2", "c3"], ["A11", "B22", "C33"])
In [19]: s.index
Out[19]: Index(['A11', 'B22', 'C33'], dtype='object')
In [20]: s.index.str.extract("(?P[a-zA-Z])" , expand=False)
Out[20]: Index(['A', 'B', 'C'], dtype='object', name='letter')
Возвращает DataFrame с одним столбцом, если expand=True.
In [21]: s.index.str.extract("(?P[a-zA-Z])" , expand=True)
Out[21]:
letter
0 A
1 B
2 C
[3 rows x 1 columns]
Вызов на Index с регулярным выражением, содержащим более одной группы захвата, вызывает ValueError if expand=False.
>>> s.index.str.extract("(?P[a-zA-Z])([0-9]+)" , expand=False)
ValueError: only one regex group is supported with Index
Возвращает DataFrame if expand=True.
In [22]: s.index.str.extract("(?P[a-zA-Z])([0-9]+)" , expand=True)
Out[22]:
letter 1
0 A 11
1 B 22
2 C 33
[3 rows x 2 columns]
В итоге, extract(expand=True) всегда возвращает DataFrame
со строкой для каждой строки субъекта и столбцом для каждой группы захвата.
Добавление str.extractall#
The .str.extractall метод был добавлен
(GH 11386). В отличие от extract, который возвращает только первое совпадение.
In [23]: s = pd.Series(["a1a2", "b1", "c1"], ["A", "B", "C"])
In [24]: s
Out[24]:
A a1a2
B b1
C c1
Length: 3, dtype: object
In [25]: s.str.extract(r"(?P[ab])(?P\d)" , expand=False)
Out[25]:
letter digit
A a 1
B b 1
C NaN NaN
[3 rows x 2 columns]
The extractall метод возвращает все совпадения.
In [26]: s.str.extractall(r"(?P[ab])(?P\d)" )
Out[26]:
letter digit
match
A 0 a 1
1 a 2
B 0 b 1
[3 rows x 2 columns]
Изменения в str.cat#
Метод .str.cat() объединяет элементы Series. Ранее, если NaN значения присутствовали в Series, вызов .str.cat() на нем вернет NaN, в отличие от остальной части Series.str.* API. Это поведение было изменено, чтобы игнорировать NaN значения по умолчанию. (GH 11435).
Новый, более дружелюбный ValueError добавлена для защиты от ошибки предоставления sep в качестве аргумента, а не в качестве ключевого аргумента. (GH 11334).
In [27]: pd.Series(['a', 'b', np.nan, 'c']).str.cat(sep=' ')
Out[27]: 'a b c'
In [28]: pd.Series(['a', 'b', np.nan, 'c']).str.cat(sep=' ', na_rep='?')
Out[28]: 'a b ? c'
In [2]: pd.Series(['a', 'b', np.nan, 'c']).str.cat(' ')
ValueError: Did you mean to supply a ``sep`` keyword?
Округление даты/времени#
DatetimeIndex, Timestamp, TimedeltaIndex, Timedelta получили .round(), .floor() и .ceil() метод для округления, округления вниз и вверх для дат и времени. (GH 4314, GH 11963)
Наивные даты и время
In [29]: dr = pd.date_range('20130101 09:12:56.1234', periods=3)
In [30]: dr
Out[30]:
DatetimeIndex(['2013-01-01 09:12:56.123400', '2013-01-02 09:12:56.123400',
'2013-01-03 09:12:56.123400'],
dtype='datetime64[ns]', freq='D')
In [31]: dr.round('s')
Out[31]:
DatetimeIndex(['2013-01-01 09:12:56', '2013-01-02 09:12:56',
'2013-01-03 09:12:56'],
dtype='datetime64[ns]', freq=None)
# Timestamp scalar
In [32]: dr[0]
Out[32]: Timestamp('2013-01-01 09:12:56.123400')
In [33]: dr[0].round('10s')
Out[33]: Timestamp('2013-01-01 09:13:00')
Временные метки с часовым поясом округляются, округляются вниз и вверх в местном времени
In [34]: dr = dr.tz_localize('US/Eastern')
In [35]: dr
Out[35]:
DatetimeIndex(['2013-01-01 09:12:56.123400-05:00',
'2013-01-02 09:12:56.123400-05:00',
'2013-01-03 09:12:56.123400-05:00'],
dtype='datetime64[ns, US/Eastern]', freq=None)
In [36]: dr.round('s')
Out[36]:
DatetimeIndex(['2013-01-01 09:12:56-05:00', '2013-01-02 09:12:56-05:00',
'2013-01-03 09:12:56-05:00'],
dtype='datetime64[ns, US/Eastern]', freq=None)
Timedeltas
In [37]: t = pd.timedelta_range('1 days 2 hr 13 min 45 us', periods=3, freq='d')
In [38]: t
Out[38]:
TimedeltaIndex(['1 days 02:13:00.000045', '2 days 02:13:00.000045',
'3 days 02:13:00.000045'],
dtype='timedelta64[ns]', freq='D')
In [39]: t.round('10min')
Out[39]: TimedeltaIndex(['1 days 02:10:00', '2 days 02:10:00', '3 days 02:10:00'], dtype='timedelta64[ns]', freq=None)
# Timedelta scalar
In [40]: t[0]
Out[40]: Timedelta('1 days 02:13:00.000045')
In [41]: t[0].round('2h')
Out[41]: Timedelta('1 days 02:00:00')
Кроме того, .round(), .floor() и .ceil() будет доступно через .dt аксессор Series.
In [42]: s = pd.Series(dr)
In [43]: s
Out[43]:
0 2013-01-01 09:12:56.123400-05:00
1 2013-01-02 09:12:56.123400-05:00
2 2013-01-03 09:12:56.123400-05:00
Length: 3, dtype: datetime64[ns, US/Eastern]
In [44]: s.dt.round('D')
Out[44]:
0 2013-01-01 00:00:00-05:00
1 2013-01-02 00:00:00-05:00
2 2013-01-03 00:00:00-05:00
Length: 3, dtype: datetime64[ns, US/Eastern]
Форматирование целых чисел в FloatIndex#
Целые числа в FloatIndex, например 1., теперь форматируются с десятичной точкой и 0 цифра, например. 1.0 (GH 11713)
Это изменение влияет не только на отображение в консоли, но и на вывод методов ввода-вывода, таких как .to_csv или .to_html.
Предыдущее поведение:
In [2]: s = pd.Series([1, 2, 3], index=np.arange(3.))
In [3]: s
Out[3]:
0 1
1 2
2 3
dtype: int64
In [4]: s.index
Out[4]: Float64Index([0.0, 1.0, 2.0], dtype='float64')
In [5]: print(s.to_csv(path=None))
0,1
1,2
2,3
Новое поведение:
In [45]: s = pd.Series([1, 2, 3], index=np.arange(3.))
In [46]: s
Out[46]:
0.0 1
1.0 2
2.0 3
Length: 3, dtype: int64
In [47]: s.index
Out[47]: Index([0.0, 1.0, 2.0], dtype='float64')
In [48]: print(s.to_csv(path_or_buf=None, header=False))
0.0,1
1.0,2
2.0,3
Изменения в поведении назначения типов данных#
Когда срез DataFrame обновляется новым срезом того же типа данных, тип данных DataFrame теперь останется прежним. (GH 10503)
Предыдущее поведение:
In [5]: df = pd.DataFrame({'a': [0, 1, 1],
'b': pd.Series([100, 200, 300], dtype='uint32')})
In [7]: df.dtypes
Out[7]:
a int64
b uint32
dtype: object
In [8]: ix = df['a'] == 1
In [9]: df.loc[ix, 'b'] = df.loc[ix, 'b']
In [11]: df.dtypes
Out[11]:
a int64
b int64
dtype: object
Новое поведение:
In [49]: df = pd.DataFrame({'a': [0, 1, 1],
....: 'b': pd.Series([100, 200, 300], dtype='uint32')})
....:
In [50]: df.dtypes
Out[50]:
a int64
b uint32
Length: 2, dtype: object
In [51]: ix = df['a'] == 1
In [52]: df.loc[ix, 'b'] = df.loc[ix, 'b']
In [53]: df.dtypes
Out[53]:
a int64
b uint32
Length: 2, dtype: object
Когда целочисленный срез DataFrame частично обновляется новым срезом чисел с плавающей точкой, которые потенциально могут быть приведены к целому числу без потери точности, тип данных среза будет установлен как float вместо integer.
Предыдущее поведение:
In [4]: df = pd.DataFrame(np.array(range(1,10)).reshape(3,3),
columns=list('abc'),
index=[[4,4,8], [8,10,12]])
In [5]: df
Out[5]:
a b c
4 8 1 2 3
10 4 5 6
8 12 7 8 9
In [7]: df.ix[4, 'c'] = np.array([0., 1.])
In [8]: df
Out[8]:
a b c
4 8 1 2 0
10 4 5 1
8 12 7 8 9
Новое поведение:
In [54]: df = pd.DataFrame(np.array(range(1,10)).reshape(3,3),
....: columns=list('abc'),
....: index=[[4,4,8], [8,10,12]])
....:
In [55]: df
Out[55]:
a b c
4 8 1 2 3
10 4 5 6
8 12 7 8 9
[3 rows x 3 columns]
In [56]: df.loc[4, 'c'] = np.array([0., 1.])
In [57]: df
Out[57]:
a b c
4 8 1 2 0
10 4 5 1
8 12 7 8 9
[3 rows x 3 columns]
Метод to_xarray#
В будущей версии pandas мы устареем Panel и другие объекты > 2 измерений. Для обеспечения непрерывности,
все NDFrame объекты получили .to_xarray() метод для преобразования в xarray объекты, которые имеют
интерфейс, подобный pandas, для > 2 измерений. (GH 11972)
См. полная документация xarray здесь.
In [1]: p = Panel(np.arange(2*3*4).reshape(2,3,4))
In [2]: p.to_xarray()
Out[2]:
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
Coordinates:
* items (items) int64 0 1
* major_axis (major_axis) int64 0 1 2
* minor_axis (minor_axis) int64 0 1 2 3
Представление в Latex#
DataFrame получил ._repr_latex_() метод для обеспечения возможности преобразования в latex в блокноте ipython/jupyter с использованием nbconvert. (GH 11778)
Обратите внимание, что это необходимо активировать, установив опцию pd.display.latex.repr=True (GH 12182)
Например, если у вас есть блокнот jupyter, который вы планируете преобразовать в latex с помощью nbconvert, поместите оператор pd.display.latex.repr=True в первой ячейке, чтобы содержащийся DataFrame также выводился как latex.
Опции display.latex.escape и display.latex.longtable также добавлены в конфигурацию и автоматически используются to_latex
метод. См. документация по доступным опциям для получения дополнительной информации.
pd.read_sas() изменения#
read_sas получил возможность читать файлы SAS7BDAT, включая сжатые файлы. Файлы можно читать полностью или по частям. Подробности см. в здесь. (GH 4052)
Другие улучшения#
Обработка усеченных чисел с плавающей точкой в файлах SAS xport (GH 11713)
Добавлена опция скрытия индекса в
Series.to_string(GH 11729)read_excelтеперь поддерживает s3-ссылки форматаs3://bucketname/filename(GH 11447)добавить поддержку для
AWS_S3_HOSTпеременная окружения при чтении из s3 (GH 12198)Простая версия
Panel.round()теперь реализовано (GH 11763)Для Python 3.x,
round(DataFrame),round(Series),round(Panel)будет работать (GH 11763)sys.getsizeof(obj)возвращает использование памяти объектом pandas, включая содержащиеся в нем значения (GH 11597)Seriesполучилis_uniqueатрибут (GH 11946)DataFrame.quantileиSeries.quantileтеперь принимаютinterpolationключевое слово (GH 10174).Добавлен
DataFrame.style.formatдля более гибкого форматирования значений ячеек (GH 11692)DataFrame.select_dtypesтеперь позволяетnp.float16код типа (GH 11990)pivot_table()теперь принимает большинство итерируемых объектов дляvaluesпараметр (GH 12017)Добавлен Google
BigQueryподдержка аутентификации через сервисный аккаунт, что позволяет аутентификацию на удалённых серверах. (GH 11881, GH 12572). Для получения дополнительных сведений см. здесьHDFStoreтеперь является итерируемым:for k in storeэквивалентноfor k in store.keys()(GH 12221).Добавить отсутствующие методы/поля в
.dtдляPeriod(GH 8848)Вся кодовая база была
PEP-ифицированный (GH 12096)
Обратно несовместимые изменения API#
ведущие пробелы были удалены из вывода
.to_string(index=False)метод (GH 11833)the
outпараметр был удален изSeries.round()метод. (GH 11763)DataFrame.round()оставляет нечисловые столбцы неизменными в своем возвращаемом значении, а не вызывает ошибку. (GH 11885)DataFrame.head(0)иDataFrame.tail(0)возвращать пустые фреймы, а неself. (GH 11937)Series.head(0)иSeries.tail(0)возвращать пустую серию, а неself. (GH 11937)to_msgpackиread_msgpackкодировка теперь по умолчанию'utf-8'. (GH 12170)порядок аргументов ключевых слов для функций парсинга текстовых файлов (
.read_csv(),.read_table(),.read_fwf()) изменено для группировки связанных аргументов. (GH 11555)NaTType.isoformatтеперь возвращает строку'NaTчтобы позволить передать результат в конструкторTimestamp. (GH 12300)
Операции с NaT и Timedelta#
NaT и Timedelta расширили арифметические операции, которые расширены до Series
арифметические операции, где применимо. Операции, определённые для datetime64[ns] или timedelta64[ns]
теперь также определены для NaT (GH 11564).
NaT теперь поддерживает арифметические операции с целыми числами и числами с плавающей точкой.
In [58]: pd.NaT * 1
Out[58]: NaT
In [59]: pd.NaT * 1.5
Out[59]: NaT
In [60]: pd.NaT / 2
Out[60]: NaT
In [61]: pd.NaT * np.nan
Out[61]: NaT
NaT определяет дополнительные арифметические операции с datetime64[ns] и timedelta64[ns].
In [62]: pd.NaT / pd.NaT
Out[62]: nan
In [63]: pd.Timedelta('1s') / pd.NaT
Out[63]: nan
NaT может представлять либо datetime64[ns] null или a timedelta64[ns] null.
Учитывая неоднозначность, это рассматривается как timedelta64[ns], что позволяет выполнять больше операций
успешно.
In [64]: pd.NaT + pd.NaT
Out[64]: NaT
# same as
In [65]: pd.Timedelta('1s') + pd.Timedelta('1s')
Out[65]: Timedelta('0 days 00:00:02')
в отличие от
In [3]: pd.Timestamp('19900315') + pd.Timestamp('19900315')
TypeError: unsupported operand type(s) for +: 'Timestamp' and 'Timestamp'
Однако, когда обернуто в Series чей dtype является datetime64[ns] или timedelta64[ns], dtype информация учитывается.
In [1]: pd.Series([pd.NaT], dtype=') + pd.Series([pd.NaT], dtype=')
TypeError: can only operate on a datetimes for subtraction,
but the operator [__add__] was passed
In [66]: pd.Series([pd.NaT], dtype=') + pd.Series([pd.NaT], dtype=')
Out[66]:
0 NaT
Length: 1, dtype: timedelta64[ns]
Timedelta деление на floats теперь работает.
In [67]: pd.Timedelta('1s') / 2.0
Out[67]: Timedelta('0 days 00:00:00.500000')
Вычитание на Timedelta в Series с помощью Timestamp работает (GH 11925)
In [68]: ser = pd.Series(pd.timedelta_range('1 day', periods=3))
In [69]: ser
Out[69]:
0 1 days
1 2 days
2 3 days
Length: 3, dtype: timedelta64[ns]
In [70]: pd.Timestamp('2012-01-01') - ser
Out[70]:
0 2011-12-31
1 2011-12-30
2 2011-12-29
Length: 3, dtype: datetime64[ns]
NaT.isoformat() теперь возвращает 'NaT'. Это изменение позволяет
pd.Timestamp для восстановления любого объекта временной метки из его isoформата
(GH 12300).
Изменения в msgpack#
Несовместимые изменения в будущих версиях в msgpack формат записи был изменен в версиях 0.17.0 и 0.18.0; старые версии pandas не могут читать файлы, созданные новыми версиями (GH 12129, GH 10527)
Ошибки в to_msgpack и read_msgpack введено в 0.17.0 и исправлено в 0.18.0, из-за чего файлы, упакованные в Python 2, не читались в Python 3 (GH 12142). Следующая таблица описывает обратную и прямую совместимость msgpacks.
Предупреждение
Упаковано с |
Может быть распаковано с помощью |
|---|---|
до версии 0.17 / Python 2 |
любой |
pre-0.17 / Python 3 |
любой |
0.17 / Python 2 |
|
0.17 / Python 3 |
>=0.18 / любой Python |
0.18 |
>= 0.18 |
0.18.0 обратно совместима для чтения файлов, упакованных старыми версиями, за исключением файлов, упакованных с 0.17 в Python 2, в этом случае их можно распаковать только в Python 2.
Изменение сигнатуры для .rank#
Series.rank и DataFrame.rank теперь имеют одинаковую сигнатуру (GH 11759)
Предыдущая сигнатура
In [3]: pd.Series([0,1]).rank(method='average', na_option='keep',
ascending=True, pct=False)
Out[3]:
0 1
1 2
dtype: float64
In [4]: pd.DataFrame([0,1]).rank(axis=0, numeric_only=None,
method='average', na_option='keep',
ascending=True, pct=False)
Out[4]:
0
0 1
1 2
Новая сигнатура
In [71]: pd.Series([0,1]).rank(axis=0, method='average', numeric_only=False,
....: na_option='keep', ascending=True, pct=False)
....:
Out[71]:
0 1.0
1 2.0
Length: 2, dtype: float64
In [72]: pd.DataFrame([0,1]).rank(axis=0, method='average', numeric_only=False,
....: na_option='keep', ascending=True, pct=False)
....:
Out[72]:
0
0 1.0
1 2.0
[2 rows x 1 columns]
Ошибка в QuarterBegin с n=0#
В предыдущих версиях поведение смещения QuarterBegin было непоследовательным в зависимости от даты, когда n параметр был 0. (GH 11406)
Общая семантика закрепленных смещений для n=0 состоит в том, чтобы не перемещать дату
когда это точка привязки (например, начало квартала), а в противном случае сдвигать
вперед к следующей точке привязки.
In [73]: d = pd.Timestamp('2014-02-01')
In [74]: d
Out[74]: Timestamp('2014-02-01 00:00:00')
In [75]: d + pd.offsets.QuarterBegin(n=0, startingMonth=2)
Out[75]: Timestamp('2014-02-01 00:00:00')
In [76]: d + pd.offsets.QuarterBegin(n=0, startingMonth=1)
Out[76]: Timestamp('2014-04-01 00:00:00')
Для QuarterBegin смещение в предыдущих версиях, дата была бы перенесена
обратной совместимостью если дата была в том же месяце, что и дата начала квартала.
In [3]: d = pd.Timestamp('2014-02-15')
In [4]: d + pd.offsets.QuarterBegin(n=0, startingMonth=2)
Out[4]: Timestamp('2014-02-01 00:00:00')
Это поведение было исправлено в версии 0.18.0, что согласуется с другими закреплёнными смещениями, такими как MonthBegin и YearBegin.
In [77]: d = pd.Timestamp('2014-02-15')
In [78]: d + pd.offsets.QuarterBegin(n=0, startingMonth=2)
Out[78]: Timestamp('2014-05-01 00:00:00')
API Resample#
Как изменение в API оконных функций выше, .resample(...) изменяется для более похожего на groupby API. (GH 11732, GH 12702, GH 12202, GH 12332, GH 12334, GH 12348, GH 12448).
In [79]: np.random.seed(1234)
In [80]: df = pd.DataFrame(np.random.rand(10,4),
....: columns=list('ABCD'),
....: index=pd.date_range('2010-01-01 09:00:00',
....: periods=10, freq='s'))
....:
In [81]: df
Out[81]:
A B C D
2010-01-01 09:00:00 0.191519 0.622109 0.437728 0.785359
2010-01-01 09:00:01 0.779976 0.272593 0.276464 0.801872
2010-01-01 09:00:02 0.958139 0.875933 0.357817 0.500995
2010-01-01 09:00:03 0.683463 0.712702 0.370251 0.561196
2010-01-01 09:00:04 0.503083 0.013768 0.772827 0.882641
2010-01-01 09:00:05 0.364886 0.615396 0.075381 0.368824
2010-01-01 09:00:06 0.933140 0.651378 0.397203 0.788730
2010-01-01 09:00:07 0.316836 0.568099 0.869127 0.436173
2010-01-01 09:00:08 0.802148 0.143767 0.704261 0.704581
2010-01-01 09:00:09 0.218792 0.924868 0.442141 0.909316
[10 rows x 4 columns]
Предыдущий API:
Вы бы написали операцию передискретизации, которая немедленно вычисляется. Если how параметр не был предоставлен, он
по умолчанию будет равен how='mean'.
In [6]: df.resample('2s')
Out[6]:
A B C D
2010-01-01 09:00:00 0.485748 0.447351 0.357096 0.793615
2010-01-01 09:00:02 0.820801 0.794317 0.364034 0.531096
2010-01-01 09:00:04 0.433985 0.314582 0.424104 0.625733
2010-01-01 09:00:06 0.624988 0.609738 0.633165 0.612452
2010-01-01 09:00:08 0.510470 0.534317 0.573201 0.806949
Вы также можете указать how напрямую
In [7]: df.resample('2s', how='sum')
Out[7]:
A B C D
2010-01-01 09:00:00 0.971495 0.894701 0.714192 1.587231
2010-01-01 09:00:02 1.641602 1.588635 0.728068 1.062191
2010-01-01 09:00:04 0.867969 0.629165 0.848208 1.251465
2010-01-01 09:00:06 1.249976 1.219477 1.266330 1.224904
2010-01-01 09:00:08 1.020940 1.068634 1.146402 1.613897
Новый API:
Теперь вы можете писать .resample(..) как двухэтапная операция, например .groupby(...), что
дает Resampler.
In [82]: r = df.resample('2s')
In [83]: r
Out[83]:
Понижающая дискретизация#
Затем вы можете использовать этот объект для выполнения операций. Это операции понижающей дискретизации (переход от более высокой частоты к более низкой).
In [84]: r.mean()
Out[84]:
A B C D
2010-01-01 09:00:00 0.485748 0.447351 0.357096 0.793615
2010-01-01 09:00:02 0.820801 0.794317 0.364034 0.531096
2010-01-01 09:00:04 0.433985 0.314582 0.424104 0.625733
2010-01-01 09:00:06 0.624988 0.609738 0.633165 0.612452
2010-01-01 09:00:08 0.510470 0.534317 0.573201 0.806949
[5 rows x 4 columns]
In [85]: r.sum()
Out[85]:
A B C D
2010-01-01 09:00:00 0.971495 0.894701 0.714192 1.587231
2010-01-01 09:00:02 1.641602 1.588635 0.728068 1.062191
2010-01-01 09:00:04 0.867969 0.629165 0.848208 1.251465
2010-01-01 09:00:06 1.249976 1.219477 1.266330 1.224904
2010-01-01 09:00:08 1.020940 1.068634 1.146402 1.613897
[5 rows x 4 columns]
Кроме того, resample теперь поддерживает getitem операции для выполнения передискретизации по определенным столбцам.
In [86]: r[['A','C']].mean()
Out[86]:
A C
2010-01-01 09:00:00 0.485748 0.357096
2010-01-01 09:00:02 0.820801 0.364034
2010-01-01 09:00:04 0.433985 0.424104
2010-01-01 09:00:06 0.624988 0.633165
2010-01-01 09:00:08 0.510470 0.573201
[5 rows x 2 columns]
и .aggregate операции с типами.
In [87]: r.agg({'A' : 'mean', 'B' : 'sum'})
Out[87]:
A B
2010-01-01 09:00:00 0.485748 0.894701
2010-01-01 09:00:02 0.820801 1.588635
2010-01-01 09:00:04 0.433985 0.629165
2010-01-01 09:00:06 0.624988 1.219477
2010-01-01 09:00:08 0.510470 1.068634
[5 rows x 2 columns]
Эти аксессоры, конечно, могут быть объединены
In [88]: r[['A','B']].agg(['mean','sum'])
Out[88]:
A B
mean sum mean sum
2010-01-01 09:00:00 0.485748 0.971495 0.447351 0.894701
2010-01-01 09:00:02 0.820801 1.641602 0.794317 1.588635
2010-01-01 09:00:04 0.433985 0.867969 0.314582 0.629165
2010-01-01 09:00:06 0.624988 1.249976 0.609738 1.219477
2010-01-01 09:00:08 0.510470 1.020940 0.534317 1.068634
[5 rows x 4 columns]
Повышение частоты дискретизации#
Операции повышающей дискретизации переводят вас с более низкой частоты на более высокую. Теперь они
выполняются с помощью Resampler объекты с backfill(),
ffill(), fillna() и asfreq() методы.
In [89]: s = pd.Series(np.arange(5, dtype='int64'),
index=pd.date_range('2010-01-01', periods=5, freq='Q'))
In [90]: s
Out[90]:
2010-03-31 0
2010-06-30 1
2010-09-30 2
2010-12-31 3
2011-03-31 4
Freq: Q-DEC, Length: 5, dtype: int64
Ранее
In [6]: s.resample('M', fill_method='ffill')
Out[6]:
2010-03-31 0
2010-04-30 0
2010-05-31 0
2010-06-30 1
2010-07-31 1
2010-08-31 1
2010-09-30 2
2010-10-31 2
2010-11-30 2
2010-12-31 3
2011-01-31 3
2011-02-28 3
2011-03-31 4
Freq: M, dtype: int64
Новый API
In [91]: s.resample('M').ffill()
Out[91]:
2010-03-31 0
2010-04-30 0
2010-05-31 0
2010-06-30 1
2010-07-31 1
2010-08-31 1
2010-09-30 2
2010-10-31 2
2010-11-30 2
2010-12-31 3
2011-01-31 3
2011-02-28 3
2011-03-31 4
Freq: M, Length: 13, dtype: int64
Примечание
В новом API вы можете либо понизить, либо повысить частоту дискретизации. Предыдущая реализация позволяла передавать агрегирующую функцию (например, mean) даже при апсемплинге, что вызывало некоторую путаницу.
Предыдущий API будет работать, но с устареваниями#
Предупреждение
funnycrab +
In [4]: r = df.resample('2s')
In [6]: r*10
pandas/tseries/resample.py:80: FutureWarning: .resample() is now a deferred operation
use .resample(...).mean() instead of .resample(...)
Out[6]:
A B C D
2010-01-01 09:00:00 4.857476 4.473507 3.570960 7.936154
2010-01-01 09:00:02 8.208011 7.943173 3.640340 5.310957
2010-01-01 09:00:04 4.339846 3.145823 4.241039 6.257326
2010-01-01 09:00:06 6.249881 6.097384 6.331650 6.124518
2010-01-01 09:00:08 5.104699 5.343172 5.732009 8.069486
Однако операции получения и присваивания непосредственно на Resampler вызовет ValueError:
In [7]: r.iloc[0] = 5
ValueError: .resample() is now a deferred operation
use .resample(...).mean() instead of .resample(...)
Существует ситуация, когда новый API не может выполнить все операции при использовании исходного кода.
Этот код предназначен для ресемплинга каждые 2 секунды, взятия mean И затем взять min из этих результатов.
In [4]: df.resample('2s').min()
Out[4]:
A 0.433985
B 0.314582
C 0.357096
D 0.531096
dtype: float64
Новый API будет:
In [89]: df.resample('2s').min()
Out[89]:
A B C D
2010-01-01 09:00:00 0.191519 0.272593 0.276464 0.785359
2010-01-01 09:00:02 0.683463 0.712702 0.357817 0.500995
2010-01-01 09:00:04 0.364886 0.013768 0.075381 0.368824
2010-01-01 09:00:06 0.316836 0.568099 0.397203 0.436173
2010-01-01 09:00:08 0.218792 0.143767 0.442141 0.704581
[5 rows x 4 columns]
Хорошая новость в том, что размеры возвращаемых данных будут различаться между новым API и старым API, поэтому это должно вызвать исключение.
Для воспроизведения исходной операции
In [90]: df.resample('2s').mean().min()
Out[90]:
A 0.433985
B 0.314582
C 0.357096
D 0.531096
Length: 4, dtype: float64
Изменения в eval#
В предыдущих версиях присвоение новых столбцов в eval выражение привело к изменению на месте в DataFrame. (GH 9297, GH 8664, GH 10486)
In [91]: df = pd.DataFrame({'a': np.linspace(0, 10, 5), 'b': range(5)})
In [92]: df
Out[92]:
a b
0 0.0 0
1 2.5 1
2 5.0 2
3 7.5 3
4 10.0 4
[5 rows x 2 columns]
In [12]: df.eval('c = a + b')
FutureWarning: eval expressions containing an assignment currentlydefault to operating inplace.
This will change in a future version of pandas, use inplace=True to avoid this warning.
In [13]: df
Out[13]:
a b c
0 0.0 0 0.0
1 2.5 1 3.5
2 5.0 2 7.0
3 7.5 3 10.5
4 10.0 4 14.0
В версии 0.18.0 новый inplace Ключевое слово было добавлено для выбора, должно ли назначение выполняться на месте или возвращать копию.
In [93]: df
Out[93]:
a b c
0 0.0 0 0.0
1 2.5 1 3.5
2 5.0 2 7.0
3 7.5 3 10.5
4 10.0 4 14.0
[5 rows x 3 columns]
In [94]: df.eval('d = c - b', inplace=False)
Out[94]:
a b c d
0 0.0 0 0.0 0.0
1 2.5 1 3.5 2.5
2 5.0 2 7.0 5.0
3 7.5 3 10.5 7.5
4 10.0 4 14.0 10.0
[5 rows x 4 columns]
In [95]: df
Out[95]:
a b c
0 0.0 0 0.0
1 2.5 1 3.5
2 5.0 2 7.0
3 7.5 3 10.5
4 10.0 4 14.0
[5 rows x 3 columns]
In [96]: df.eval('d = c - b', inplace=True)
In [97]: df
Out[97]:
a b c d
0 0.0 0 0.0 0.0
1 2.5 1 3.5 2.5
2 5.0 2 7.0 5.0
3 7.5 3 10.5 7.5
4 10.0 4 14.0 10.0
[5 rows x 4 columns]
Предупреждение
Для обратной совместимости, inplace по умолчанию True если не указано.
Это изменится в будущей версии pandas. Если ваш код зависит от
присваивания на месте, вам следует обновить его, чтобы явно установить inplace=True
The inplace параметр ключевого слова также был добавлен query метод.
In [98]: df.query('a > 5')
Out[98]:
a b c d
3 7.5 3 10.5 7.5
4 10.0 4 14.0 10.0
[2 rows x 4 columns]
In [99]: df.query('a > 5', inplace=True)
In [100]: df
Out[100]:
a b c d
3 7.5 3 10.5 7.5
4 10.0 4 14.0 10.0
[2 rows x 4 columns]
Предупреждение
Обратите внимание, что значение по умолчанию для inplace в query
является False, что соответствует предыдущим версиям.
eval также было обновлено для поддержки многострочных выражений при множественных присваиваниях. Эти выражения будут вычисляться по одному в порядке следования. Только присваивания допустимы для многострочных выражений.
In [101]: df
Out[101]:
a b c d
3 7.5 3 10.5 7.5
4 10.0 4 14.0 10.0
[2 rows x 4 columns]
In [102]: df.eval("""
.....: e = d + a
.....: f = e - 22
.....: g = f / 2.0""", inplace=True)
.....:
In [103]: df
Out[103]:
a b c d e f g
3 7.5 3 10.5 7.5 15.0 -7.0 -3.5
4 10.0 4 14.0 10.0 20.0 -2.0 -1.0
[2 rows x 7 columns]
Другие изменения API#
DataFrame.between_timeиSeries.between_timeтеперь разбирает только фиксированный набор строк времени. Разбор строк даты больше не поддерживается и вызываетValueError. (GH 11818)In [107]: s = pd.Series(range(10), pd.date_range('2015-01-01', freq='H', periods=10)) In [108]: s.between_time("7:00am", "9:00am") Out[108]: 2015-01-01 07:00:00 7 2015-01-01 08:00:00 8 2015-01-01 09:00:00 9 Freq: H, Length: 3, dtype: int64
Теперь это будет вызывать ошибку.
In [2]: s.between_time('20150101 07:00:00','20150101 09:00:00') ValueError: Cannot convert arg ['20150101 07:00:00'] to a time.
.memory_usage()теперь включает значения в индексе, как и memory_usage в.info()(GH 11597)DataFrame.to_latex()теперь поддерживает не-ASCII кодировки (например,utf-8) в Python 2 с параметромencoding(GH 7061)pandas.merge()иDataFrame.merge()будет показывать конкретное сообщение об ошибке при попытке слияния с объектом, не являющимся типомDataFrameили подкласс (GH 12081)DataFrame.unstackиSeries.unstackтеперь принимаютfill_valueключевое слово для прямой замены пропущенных значений, когда unstack приводит к пропущенным значениям в результатеDataFrame. В качестве дополнительного преимущества, указаниеfill_valueсохранит тип данных исходных уложенных данных. (GH 9746)В рамках нового API для оконные функции и ресемплинг, функции агрегации были уточнены, выводя более информативные сообщения об ошибках при недопустимых агрегациях. (GH 9052). Полный набор примеров представлен в groupby.
Статистические функции для
NDFrameобъектов (таких какsum(), mean(), min()) теперь будет вызывать ошибку, если переданы аргументы, несовместимые с numpy, для**kwargs(GH 12301).to_latexи.to_htmlполучитьdecimalпараметра, такого как.to_csv; по умолчанию'.'(GH 12031)Более полезное сообщение об ошибке при создании
DataFrameс пустыми данными, но с индексами (GH 8020).describe()теперь будет правильно обрабатывать bool dtype как категориальный (GH 6625)Более информативное сообщение об ошибке при недопустимом
.transformс пользовательским вводом (GH 10165)Экспоненциально взвешенные функции теперь позволяют напрямую указывать альфа (GH 10789) и вызывает
ValueErrorесли параметры нарушают0 < alpha <= 1(GH 12492)
Устаревшие функции#
Функции
pd.rolling_*,pd.expanding_*, иpd.ewm*устарели и заменены соответствующими вызовами методов. Обратите внимание, что новый предлагаемый синтаксис включает все аргументы (даже по умолчанию) (GH 11603)In [1]: s = pd.Series(range(3)) In [2]: pd.rolling_mean(s,window=2,min_periods=1) FutureWarning: pd.rolling_mean is deprecated for Series and will be removed in a future version, replace with Series.rolling(min_periods=1,window=2,center=False).mean() Out[2]: 0 0.0 1 0.5 2 1.5 dtype: float64 In [3]: pd.rolling_cov(s, s, window=2) FutureWarning: pd.rolling_cov is deprecated for Series and will be removed in a future version, replace with Series.rolling(window=2).cov(other=
) Out[3]: 0 NaN 1 0.5 2 0.5 dtype: float64The
freqиhowаргументы для.rolling,.expanding, и.ewm(новые) функции устарели и будут удалены в будущей версии. Вы можете просто передискретизировать входные данные перед созданием оконной функции. (GH 11603).Например, вместо
s.rolling(window=5,freq='D').max()чтобы получить максимальное значение в скользящем окне 5 дней, можно использоватьs.resample('D').mean().rolling(window=5).max(), который сначала передискретизирует данные до ежедневных, затем предоставляет скользящее окно в 5 дней.pd.tseries.frequencies.get_offset_nameфункция устарела. Используйте offset’s.freqstrсвойство как альтернатива (GH 11192)pandas.stats.fama_macbethподпрограммы устарели и будут удалены в будущей версии (GH 6077)pandas.stats.ols,pandas.stats.plmиpandas.stats.varподпрограммы устарели и будут удалены в будущей версии (GH 6077)показать
FutureWarningа неDeprecationWarningпри использовании давно устаревшего синтаксиса вHDFStore.select, гдеwhereусловие не является строкоподобным (GH 12027)The
pandas.options.display.mpl_styleконфигурация устарела и будет удалена в будущей версии pandas. Эта функциональность лучше обрабатывается таблицы стилей (GH 11783).
Удаление устаревших индексаторов с плавающей точкой#
В GH 4892 индексирование с числами с плавающей точкой на не-Float64Index было устаревшим (в версии 0.14.0).
В 0.18.0 это предупреждение об устаревании удалено, и теперь они будут вызывать TypeError. (GH 12165, GH 12333)
In [104]: s = pd.Series([1, 2, 3], index=[4, 5, 6])
In [105]: s
Out[105]:
4 1
5 2
6 3
Length: 3, dtype: int64
In [106]: s2 = pd.Series([1, 2, 3], index=list('abc'))
In [107]: s2
Out[107]:
a 1
b 2
c 3
Length: 3, dtype: int64
Предыдущее поведение:
# this is label indexing
In [2]: s[5.0]
FutureWarning: scalar indexers for index type Int64Index should be integers and not floating point
Out[2]: 2
# this is positional indexing
In [3]: s.iloc[1.0]
FutureWarning: scalar indexers for index type Int64Index should be integers and not floating point
Out[3]: 2
# this is label indexing
In [4]: s.loc[5.0]
FutureWarning: scalar indexers for index type Int64Index should be integers and not floating point
Out[4]: 2
# .ix would coerce 1.0 to the positional 1, and index
In [5]: s2.ix[1.0] = 10
FutureWarning: scalar indexers for index type Index should be integers and not floating point
In [6]: s2
Out[6]:
a 1
b 10
c 3
dtype: int64
Новое поведение:
Для iloc, получение и установка через скаляр с плавающей точкой всегда будет вызывать ошибку.
In [3]: s.iloc[2.0]
TypeError: cannot do label indexing on with these indexers [2.0] of
Другие индексаторы будут преобразованы в аналогичный целочисленный тип как для получения, так и для установки значений. FutureWarning был удален для .loc, .ix и [].
In [108]: s[5.0]
Out[108]: 2
In [109]: s.loc[5.0]
Out[109]: 2
и установка
In [110]: s_copy = s.copy()
In [111]: s_copy[5.0] = 10
In [112]: s_copy
Out[112]:
4 1
5 10
6 3
Length: 3, dtype: int64
In [113]: s_copy = s.copy()
In [114]: s_copy.loc[5.0] = 10
In [115]: s_copy
Out[115]:
4 1
5 10
6 3
Length: 3, dtype: int64
Позиционная установка с .ix и индексатор с плавающей точкой ДОБАВИТ это значение к индексу, а не установит значение по позиции, как ранее.
In [3]: s2.ix[1.0] = 10
In [4]: s2
Out[4]:
a 1
b 2
c 3
1.0 10
dtype: int64
Срезы также будут преобразовывать целочисленные подобные числа с плавающей точкой в целые числа для не-Float64Index.
In [116]: s.loc[5.0:6]
Out[116]:
5 2
6 3
Length: 2, dtype: int64
Обратите внимание, что для чисел с плавающей точкой, которые НЕ преобразуются в целые числа, границы на основе меток будут исключены
In [117]: s.loc[5.1:6]
Out[117]:
6 3
Length: 1, dtype: int64
Индексирование с плавающей точкой на Float64Index не изменяется.
In [118]: s = pd.Series([1, 2, 3], index=np.arange(3.))
In [119]: s[1.0]
Out[119]: 2
In [120]: s[1.0:2.5]
Out[120]:
1.0 2
2.0 3
Length: 2, dtype: int64
Удаление устаревших функций/изменений предыдущих версий#
Удаление
rolling_corr_pairwiseв пользу.rolling().corr(pairwise=True)(GH 4950)Удаление
expanding_corr_pairwiseв пользу.expanding().corr(pairwise=True)(GH 4950)Удаление
DataMatrixмодуля. Это не было импортировано в пространство имен pandas в любом случае (GH 12111)Удаление
colsключевое слово в пользуsubsetвDataFrame.duplicated()иDataFrame.drop_duplicates()(GH 6680)Удаление
read_frameиframe_query(оба псевдонима дляpd.read_sql) иwrite_frame(псевдонимto_sql) функции вpd.io.sqlпространство имен, устарело с версии 0.14.0 (GH 6292).Удаление
orderключевое слово из.factorize()(GH 6930)
Улучшения производительности#
Улучшена производительность
andrews_curves(GH 11534)Улучшена обработка огромных
DatetimeIndex,PeriodIndexиTimedeltaIndexпроизводительность операций, включаяNaT(GH 10277)Улучшена производительность
pandas.concat(GH 11958)Улучшена производительность
StataReader(GH 11591)Улучшена производительность при построении
CategoricalsсSeriesдат, содержащихNaT(GH 12077)Улучшена производительность парсинга дат ISO 8601 для дат без разделителей (GH 11899), ведущие нули (GH 11871) и с пробелом перед часовым поясом (GH 9714)
Исправления ошибок#
Ошибка в
GroupBy.sizeкогда фрейм данных пуст. (GH 11699)Ошибка в
Period.end_timeкогда запрашивается кратное временному периоду (GH 11738)Регрессия в
.clipс датами с учетом часового пояса (GH 11838)Ошибка в
date_rangeкогда границы попадали на частоту (GH 11804, GH 12409)Ошибка в согласованности передачи вложенных словарей в
.groupby(...).agg(...)(GH 9052)Принимать unicode в
Timedeltaконструктор (GH 11995)Ошибка при чтении метки значения для
StataReaderпри инкрементальном чтении (GH 12014)Ошибка в векторизованном
DateOffsetкогдаnпараметр0(GH 11370)Совместимость с numpy 1.11 относительно
NaTизменения сравнения (GH 12049)Ошибка в
read_csvпри чтении изStringIOв потоках (GH 11790)Ошибка в неправильной обработке
NaTкак пропущенное значение в datetime при факторизации и сCategoricals(GH 12077)Ошибка в getitem, когда значения
Seriesбыли с учетом часового пояса (GH 12089)Ошибка в
Series.str.get_dummiesкогда одной из переменных было 'name' (GH 12180)Ошибка в
pd.concatпри объединении серий NaT с учетом часового пояса. (GH 11693, GH 11755, GH 12217)Ошибка в
pd.read_stataс файлами версии <= 108 (GH 12232)Ошибка в
Series.resampleиспользуя частотуNanoкогда индекс являетсяDatetimeIndexи содержит ненулевые наносекундные части (GH 12037)Ошибка при передискретизации с
.nuniqueи разреженный индекс (GH 12352)Убраны некоторые предупреждения компилятора (GH 12471)
Обход проблем совместимости с
botoв python 3.5 (GH 11915)Ошибка в
NaTвычитание изTimestampилиDatetimeIndexс часовыми поясами (GH 11718)Ошибка при вычитании
Seriesодного tz-awareTimestamp(GH 12290)Использовать совместимые итераторы в PY2 для поддержки
.next()(GH 12299)Ошибка в
Timedelta.roundс отрицательными значениями (GH 11690)Ошибка в
.locпротивCategoricalIndexможет привести к нормальномуIndex(GH 11586)Ошибка в
DataFrame.infoкогда существуют повторяющиеся имена столбцов (GH 11761)Ошибка в
.copydatetime объектов с информацией о часовом поясе (GH 11794)Ошибка в
Series.applyиSeries.mapгдеtimedelta64не был упакован (GH 11349)Ошибка в
DataFrame.set_index()с учетом часового поясаSeries(GH 12358)Ошибка в подклассах
DataFrameгдеAttributeErrorне распространялось (GH 11808)Ошибка groupby на данных с часовым поясом, где выборка не возвращает
Timestamp(GH 11616)Ошибка в
pd.read_clipboardиpd.to_clipboardфункции, не поддерживающие Unicode; обновление включеноpyperclipдо v1.5.15 (GH 9263)Ошибка в
DataFrame.queryсодержащий присваивание (GH 8664)Ошибка в
from_msgpackгде__contains__()не работает для столбцов распакованногоDataFrame, еслиDataFrameимеет столбцы типа object. (GH 11880)Ошибка в
.resampleна категориальных данных сTimedeltaIndex(GH 12169)Ошибка: информация о часовом поясе теряется при трансляции скалярного datetime в
DataFrame(GH 11682)Ошибка в
Indexсоздание изTimestampсо смешанными часовыми поясами преобразуется в UTC (GH 11488)Ошибка в
to_numericгде не вызывает ошибку, если входные данные имеют более одного измерения (GH 11776)Ошибка в разборе строк смещения часового пояса с ненулевыми минутами (GH 11708)
Ошибка в
df.plotиспользование некорректных цветов для столбчатых диаграмм в matplotlib 1.5+ (GH 11614)Ошибка в
groupbyplotметод при использовании ключевых аргументов (GH 11805).Ошибка в
DataFrame.duplicatedиdrop_duplicatesвызывая ложные совпадения при установкеkeep=False(GH 11864)Ошибка в
.locрезультат с дублированным ключом может иметьIndexс некорректным dtype (GH 11497)Ошибка в
pd.rolling_medianгде выделение памяти завершилось неудачей даже при достаточном объеме памяти (GH 11696)Ошибка в
DataFrame.styleсо случайными нулями (GH 12134)Ошибка в
DataFrame.styleс целочисленными столбцами, не начинающимися с 0 (GH 12125)Ошибка в
.style.barможет отображаться некорректно в определённых браузерах (GH 11678)Ошибка в богатом сравнении
Timedeltaсnumpy.arrayofTimedeltaчто вызвало бесконечную рекурсию (GH 11835)Ошибка в
DataFrame.roundудаление имени индекса столбца (GH 11986)Ошибка в
df.replaceпри замене значения в смешанном типе данныхDataframe(GH 11698)Ошибка в
Indexпредотвращает копирование имени переданногоIndex, когда новое имя не предоставлено (GH 11193)Ошибка в
read_excelне удается прочитать непустые листы при наличии пустых листов иsheetname=None(GH 11711)Ошибка в
read_excelне удалось вызватьNotImplementedошибка при использовании ключевых словparse_datesиdate_parserпредоставлены (GH 11544)Ошибка в
read_sqlсpymysqlсоединения, не возвращающие фрагментированные данные (GH 11522)Ошибка в
.to_csvигнорируя параметры форматированияdecimal,na_rep,float_formatдля индексов с плавающей запятой (GH 11553)Ошибка в
Int64IndexиFloat64Indexпредотвращая использование оператора модуля (GH 9244)Ошибка в
MultiIndex.dropдля не лексически отсортированных MultiIndexes (GH 12078)Ошибка в
DataFrameпри маскировании пустогоDataFrame(GH 11859)Ошибка в
.plotпотенциально изменяяcolorsвходные данные, когда количество столбцов не соответствовало количеству предоставленных серий (GH 12039).Ошибка в
Series.plotошибка при наличии индекса сCustomBusinessDayчастота (GH 7222).Ошибка в
.to_sqlдляdatetime.timeзначения с резервным вариантом sqlite (GH 8341)Ошибка в
read_excelне удается прочитать данные с одним столбцом, когдаsqueeze=True(GH 12157)Ошибка в
read_excelне удалось прочитать один пустой столбец (GH 12292, GH 9002)Ошибка в
.groupbyгдеKeyErrorне вызывалось для неправильного столбца, если в dataframe была только одна строка (GH 11741)Ошибка в
.read_csvс указанием dtype на пустых данных, вызывающих ошибку (GH 12048)Ошибка в
.read_csvгде строки, такие как'2E'рассматриваются как допустимые числа с плавающей точкой (GH 12237)Ошибка в сборке pandas с символами отладки (GH 12123)
Удалено
millisecondсвойствоDatetimeIndex. Это всегда вызывало быValueError(GH 12019).Ошибка в
Seriesконструктор с данными только для чтения (GH 11502)Удалено
pandas._testing.choice(). Следует использоватьnp.random.choice(), вместо этого. (GH 12386)Ошибка в
.locиндексатор setitem, предотвращающий использование DatetimeIndex с учетом часового пояса (GH 12050)Ошибка в
.styleиндексы и MultiIndexes не отображаются (GH 11655)Ошибка в
to_msgpackиfrom_msgpackкоторый некорректно сериализовал или десериализовалNaT(GH 12307).Ошибка в
.skewи.kurtиз-за ошибки округления для очень похожих значений (GH 11974)Ошибка в
Timestampконструктор, где разрешение микросекунд терялось, если HHMMSS не были разделены ':' (GH 10041)Ошибка в
buffer_rd_bytessrc->buffer мог быть освобожден более одного раза при неудачном чтении, вызывая ошибку сегментации (GH 12098)Ошибка в
crosstabгде аргументы с непересекающимися индексами возвращаютKeyError(GH 10291)Ошибка в
DataFrame.applyв котором предотвращение редукции не выполнялось для случаев, когдаdtypeне был numpy dtype (GH 12244)Ошибка при инициализации категориальной серии скалярным значением. (GH 12336)
Ошибка при указании UTC
DatetimeIndexустановкойutc=Trueв.to_datetime(GH 11934)Ошибка при увеличении размера буфера CSV-ридера в
read_csv(GH 12494)Ошибка при установке столбцов
DataFrameс повторяющимися именами столбцов (GH 12344)
Участники#
Всего 101 человек внесли патчи в этот релиз. Люди с «+» рядом с именами внесли патч впервые.
ARF +
Alex Alekseyev +
Andrew McPherson +
Andrew Rosenfeld
Andy Hayden
Anthonios Partheniou
Anton I. Sipos
Ben +
Ben North +
Bran Yang +
Chris
Chris Carroux +
Christopher C. Aycock +
Christopher Scanlin +
Cody +
Da Wang +
Daniel Grady +
Dorozhko Anton +
Dr-Irv +
Эрик М. Брей +
Evan Wright
Фрэнсис Т. О’Донован +
Frank Cleary +
Джанлука Росси
Грэм Джеффрис +
Guillaume Horel
Henry Hammond +
Isaac Schwabacher +
Jean-Mathieu Deschenes
Jeff Reback
Joe Jevnik +
Джон Фримен +
John Fremlin +
Jonas Hoersch +
Joris Van den Bossche
Joris Vankerschaver
Justin Lecher
Justin Lin +
Ka Wo Chen
Кеминг Чжан +
Керби Шедден
Kyle +
Marco Farrugia +
MasonGallo +
MattRijk +
Matthew Lurie +
Maximilian Roos
Mayank Asthana +
Mortada Mehyar
Moussa Taifi +
Navreet Gill +
Nicolas Bonnotte
Paul Reiners +
Филип Гура +
Пьетро Баттистон
RahulHP +
Randy Carnevale
Rinoc Johnson
Rishipuri +
Sangmin Park +
Скотт Э. Ласли
Sereger13 +
Shannon Wang +
Skipper Seabold
Thierry Moisan
Thomas A Caswell
Toby Dylan Hocking +
Tom Augspurger
Travis +
Trent Hauck
Tux1
Varun
Wes McKinney
Will Thompson +
register_dataframe_accessor
Yoong Kang Lim +
Yoshiki Vázquez Baeza
Young Joong Kim +
Younggun Kim
Yuval Langer +
alex argunov +
behzad nouri
boombard +
brian-pantano +
chromy +
daniel +
dgram0 +
gfyoung +
hack-c +
hcontrast +
jfoo +
kaustuv deolal +
llllllllll
ranarag +
rockg
scls19fr
seales +
sinhrks
srib +
surveymedia.ca +
tworec +