Что нового в 0.23.0 (15 мая 2018)#

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

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

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

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

Начиная с 1 января 2019 года, релизы функций pandas будут поддерживать только Python 3. См. Удаление Python 2.7 подробнее.

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

Чтение/запись JSON с сохранением цикла (round-trippable) с orient='table'#

A DataFrame теперь можно записывать и затем считывать через JSON с сохранением метаданных с использованием orient='table' аргумент (см. GH 18912 и GH 9146). Ранее ни один из доступных orient значения гарантировали сохранение типов данных и имен индексов, среди прочих метаданных.

In [1]: df = pd.DataFrame({'foo': [1, 2, 3, 4],
   ...:                    'bar': ['a', 'b', 'c', 'd'],
   ...:                    'baz': pd.date_range('2018-01-01', freq='d', periods=4),
   ...:                    'qux': pd.Categorical(['a', 'b', 'c', 'c'])},
   ...:                   index=pd.Index(range(4), name='idx'))
   ...: 

In [2]: df
Out[2]: 
     foo bar        baz qux
idx                        
0      1   a 2018-01-01   a
1      2   b 2018-01-02   b
2      3   c 2018-01-03   c
3      4   d 2018-01-04   c

[4 rows x 4 columns]

In [3]: df.dtypes
Out[3]: 
foo             int64
bar            object
baz    datetime64[ns]
qux          category
Length: 4, dtype: object

In [4]: df.to_json('test.json', orient='table')

In [5]: new_df = pd.read_json('test.json', orient='table')

In [6]: new_df
Out[6]: 
     foo bar        baz qux
idx                        
0      1   a 2018-01-01   a
1      2   b 2018-01-02   b
2      3   c 2018-01-03   c
3      4   d 2018-01-04   c

[4 rows x 4 columns]

In [7]: new_df.dtypes
Out[7]: 
foo             int64
bar            object
baz    datetime64[ns]
qux          category
Length: 4, dtype: object

Обратите внимание, что строка index не поддерживается с форматом кругового обхода, так как он используется по умолчанию в write_json для указания отсутствующего имени индекса.

In [8]: df.index.name = 'index'

In [9]: df.to_json('test.json', orient='table')

In [10]: new_df = pd.read_json('test.json', orient='table')

In [11]: new_df
Out[11]: 
   foo bar        baz qux
0    1   a 2018-01-01   a
1    2   b 2018-01-02   b
2    3   c 2018-01-03   c
3    4   d 2018-01-04   c

[4 rows x 4 columns]

In [12]: new_df.dtypes
Out[12]: 
foo             int64
bar            object
baz    datetime64[ns]
qux          category
Length: 4, dtype: object

Метод .assign() принимает зависимые аргументы#

The DataFrame.assign() теперь принимает зависимые ключевые аргументы для версии Python позже 3.6 (см. также PEP 468). Поздние ключевые аргументы теперь могут ссылаться на более ранние, если аргумент является вызываемым. См. документация здесь (GH 14207)

In [13]: df = pd.DataFrame({'A': [1, 2, 3]})

In [14]: df
Out[14]: 
   A
0  1
1  2
2  3

[3 rows x 1 columns]

In [15]: df.assign(B=df.A, C=lambda x: x['A'] + x['B'])
Out[15]: 
   A  B  C
0  1  1  2
1  2  2  4
2  3  3  6

[3 rows x 3 columns]

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

Это может незаметно изменить поведение вашего кода при использовании .assign() для обновления существующего столбца. Ранее вызываемые объекты, ссылающиеся на другие обновляемые переменные, получали «старые» значения

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

In [2]: df = pd.DataFrame({"A": [1, 2, 3]})

In [3]: df.assign(A=lambda df: df.A + 1, C=lambda df: df.A * -1)
Out[3]:
   A  C
0  2 -1
1  3 -2
2  4 -3

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

In [16]: df.assign(A=df.A + 1, C=lambda df: df.A * -1)
Out[16]: 
   A  C
0  2 -2
1  3 -3
2  4 -4

[3 rows x 2 columns]

Слияние по комбинации столбцов и уровней индекса#

Строки, переданные в DataFrame.merge() как on, left_on, и right_on параметры теперь могут ссылаться либо на имена столбцов, либо на имена уровней индекса. Это позволяет объединять DataFrame экземпляры на комбинации уровней индекса и столбцов без сброса индексов. См. Объединение по столбцам и уровням раздел документации. (GH 14355)

In [17]: left_index = pd.Index(['K0', 'K0', 'K1', 'K2'], name='key1')

In [18]: left = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
   ....:                      'B': ['B0', 'B1', 'B2', 'B3'],
   ....:                      'key2': ['K0', 'K1', 'K0', 'K1']},
   ....:                     index=left_index)
   ....: 

In [19]: right_index = pd.Index(['K0', 'K1', 'K2', 'K2'], name='key1')

In [20]: right = pd.DataFrame({'C': ['C0', 'C1', 'C2', 'C3'],
   ....:                       'D': ['D0', 'D1', 'D2', 'D3'],
   ....:                       'key2': ['K0', 'K0', 'K0', 'K1']},
   ....:                      index=right_index)
   ....: 

In [21]: left.merge(right, on=['key1', 'key2'])
Out[21]: 
       A   B key2   C   D
key1                     
K0    A0  B0   K0  C0  D0
K1    A2  B2   K0  C1  D1
K2    A3  B3   K1  C3  D3

[3 rows x 5 columns]

Сортировка по комбинации столбцов и уровней индекса#

Строки, переданные в DataFrame.sort_values() как by Параметр теперь может ссылаться как на имена столбцов, так и на имена уровней индекса. Это позволяет сортировку DataFrame экземпляров по комбинации уровней индекса и столбцов без сброса индексов. См. Сортировка по индексам и значениям раздел документации. (GH 14353)

# Build MultiIndex
In [22]: idx = pd.MultiIndex.from_tuples([('a', 1), ('a', 2), ('a', 2),
   ....:                                  ('b', 2), ('b', 1), ('b', 1)])
   ....: 

In [23]: idx.names = ['first', 'second']

# Build DataFrame
In [24]: df_multi = pd.DataFrame({'A': np.arange(6, 0, -1)},
   ....:                         index=idx)
   ....: 

In [25]: df_multi
Out[25]: 
              A
first second   
a     1       6
      2       5
      2       4
b     2       3
      1       2
      1       1

[6 rows x 1 columns]

# Sort by 'second' (index) and 'A' (column)
In [26]: df_multi.sort_values(by=['second', 'A'])
Out[26]: 
              A
first second   
b     1       1
      1       2
a     1       6
b     2       3
a     2       4
      2       5

[6 rows x 1 columns]

Расширение pandas пользовательскими типами (экспериментальная функция)#

pandas теперь поддерживает хранение объектов, похожих на массивы, которые не обязательно являются 1-D массивами NumPy, в качестве столбцов DataFrame или значений в Series. Это позволяет сторонним библиотекам реализовывать расширения типов NumPy, аналогично тому, как pandas реализовал категории, даты и время с часовыми поясами, периоды и интервалы.

В качестве демонстрации мы будем использовать cyberpandas, который предоставляет IPArray тип для хранения IP-адресов.

In [1]: from cyberpandas import IPArray

In [2]: values = IPArray([
   ...:     0,
   ...:     3232235777,
   ...:     42540766452641154071740215577757643572
   ...: ])
   ...:
   ...:

IPArray не является обычным одномерным массивом NumPy, а потому что это pandas ExtensionArray, он может быть правильно сохранен внутри контейнеров pandas.

In [3]: ser = pd.Series(values)

In [4]: ser
Out[4]:
0                         0.0.0.0
1                     192.168.1.1
2    2001:db8:85a3::8a2e:370:7334
dtype: ip

Обратите внимание, что тип данных - ip. Семантика пропущенных значений базового массива учитывается:

In [5]: ser.isna()
Out[5]:
0     True
1    False
2    False
dtype: bool

Для получения дополнительной информации см. расширенные типы документации. Если вы создаете массив расширений, опубликуйте его в страница экосистемы.

Новый observed ключевое слово для исключения ненаблюдаемых категорий в GroupBy#

Группировка по категориальной переменной включает ненаблюдаемые категории в вывод. При группировке по нескольким категориальным столбцам это означает, что вы получаете декартово произведение всех категорий, включая комбинации, где нет наблюдений, что может привести к большому количеству групп. Мы добавили ключевое слово observed для управления этим поведением по умолчанию установлено observed=False для обратной совместимости. (GH 14942, GH 8138, GH 15217, GH 17594, GH 8669, GH 20583, GH 20902)

In [27]: cat1 = pd.Categorical(["a", "a", "b", "b"],
   ....:                       categories=["a", "b", "z"], ordered=True)
   ....: 

In [28]: cat2 = pd.Categorical(["c", "d", "c", "d"],
   ....:                       categories=["c", "d", "y"], ordered=True)
   ....: 

In [29]: df = pd.DataFrame({"A": cat1, "B": cat2, "values": [1, 2, 3, 4]})

In [30]: df['C'] = ['foo', 'bar'] * 2

In [31]: df
Out[31]: 
   A  B  values    C
0  a  c       1  foo
1  a  d       2  bar
2  b  c       3  foo
3  b  d       4  bar

[4 rows x 4 columns]

Чтобы показать все значения, предыдущее поведение:

In [32]: df.groupby(['A', 'B', 'C'], observed=False).count()
Out[32]: 
         values
A B C          
a c bar       0
    foo       1
  d bar       1
    foo       0
  y bar       0
...         ...
z c foo       0
  d bar       0
    foo       0
  y bar       0
    foo       0

[18 rows x 1 columns]

Чтобы показать только наблюдаемые значения:

In [33]: df.groupby(['A', 'B', 'C'], observed=True).count()
Out[33]: 
         values
A B C          
a c foo       1
  d bar       1
b c foo       1
  d bar       1

[4 rows x 1 columns]

Для операций сводных таблиц это поведение уже управляется параметром dropna ключевое слово:

In [34]: cat1 = pd.Categorical(["a", "a", "b", "b"],
   ....:                       categories=["a", "b", "z"], ordered=True)
   ....: 

In [35]: cat2 = pd.Categorical(["c", "d", "c", "d"],
   ....:                       categories=["c", "d", "y"], ordered=True)
   ....: 

In [36]: df = pd.DataFrame({"A": cat1, "B": cat2, "values": [1, 2, 3, 4]})

In [37]: df
Out[37]: 
   A  B  values
0  a  c       1
1  a  d       2
2  b  c       3
3  b  d       4

[4 rows x 3 columns]
In [1]: pd.pivot_table(df, values='values', index=['A', 'B'], dropna=True)

Out[1]:
     values
A B
a c     1.0
  d     2.0
b c     3.0
  d     4.0

In [2]: pd.pivot_table(df, values='values', index=['A', 'B'], dropna=False)

Out[2]:
     values
A B
a c     1.0
  d     2.0
  y     NaN
b c     3.0
  d     4.0
  y     NaN
z c     NaN
  d     NaN
  y     NaN

Rolling/Expanding.apply() принимает raw=False передать Series в функцию#

Series.rolling().apply(), DataFrame.rolling().apply(), Series.expanding().apply(), и DataFrame.expanding().apply() получили raw=None параметр. Это похоже на DataFame.apply()Этот параметр, если True позволяет отправить np.ndarray в применяемую функцию. Если False a Series будет передан. Значение по умолчанию: None, что сохраняет обратную совместимость, поэтому по умолчанию будет True, отправляя np.ndarray. В будущей версии значение по умолчанию будет изменено на False, отправляя Series. (GH 5071, GH 20584)

In [38]: s = pd.Series(np.arange(5), np.arange(5) + 1)

In [39]: s
Out[39]: 
1    0
2    1
3    2
4    3
5    4
Length: 5, dtype: int64

Передать Series:

In [40]: s.rolling(2, min_periods=1).apply(lambda x: x.iloc[-1], raw=False)
Out[40]: 
1    0.0
2    1.0
3    2.0
4    3.0
5    4.0
Length: 5, dtype: float64

Имитировать исходное поведение передачи ndarray:

In [41]: s.rolling(2, min_periods=1).apply(lambda x: x[-1], raw=True)
Out[41]: 
1    0.0
2    1.0
3    2.0
4    3.0
5    4.0
Length: 5, dtype: float64

DataFrame.interpolate получил limit_area kwarg#

DataFrame.interpolate() получил limit_area параметр для дополнительного контроля над тем, какие NaN заменяются. Используйте limit_area='inside' для заполнения только NaN, окружённых допустимыми значениями, или использовать limit_area='outside' для заполнения только NaN s вне существующих допустимых значений, сохраняя те, что внутри. (GH 16284) См. полная документация здесь.

In [42]: ser = pd.Series([np.nan, np.nan, 5, np.nan, np.nan,
   ....:                  np.nan, 13, np.nan, np.nan])
   ....: 

In [43]: ser
Out[43]: 
0     NaN
1     NaN
2     5.0
3     NaN
4     NaN
5     NaN
6    13.0
7     NaN
8     NaN
Length: 9, dtype: float64

Заполнить одно последовательное внутреннее значение в обоих направлениях

In [44]: ser.interpolate(limit_direction='both', limit_area='inside', limit=1)
Out[44]: 
0     NaN
1     NaN
2     5.0
3     7.0
4     NaN
5    11.0
6    13.0
7     NaN
8     NaN
Length: 9, dtype: float64

Заполнить все последовательные внешние значения назад

In [45]: ser.interpolate(limit_direction='backward', limit_area='outside')
Out[45]: 
0     5.0
1     5.0
2     5.0
3     NaN
4     NaN
5     NaN
6    13.0
7     NaN
8     NaN
Length: 9, dtype: float64

Заполнить все последовательные внешние значения в обоих направлениях

In [46]: ser.interpolate(limit_direction='both', limit_area='outside')
Out[46]: 
0     5.0
1     5.0
2     5.0
3     NaN
4     NaN
5     NaN
6    13.0
7    13.0
8    13.0
Length: 9, dtype: float64

Функция get_dummies теперь поддерживает dtype аргумент#

The get_dummies() теперь принимает dtype аргумент, который указывает dtype для новых столбцов. По умолчанию остается uint8. (GH 18330)

In [47]: df = pd.DataFrame({'a': [1, 2], 'b': [3, 4], 'c': [5, 6]})

In [48]: pd.get_dummies(df, columns=['c']).dtypes
Out[48]: 
a      int64
b      int64
c_5     bool
c_6     bool
Length: 4, dtype: object

In [49]: pd.get_dummies(df, columns=['c'], dtype=bool).dtypes
Out[49]: 
a      int64
b      int64
c_5     bool
c_6     bool
Length: 4, dtype: object

Метод mod для Timedelta#

mod (%) и divmod операции теперь определены на Timedelta объектов при работе либо с дельта-времени, либо с числовыми аргументами. См. документация здесь. (GH 19365)

In [50]: td = pd.Timedelta(hours=37)

In [51]: td % pd.Timedelta(minutes=45)
Out[51]: Timedelta('0 days 00:15:00')

Метод .rank() обрабатывает inf значения, когда NaN присутствуют#

В предыдущих версиях, .rank() присвоит inf элементы NaN в качестве их рангов. Теперь ранги рассчитываются правильно. (GH 6945)

In [52]: s = pd.Series([-np.inf, 0, 1, np.nan, np.inf])

In [53]: s
Out[53]: 
0   -inf
1    0.0
2    1.0
3    NaN
4    inf
Length: 5, dtype: float64

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

In [11]: s.rank()
Out[11]:
0    1.0
1    2.0
2    3.0
3    NaN
4    NaN
dtype: float64

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

In [54]: s.rank()
Out[54]: 
0    1.0
1    2.0
2    3.0
3    NaN
4    4.0
Length: 5, dtype: float64

Кроме того, ранее если вы ранжировали inf или -inf значения вместе с NaN значения, вычисление не будет различать NaN от бесконечности при использовании аргументов 'top' или 'bottom'.

In [55]: s = pd.Series([np.nan, np.nan, -np.inf, -np.inf])

In [56]: s
Out[56]: 
0    NaN
1    NaN
2   -inf
3   -inf
Length: 4, dtype: float64

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

In [15]: s.rank(na_option='top')
Out[15]:
0    2.5
1    2.5
2    2.5
3    2.5
dtype: float64

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

In [57]: s.rank(na_option='top')
Out[57]: 
0    1.5
1    1.5
2    3.5
3    3.5
Length: 4, dtype: float64

Эти ошибки были исправлены:

  • Ошибка в DataFrame.rank() и Series.rank() когда method='dense' и pct=True в котором процентильные ранги не использовались с количеством уникальных наблюдений (GH 15630)

  • Ошибка в Series.rank() и DataFrame.rank() когда ascending='False' не возвращал правильные ранги для бесконечности, если NaN присутствовали (GH 19538)

  • Ошибка в DataFrameGroupBy.rank() где ранги были некорректными при наличии как бесконечности, так и NaN присутствовали (GH 20561)

Series.str.cat получил join kwarg#

Ранее, Series.str.cat() не – в отличие от большинства pandas – выравнивание Series по их индексу перед конкатенацией (см. GH 18657). Метод теперь получил ключевое слово join для управления способом выравнивания, см. примеры ниже и здесь.

В версии 0.23 join по умолчанию будет None (означает отсутствие выравнивания), но это значение по умолчанию изменится на 'left' в будущей версии pandas.

In [58]: s = pd.Series(['a', 'b', 'c', 'd'])

In [59]: t = pd.Series(['b', 'd', 'e', 'c'], index=[1, 3, 4, 2])

In [60]: s.str.cat(t)
Out[60]: 
0    NaN
1     bb
2     cc
3     dd
Length: 4, dtype: object

In [61]: s.str.cat(t, join='left', na_rep='-')
Out[61]: 
0    a-
1    bb
2    cc
3    dd
Length: 4, dtype: object

Кроме того, Series.str.cat() теперь работает для CategoricalIndex также (ранее вызывал ValueError; см. GH 20842).

DataFrame.astype выполняет построчное преобразование в Categorical#

DataFrame.astype() теперь может выполнять преобразование по столбцам в Categorical путем предоставления строки 'category' или CategoricalDtype. Ранее попытка этого вызывала NotImplementedError. См. Создание объектов раздел документации для получения дополнительных подробностей и примеров. (GH 12860, GH 18099)

Предоставление строки 'category' выполняет преобразование по столбцам, с установкой в качестве категорий только меток, появляющихся в данном столбце:

In [62]: df = pd.DataFrame({'A': list('abca'), 'B': list('bccd')})

In [63]: df = df.astype('category')

In [64]: df['A'].dtype
Out[64]: CategoricalDtype(categories=['a', 'b', 'c'], ordered=False, categories_dtype=object)

In [65]: df['B'].dtype
Out[65]: CategoricalDtype(categories=['b', 'c', 'd'], ordered=False, categories_dtype=object)

Предоставление CategoricalDtype сделает категории в каждом столбце согласованными с указанным dtype:

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

In [67]: df = pd.DataFrame({'A': list('abca'), 'B': list('bccd')})

In [68]: cdt = CategoricalDtype(categories=list('abcd'), ordered=True)

In [69]: df = df.astype(cdt)

In [70]: df['A'].dtype
Out[70]: CategoricalDtype(categories=['a', 'b', 'c', 'd'], ordered=True, categories_dtype=object)

In [71]: df['B'].dtype
Out[71]: CategoricalDtype(categories=['a', 'b', 'c', 'd'], ordered=True, categories_dtype=object)

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

  • Унарный + теперь разрешено для Series и DataFrame как числовой оператор (GH 16073)

  • Улучшенная поддержка для to_excel() вывод с xlsxwriter движок. (GH 16149)

  • pandas.tseries.frequencies.to_offset() теперь принимает ведущие знаки '+' например '+1h'. (GH 18171)

  • MultiIndex.unique() теперь поддерживает level= аргумент, чтобы получить уникальные значения с определенного уровня индекса (GH 17896)

  • pandas.io.formats.style.Styler теперь имеет метод hide_index() чтобы определить, будет ли индекс отображаться в выводе (GH 14194)

  • pandas.io.formats.style.Styler теперь имеет метод hide_columns() для определения, будут ли столбцы скрыты в выводе (GH 14194)

  • Улучшенная формулировка ValueError вызвано в to_datetime() когда unit= передается с неконвертируемым значением (GH 14350)

  • Series.fillna() теперь принимает Series или dict в качестве value для категориального типа данных (GH 17033)

  • pandas.read_clipboard() обновлено для использования qtpy с откатом на PyQt5 и затем PyQt4, добавлена совместимость с Python3 и несколькими python-qt биндингами (GH 17722)

  • Улучшенная формулировка ValueError вызвано в read_csv() когда usecols аргумент не может соответствовать всем столбцам. (GH 17301)

  • DataFrame.corrwith() теперь молча удаляет нечисловые столбцы при передаче Series. Ранее возникало исключение (GH 18570).

  • IntervalIndex теперь поддерживает учитывающие часовой пояс Interval объекты (GH 18537, GH 18538)

  • Series() / DataFrame() автодополнение также возвращает идентификаторы на первом уровне MultiIndex(). (GH 16326)

  • read_excel() получил nrows параметр (GH 16645)

  • DataFrame.append() теперь может в большем числе случаев сохранять тип столбцов вызывающего dataframe (например, если оба являются CategoricalIndex) (GH 18359)

  • DataFrame.to_json() и Series.to_json() теперь принимает index аргумент, который позволяет пользователю исключить индекс из вывода JSON (GH 17394)

  • IntervalIndex.to_tuples() получил na_tuple параметр для управления, возвращается ли NA как кортеж NA или сам NA (GH 18756)

  • Categorical.rename_categories, CategoricalIndex.rename_categories и Series.cat.rename_categories теперь могут принимать вызываемый объект в качестве аргумента (GH 18862)

  • Interval и IntervalIndex получили length атрибут (GH 18789)

  • Resampler объекты теперь имеют работающий Resampler.pipe метод. Ранее вызовы к pipe были перенаправлены в mean метод (GH 17905).

  • is_scalar() теперь возвращает True для DateOffset объекты (GH 18943).

  • DataFrame.pivot() теперь принимает список для values= kwarg (GH 17160).

  • Добавлен pandas.api.extensions.register_dataframe_accessor(), pandas.api.extensions.register_series_accessor(), и pandas.api.extensions.register_index_accessor(), аксессор для библиотек, зависимых от pandas, чтобы регистрировать пользовательские аксессоры, такие как .cat для объектов pandas. См. Регистрация пользовательских аксессоров для получения дополнительной информации (GH 14781).

  • IntervalIndex.astype теперь поддерживает преобразования между подтипами при передаче IntervalDtype (GH 19197)

  • IntervalIndex и связанные с ним методы конструктора (from_arrays, from_breaks, from_tuples) получили dtype параметр (GH 19262)

  • Добавлен SeriesGroupBy.is_monotonic_increasing() и SeriesGroupBy.is_monotonic_decreasing() (GH 17015)

  • Для унаследованных DataFrames, DataFrame.apply() теперь сохранит Series подкласс (если определен) при передаче данных применяемой функции (GH 19822)

  • DataFrame.from_dict() теперь принимает columns аргумент, который можно использовать для указания имён столбцов, когда orient='index' используется (GH 18529)

  • Добавлена опция display.html.use_mathjax так MathJax может быть отключен при отображении таблиц в Jupyter блокноты (GH 19856, GH 19824)

  • DataFrame.replace() теперь поддерживает method параметр, который можно использовать для указания метода замены, когда to_replace является скаляром, списком или кортежем и value является None (GH 19632)

  • Timestamp.month_name(), DatetimeIndex.month_name(), и Series.dt.month_name() теперь доступны (GH 12805)

  • Timestamp.day_name() и DatetimeIndex.day_name() теперь доступны для возврата названий дней с указанной локалью (GH 12806)

  • DataFrame.to_sql() теперь выполняет множественную вставку, если базовое соединение поддерживает её, вместо вставки построчно. SQLAlchemy диалекты, поддерживающие вставку нескольких значений, включают: mysql, postgresql, sqlite и любой диалект с supports_multivalues_insert. (GH 14315, GH 8953)

  • read_html() теперь принимает displayed_only ключевой аргумент для управления тем, анализируются ли скрытые элементы (True по умолчанию) (GH 20027)

  • read_html() теперь читает все элементы в , а не только первый. (GH 20690)

  • Rolling.quantile() и Expanding.quantile() теперь принимают interpolation ключевое слово, linear по умолчанию (GH 20497)

  • поддерживается сжатие zip через compression=zip в DataFrame.to_pickle(), Series.to_pickle(), DataFrame.to_csv(), Series.to_csv(), DataFrame.to_json(), Series.to_json(). (GH 17778)

  • WeekOfMonth конструктор теперь поддерживает n=0 (GH 20517).

  • DataFrame и Series теперь поддерживают матричное умножение (@) оператор (GH 10259) для Python>=3.5

  • Обновлено DataFrame.to_gbq() и pandas.read_gbq() сигнатуру и документацию, чтобы отразить изменения из версии 0.4.0 библиотеки pandas-gbq. Добавляет intersphinx-сопоставление с библиотекой pandas-gbq. (GH 20564)

  • Добавлен новый модуль записи для экспорта файлов Stata dta в версии 117, StataWriter117. Этот формат поддерживает экспорт строк длиной до 2 000 000 символов (GH 16450)

  • to_hdf() и read_hdf() теперь принимает errors ключевой аргумент для управления обработкой ошибок кодировки (GH 20835)

  • cut() получил duplicates='raise'|'drop' опцию для управления вызовом ошибки при дублировании границ (GH 20947)

  • date_range(), timedelta_range(), и interval_range() теперь возвращает линейно распределенный индекс, если start, stop, и periods указаны, но freq не является. (GH 20808, GH 20983, GH 20976)

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

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

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

    Пакет

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

    Обязательно

    Проблема

    python-dateutil

    2.5.0

    X

    GH 15184

    openpyxl

    2.4.0

    GH 15184

    beautifulsoup4

    4.2.1

    GH 20082

    setuptools

    24.2.0

    GH 20698

Создание из словарей сохраняет порядок вставки словаря для Python 3.6+#

До Python 3.6 словари в Python не имели формально определённого порядка. Для версий Python 3.6 и выше словари упорядочены по порядку вставки, см. PEP 468. pandas будет использовать порядок вставки словаря при создании Series или DataFrame из словаря, и вы используете версию Python 3.6 или выше. (GH 19884)

Предыдущее поведение (и текущее поведение, если на Python < 3.6):

In [16]: pd.Series({'Income': 2000,
   ....:            'Expenses': -1500,
   ....:            'Taxes': -200,
   ....:            'Net result': 300})
Out[16]:
Expenses     -1500
Income        2000
Net result     300
Taxes         -200
dtype: int64

Обратите внимание, что Series выше упорядочен по алфавиту по значениям индекса.

Новое поведение (для Python >= 3.6):

In [72]: pd.Series({'Income': 2000,
   ....:            'Expenses': -1500,
   ....:            'Taxes': -200,
   ....:            'Net result': 300})
   ....: 
Out[72]: 
Income        2000
Expenses     -1500
Taxes         -200
Net result     300
Length: 4, dtype: int64

Обратите внимание, что Series теперь упорядочены по порядку вставки. Это новое поведение используется для всех соответствующих типов pandas (Series, DataFrame, SparseSeries и SparseDataFrame).

Если вы хотите сохранить старое поведение при использовании Python >= 3.6, вы можете использовать .sort_index():

In [73]: pd.Series({'Income': 2000,
   ....:            'Expenses': -1500,
   ....:            'Taxes': -200,
   ....:            'Net result': 300}).sort_index()
   ....: 
Out[73]: 
Expenses     -1500
Income        2000
Net result     300
Taxes         -200
Length: 4, dtype: int64

Устаревание Panel#

Panel был устаревшим в релизе 0.20.x, отображаясь как DeprecationWarning. Использование Panel теперь будет показывать FutureWarning. Рекомендуемый способ представления 3-D данных — с помощью MultiIndex на DataFrame через to_frame() или с пакет xarray. pandas предоставляет to_xarray() метод для автоматизации этого преобразования (GH 13563, GH 18324).

In [75]: import pandas._testing as tm

In [76]: p = tm.makePanel()

In [77]: p
Out[77]:

Dimensions: 3 (items) x 3 (major_axis) x 4 (minor_axis)
Items axis: ItemA to ItemC
Major_axis axis: 2000-01-03 00:00:00 to 2000-01-05 00:00:00
Minor_axis axis: A to D

Преобразовать в DataFrame с MultiIndex

In [78]: p.to_frame()
Out[78]:
                     ItemA     ItemB     ItemC
major      minor
2000-01-03 A      0.469112  0.721555  0.404705
           B     -1.135632  0.271860 -1.039268
           C      0.119209  0.276232 -1.344312
           D     -2.104569  0.113648 -0.109050
2000-01-04 A     -0.282863 -0.706771  0.577046
           B      1.212112 -0.424972 -0.370647
           C     -1.044236 -1.087401  0.844885
           D     -0.494929 -1.478427  1.643563
2000-01-05 A     -1.509059 -1.039575 -1.715002
           B     -0.173215  0.567020 -1.157892
           C     -0.861849 -0.673690  1.075770
           D      1.071804  0.524988 -1.469388

[12 rows x 3 columns]

Преобразовать в DataArray xarray

In [79]: p.to_xarray()
Out[79]:

array([[[ 0.469112, -1.135632,  0.119209, -2.104569],
        [-0.282863,  1.212112, -1.044236, -0.494929],
        [-1.509059, -0.173215, -0.861849,  1.071804]],

       [[ 0.721555,  0.27186 ,  0.276232,  0.113648],
        [-0.706771, -0.424972, -1.087401, -1.478427],
        [-1.039575,  0.56702 , -0.67369 ,  0.524988]],

       [[ 0.404705, -1.039268, -1.344312, -0.10905 ],
        [ 0.577046, -0.370647,  0.844885,  1.643563],
        [-1.715002, -1.157892,  1.07577 , -1.469388]]])
Coordinates:
  * items       (items) object 'ItemA' 'ItemB' 'ItemC'
  * major_axis  (major_axis) datetime64[ns] 2000-01-03 2000-01-04 2000-01-05
  * minor_axis  (minor_axis) object 'A' 'B' 'C' 'D'

удаления из pandas.core.common#

Следующие сообщения об ошибках и предупреждениях удалены из pandas.core.common (GH 13634, GH 19769):

  • PerformanceWarning

  • UnsupportedFunctionCall

  • UnsortedIndexError

  • AbstractMethodError

Они доступны при импорте из pandas.errors (с версии 0.19.0).

Изменения для вывода DataFrame.apply последовательный#

DataFrame.apply() был непоследовательным при применении произвольной пользовательской функции, возвращающей списокоподобный объект с axis=1. Устранены несколько ошибок и несоответствий. Если примененная функция возвращает Series, то pandas вернет DataFrame; в противном случае будет возвращена Series, включая случай, когда список (например, tuple или list возвращается) (GH 16353, GH 17437, GH 17970, GH 17348, GH 17892, GH 18573, GH 17602, GH 18775, GH 18901, GH 18919).

In [74]: df = pd.DataFrame(np.tile(np.arange(3), 6).reshape(6, -1) + 1,
   ....:                   columns=['A', 'B', 'C'])
   ....: 

In [75]: df
Out[75]: 
   A  B  C
0  1  2  3
1  1  2  3
2  1  2  3
3  1  2  3
4  1  2  3
5  1  2  3

[6 rows x 3 columns]

Предыдущее поведение: если возвращаемая форма случайно совпадала с длиной исходных столбцов, это возвращало DataFrame. Если возвращаемая форма не совпала, то Series возвращался со списками.

In [3]: df.apply(lambda x: [1, 2, 3], axis=1)
Out[3]:
   A  B  C
0  1  2  3
1  1  2  3
2  1  2  3
3  1  2  3
4  1  2  3
5  1  2  3

In [4]: df.apply(lambda x: [1, 2], axis=1)
Out[4]:
0    [1, 2]
1    [1, 2]
2    [1, 2]
3    [1, 2]
4    [1, 2]
5    [1, 2]
dtype: object

Новое поведение: Когда применяемая функция возвращает список, это теперь всегда возвращает Series.

In [76]: df.apply(lambda x: [1, 2, 3], axis=1)
Out[76]: 
0    [1, 2, 3]
1    [1, 2, 3]
2    [1, 2, 3]
3    [1, 2, 3]
4    [1, 2, 3]
5    [1, 2, 3]
Length: 6, dtype: object

In [77]: df.apply(lambda x: [1, 2], axis=1)
Out[77]: 
0    [1, 2]
1    [1, 2]
2    [1, 2]
3    [1, 2]
4    [1, 2]
5    [1, 2]
Length: 6, dtype: object

Чтобы иметь расширенные столбцы, вы можете использовать result_type='expand'

In [78]: df.apply(lambda x: [1, 2, 3], axis=1, result_type='expand')
Out[78]: 
   0  1  2
0  1  2  3
1  1  2  3
2  1  2  3
3  1  2  3
4  1  2  3
5  1  2  3

[6 rows x 3 columns]

Чтобы транслировать результат по исходным столбцам (старое поведение для списков правильной длины), можно использовать result_type='broadcast'. Форма должна соответствовать исходным столбцам.

In [79]: df.apply(lambda x: [1, 2, 3], axis=1, result_type='broadcast')
Out[79]: 
   A  B  C
0  1  2  3
1  1  2  3
2  1  2  3
3  1  2  3
4  1  2  3
5  1  2  3

[6 rows x 3 columns]

Возврат Series позволяет контролировать точную структуру возврата и имена столбцов:

In [80]: df.apply(lambda x: pd.Series([1, 2, 3], index=['D', 'E', 'F']), axis=1)
Out[80]: 
   D  E  F
0  1  2  3
1  1  2  3
2  1  2  3
3  1  2  3
4  1  2  3
5  1  2  3

[6 rows x 3 columns]

Конкатенация больше не будет сортировать#

В будущей версии pandas pandas.concat() BooleanArray реализует логику Клин (иногда называемую трёхзначной логикой) для логических операций. См. sort не указан и ось неконкатенации не выровнена (GH 4588).

In [81]: df1 = pd.DataFrame({"a": [1, 2], "b": [1, 2]}, columns=['b', 'a'])

In [82]: df2 = pd.DataFrame({"a": [4, 5]})

In [83]: pd.concat([df1, df2])
Out[83]: 
     b  a
0  1.0  1
1  2.0  2
0  NaN  4
1  NaN  5

[4 rows x 2 columns]

Чтобы сохранить предыдущее поведение (сортировку) и отключить предупреждение, передайте sort=True

In [84]: pd.concat([df1, df2], sort=True)
Out[84]: 
   a    b
0  1  1.0
1  2  2.0
0  4  NaN
1  5  NaN

[4 rows x 2 columns]

Чтобы принять будущее поведение (без сортировки), передайте sort=False

Обратите внимание, что это изменение также применяется к DataFrame.append(), который также получил sort ключевое слово для управления этим поведением.

Изменения сборки#

  • Сборка pandas для разработки теперь требует cython >= 0.24 (GH 18613)

  • Сборка из исходного кода теперь явно требует setuptools в setup.py (GH 18113)

  • Обновлённый рецепт conda для соответствия conda-build 3.0+ (GH 18002)

Деление индекса на ноль заполняется корректно#

Операции деления на Index и подклассы теперь будут заполнять деление положительных чисел на ноль np.inf, деление отрицательных чисел на ноль с -np.inf и 0 / 0 с np.nan. Это соответствует существующему Series поведение. (GH 19322, GH 19347)

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

In [6]: index = pd.Int64Index([-1, 0, 1])

In [7]: index / 0
Out[7]: Int64Index([0, 0, 0], dtype='int64')

# Previous behavior yielded different results depending on the type of zero in the divisor
In [8]: index / 0.0
Out[8]: Float64Index([-inf, nan, inf], dtype='float64')

In [9]: index = pd.UInt64Index([0, 1])

In [10]: index / np.array([0, 0], dtype=np.uint64)
Out[10]: UInt64Index([0, 0], dtype='uint64')

In [11]: pd.RangeIndex(1, 5) / 0
ZeroDivisionError: integer division or modulo by zero

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

In [12]: index = pd.Int64Index([-1, 0, 1])
# division by zero gives -infinity where negative,
# +infinity where positive, and NaN for 0 / 0
In [13]: index / 0

# The result of division by zero should not depend on
# whether the zero is int or float
In [14]: index / 0.0

In [15]: index = pd.UInt64Index([0, 1])
In [16]: index / np.array([0, 0], dtype=np.uint64)

In [17]: pd.RangeIndex(1, 5) / 0

Извлечение совпадающих шаблонов из строк#

По умолчанию, извлечение совпадающих шаблонов из строк с str.extract() раньше возвращал Series если извлекалась одна группа ( DataFrame если было извлечено более одной группы). Начиная с pandas 0.23.0 str.extract() всегда возвращает DataFrame, если только expand установлено в False. Наконец, None было допустимым значением для expand параметр (который был эквивалентен False), но теперь вызывает ValueError. (GH 11386)

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

In [1]: s = pd.Series(['number 10', '12 eggs'])

In [2]: extracted = s.str.extract(r'.*(\d\d).*')

In [3]: extracted
Out [3]:
0    10
1    12
dtype: object

In [4]: type(extracted)
Out [4]:
pandas.core.series.Series

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

In [85]: s = pd.Series(['number 10', '12 eggs'])

In [86]: extracted = s.str.extract(r'.*(\d\d).*')

In [87]: extracted
Out[87]: 
    0
0  10
1  12

[2 rows x 1 columns]

In [88]: type(extracted)
Out[88]: pandas.core.frame.DataFrame

Чтобы восстановить предыдущее поведение, просто установите expand to False:

In [89]: s = pd.Series(['number 10', '12 eggs'])

In [90]: extracted = s.str.extract(r'.*(\d\d).*', expand=False)

In [91]: extracted
Out[91]: 
0    10
1    12
Length: 2, dtype: object

In [92]: type(extracted)
Out[92]: pandas.core.series.Series

Значение по умолчанию для ordered параметр CategoricalDtype#

Значение по умолчанию для ordered параметр для CategoricalDtype изменился с False to None для разрешения обновления categories без влияния на ordered. Поведение должно оставаться согласованным для нижестоящих объектов, таких как Categorical (GH 18790)

В предыдущих версиях значение по умолчанию для ordered параметр был False. Это потенциально может привести к ordered параметр непреднамеренно изменяется с True to False когда пользователи пытаются обновить categories if ordered не указана явно, так как она молча будет использовать значение по умолчанию False. Новое поведение для ordered=None состоит в сохранении существующего значения ordered.

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

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

In [3]: cat = pd.Categorical(list('abcaba'), ordered=True, categories=list('cba'))

In [4]: cat
Out[4]:
[a, b, c, a, b, a]
Categories (3, object): [c < b < a]

In [5]: cdt = CategoricalDtype(categories=list('cbad'))

In [6]: cat.astype(cdt)
Out[6]:
[a, b, c, a, b, a]
Categories (4, object): [c < b < a < d]

Обратите внимание в примере выше, что преобразованный Categorical сохранил ordered=True. Значение по умолчанию для ordered остался как False, преобразованный Categorical стал бы неупорядоченным, несмотря на ordered=False никогда не указывается явно. Чтобы изменить значение ordered, явно передайте его в новый тип данных, например. CategoricalDtype(categories=list('cbad'), ordered=False).

Обратите внимание, что непреднамеренное преобразование ordered обсуждаемые выше не возникали в предыдущих версиях из-за отдельных ошибок, которые предотвращали astype от выполнения любого типа преобразования категории в категорию (GH 10696, GH 18593). Эти ошибки были исправлены в этом выпуске, что мотивировало изменение значения по умолчанию для ordered.

Улучшенное форматирование DataFrame в терминале#

Ранее значение по умолчанию для максимального количества столбцов было pd.options.display.max_columns=20. Это означало, что относительно широкие датафреймы не помещались в ширину терминала, и pandas добавлял переносы строк для отображения этих 20 столбцов. Это приводило к выводу, который был относительно трудно читаемым:

../_images/print_df_old.png

Если Python запущен в терминале, максимальное количество столбцов теперь определяется автоматически, чтобы напечатанный фрейм данных помещался в текущую ширину терминала (pd.options.display.max_columns=0) (GH 17023). Если Python запущен как ядро Jupyter (например, Jupyter QtConsole или блокнот Jupyter, а также во многих IDE), это значение не может быть определено автоматически и поэтому устанавливается в 20 как в предыдущих версиях. В терминале это дает гораздо более приятный вывод:

../_images/print_df_new.png

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

pd.options.display.max_columns = 20

Изменения в API Datetimelike#

  • По умолчанию Timedelta конструктор теперь принимает ISO 8601 Duration строка в качестве аргумента (GH 19040)

  • Вычитание NaT из Series с dtype='datetime64[ns]' возвращает Series с dtype='timedelta64[ns]' вместо dtype='datetime64[ns]' (GH 18808)

  • Сложение или вычитание NaT из TimedeltaIndex вернет TimedeltaIndex вместо DatetimeIndex (GH 19124)

  • DatetimeIndex.shift() и TimedeltaIndex.shift() теперь будет вызывать NullFrequencyError (который наследует от ValueError, которая возникала в старых версиях) когда частота объекта индекса None (GH 19147)

  • Сложение и вычитание NaN из Series с dtype='timedelta64[ns]' вызовет TypeError вместо обработки NaN как NaT (GH 19274)

  • NaT деление с datetime.timedelta теперь вернет NaN вместо вызова исключения (GH 17876)

  • Операции между Series с типом данных dtype='datetime64[ns]' и PeriodIndex будет корректно вызывать TypeError (GH 18850)

  • Вычитание Series с учетом часового пояса dtype='datetime64[ns]' с несовпадающими часовыми поясами вызовет TypeError вместо ValueError (GH 18817)

  • Timestamp больше не будет молча игнорировать неиспользуемые или недопустимые tz или tzinfo именованные аргументы (GH 17690)

  • Timestamp больше не будет молча игнорировать недопустимые freq аргументы (GH 5168)

  • CacheableOffset и WeekDay больше не доступны в pandas.tseries.offsets модуль (GH 17830)

  • pandas.tseries.frequencies.get_freq_group() и pandas.tseries.frequencies.DAYS удалены из публичного API (GH 18034)

  • Series.truncate() и DataFrame.truncate() вызовет ValueError если индекс не отсортирован, вместо бесполезного KeyError (GH 17935)

  • Series.first и DataFrame.first теперь вызовет TypeError вместо NotImplementedError когда индекс не является DatetimeIndex (GH 20725).

  • Series.last и DataFrame.last теперь вызовет TypeError вместо NotImplementedError когда индекс не является DatetimeIndex (GH 20725).

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

  • pandas.merge() предоставляет более информативное сообщение об ошибке при попытке слияния по колонкам с учётом часового пояса и без него (GH 15800)

  • Для DatetimeIndex и TimedeltaIndex с freq=None, сложение или вычитание массива с целочисленным типом данных или Index вызовет исключение NullFrequencyError вместо TypeError (GH 19895)

  • Timestamp конструктор теперь принимает nanosecond ключевой или позиционный аргумент (GH 18898)

  • DatetimeIndex теперь вызовет AttributeError когда tz атрибут устанавливается после создания экземпляра (GH 3746)

  • DatetimeIndex с pytz timezone теперь будет возвращать согласованный pytz timezone (GH 18595)

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

  • Series.astype() и Index.astype() с несовместимым dtype теперь вызовет TypeError а не ValueError (GH 18231)

  • Series конструкция с object dtyped tz-aware datetime и dtype=object если указано, теперь будет возвращать object типизированный Series, ранее это определяло тип datetime (GH 18231)

  • A Series of dtype=category созданный из пустого dict теперь будет иметь категории dtype=object вместо dtype=float64, согласованно со случаем передачи пустого списка (GH 18515)

  • Все-NaN уровни в MultiIndex теперь назначаются float вместо object dtype, обеспечивая согласованность с Index (GH 17929).

  • Названия уровней MultiIndex (когда не None) теперь должны быть уникальными: попытка создать MultiIndex с повторяющимися именами вызовет ValueError (GH 18872)

  • Как создание, так и переименование Index/MultiIndex с нехешируемым name/names теперь будет вызывать TypeError (GH 20527)

  • Index.map() теперь может принимать Series и объекты ввода словаря (GH 12756, GH 18482, GH 18509).

  • DataFrame.unstack() теперь по умолчанию будет заполняться np.nan для object столбцов. (GH 12815)

  • IntervalIndex конструктор вызовет исключение, если closed параметр конфликтует с тем, как входные данные интерпретируются как закрытые (GH 18421)

  • Вставка пропущенных значений в индексы будет работать для всех типов индексов и автоматически вставит правильный тип пропущенного значения (NaN, NaT, и т.д.) независимо от переданного типа (GH 18295)

  • При создании с повторяющимися метками, MultiIndex теперь вызывает ValueError. (GH 17464)

  • Series.fillna() теперь вызывает TypeError вместо ValueError когда передается список, кортеж или DataFrame в качестве value (GH 18293)

  • pandas.DataFrame.merge() больше не приводит к float столбец в object при слиянии по int и float столбцы (GH 16572)

  • pandas.merge() теперь вызывает ValueError при попытке слияния с несовместимыми типами данных (GH 9780)

  • Значение NA по умолчанию для UInt64Index изменилось с 0 на NaN, что влияет на методы, которые маскируют с NA, такие как UInt64Index.where() (GH 18398)

  • Рефакторинг setup.py использовать find_packages вместо явного перечисления всех подпакетов (GH 18535)

  • Изменён порядок ключевых аргументов в read_excel() для соответствия read_csv() (GH 16672)

  • wide_to_long() ранее сохранял числовые суффиксы как object dtype. Теперь они преобразуются в числовые, если возможно (GH 17627)

  • В read_excel(), comment аргумент теперь доступен как именованный параметр (GH 18735)

  • Изменён порядок ключевых аргументов в read_excel() для соответствия read_csv() (GH 16672)

  • Опции html.border и mode.use_inf_as_null были объявлены устаревшими в предыдущих версиях, теперь они будут отображаться FutureWarning а не DeprecationWarning (GH 19003)

  • IntervalIndex и IntervalDtype больше не поддерживает категориальные, объектные и строковые подтипы (GH 19016)

  • IntervalDtype теперь возвращает True при сравнении с 'interval' независимо от подтипа, и IntervalDtype.name теперь возвращает 'interval' независимо от подтипа (GH 18980)

  • KeyError теперь вызывает исключение вместо ValueError в drop(), drop(), drop(), drop() при удалении несуществующего элемента в оси с дубликатами (GH 19186)

  • Series.to_csv() теперь принимает compression аргумент, который работает так же, как compression аргумент в DataFrame.to_csv() (GH 18958)

  • Операции над множествами (объединение, разность…) на IntervalIndex с несовместимыми типами индексов теперь вызывает TypeError а не ValueError (GH 19329)

  • DateOffset объекты отображаются проще, например, days=1> вместо kwds={'days': 1}> (GH 19403)

  • Categorical.fillna теперь проверяет свои value и method именованные аргументы. Теперь возникает ошибка, когда указаны оба или ни один из них, что соответствует поведению Series.fillna() (GH 19682)

  • pd.to_datetime('today') теперь возвращает дату и время, согласованно с pd.Timestamp('today'); ранее pd.to_datetime('today') возвращал .normalized() datetime (GH 19935)

  • Series.str.replace() теперь принимает необязательный regex ключевое слово, которое при установке в False, использует замену строковых литералов вместо замены по регулярному выражению (GH 16808)

  • DatetimeIndex.strftime() и PeriodIndex.strftime() теперь возвращает Index вместо массива numpy для согласованности с аналогичными аксессорами (GH 20127)

  • Создание Series из списка длины 1 больше не транслирует этот список при указании более длинного индекса (GH 19714, GH 20391).

  • DataFrame.to_dict() с orient='index' больше не преобразует целочисленные столбцы в float для DataFrame только с целочисленными и float столбцами (GH 18580)

  • Пользовательская функция, которая передается в Series.rolling().aggregate(), DataFrame.rolling().aggregate(), или его расширяющиеся аналоги, теперь всегда передаваться Series, а не np.array; .apply() имеет только raw ключевое слово, см. здесь. Это согласуется с сигнатурами .aggregate() по всему pandas (GH 20584)

  • Типы Rolling и Expanding вызывают NotImplementedError при итерации (GH 11704).

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

  • Series.from_array и SparseSeries.from_array устарели. Используйте обычный конструктор Series(..) и SparseSeries(..) вместо (GH 18213).

  • DataFrame.as_matrix устарел. Используйте DataFrame.values вместо (GH 18458).

  • Series.asobject, DatetimeIndex.asobject, PeriodIndex.asobject и TimeDeltaIndex.asobject были устаревшими. Используйте .astype(object) вместо (GH 18572)

  • Группировка по кортежу ключей теперь выдает FutureWarning и является устаревшим. В будущем кортеж, переданный в 'by' всегда будет ссылаться на один ключ, который является фактическим кортежем, вместо того чтобы рассматривать кортеж как несколько ключей. Чтобы сохранить предыдущее поведение, используйте список вместо кортежа (GH 18314)

  • Series.valid устарел. Используйте Series.dropna() вместо (GH 18800).

  • read_excel() устарел skip_footer параметр. Используйте skipfooter вместо (GH 18836)

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

  • The is_copy атрибут устарел и будет удалён в будущей версии (GH 18801).

  • IntervalIndex.from_intervals устарел в пользу IntervalIndex конструктор (GH 19263)

  • DataFrame.from_items устарел. Используйте DataFrame.from_dict() вместо, или DataFrame.from_dict(OrderedDict()) если вы хотите сохранить порядок ключей (GH 17320, GH 17312)

  • Индексирование MultiIndex или FloatIndex со списком, содержащим некоторые отсутствующие ключи, теперь покажет FutureWarning, что согласуется с другими типами индексов (GH 17758).

  • The broadcast параметр .apply() устарел в пользу result_type='broadcast' (GH 18577)

  • The reduce параметр .apply() устарел в пользу result_type='reduce' (GH 18577)

  • The order параметр factorize() устарел и будет удален в будущем релизе (GH 19727)

  • Timestamp.weekday_name, DatetimeIndex.weekday_name, и Series.dt.weekday_name устарели в пользу Timestamp.day_name(), DatetimeIndex.day_name(), и Series.dt.day_name() (GH 12806)

  • pandas.tseries.plotting.tsplot устарел. Используйте Series.plot() вместо (GH 18627)

  • Index.summary() устарел и будет удален в будущей версии (GH 18217)

  • NDFrame.get_ftype_counts() устарел и будет удален в будущей версии (GH 18243)

  • The convert_datetime64 параметр в DataFrame.to_records() был устаревшим и будет удален в будущей версии. Ошибка NumPy, мотивировавшая этот параметр, была исправлена. Значение по умолчанию для этого параметра также изменилось с True to None (GH 18160).

  • Series.rolling().apply(), DataFrame.rolling().apply(), Series.expanding().apply(), и DataFrame.expanding().apply() устарела передача np.array по умолчанию. Потребуется передать новый raw параметр, чтобы явно указать, что передается (GH 20584)

  • The data, base, strides, flags и itemsize свойства Series и Index классы устарели и будут удалены в будущей версии (GH 20419).

  • DatetimeIndex.offset устарел. Используйте DatetimeIndex.freq вместо (GH 20716)

  • Целочисленное деление между целочисленным ndarray и Timedelta устарел. Разделите на Timedelta.value вместо (GH 19761)

  • Установка PeriodIndex.freq (что не гарантировало корректной работы) устарело. Используйте PeriodIndex.asfreq() вместо (GH 20678)

  • Index.get_duplicates() устарел и будет удален в будущей версии (GH 20239)

  • Предыдущее поведение по умолчанию для отрицательных индексов в Categorical.take устарел. В будущей версии его значение изменится с пропущенных значений на позиционные индексы справа. Будущее поведение согласуется с Series.take() (GH 20664).

  • Передача нескольких осей в axis параметр в DataFrame.dropna() устарел и будет удален в будущей версии (GH 20987)

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

  • Предупреждения об устаревшем использовании Categorical(codes, categories), которые возникали, например, когда первые два аргумента в Categorical() имели разные типы данных, и рекомендовали использование Categorical.from_codes, теперь удалены (GH 8074)

  • The levels и labels атрибуты MultiIndex больше не может быть установлен напрямую (GH 4039).

  • pd.tseries.util.pivot_annual был удален (устарел с версии v0.19). Используйте pivot_table вместо (GH 18370)

  • pd.tseries.util.isleapyear был удален (устарел с версии v0.19). Используйте .is_leap_year свойство в Datetime-подобных объектах вместо (GH 18370)

  • pd.ordered_merge был удален (устарел с версии v0.19). Используйте pd.merge_ordered вместо (GH 18459)

  • The SparseList класс был удален (GH 14007)

  • The pandas.io.wb и pandas.io.data заглушки модулей были удалены (GH 13735)

  • Categorical.from_array был удален (GH 13854)

  • The freq и how параметры были удалены из rolling/expanding/ewm методы DataFrame и Series (устарели с v0.18). Вместо этого выполните ресемплинг перед вызовом методов. (GH 18601 & GH 18668)

  • DatetimeIndex.to_datetime, Timestamp.to_datetime, PeriodIndex.to_datetime, и Index.to_datetime были удалены (GH 8254, GH 14096, GH 14113)

  • read_csv() удалил skip_footer параметр (GH 13386)

  • read_csv() удалил as_recarray параметр (GH 13373)

  • read_csv() удалил buffer_lines параметр (GH 13360)

  • read_csv() удалил compact_ints и use_unsigned параметры (GH 13323)

  • The Timestamp класс удалил offset атрибут в пользу freq (GH 13593)

  • The Series, Categorical, и Index классы удалили reshape метод (GH 13012)

  • pandas.tseries.frequencies.get_standard_freq был удалён в пользу pandas.tseries.frequencies.to_offset(freq).rule_code (GH 13874)

  • The freqstr ключевое слово было удалено из pandas.tseries.frequencies.to_offset в пользу freq (GH 13874)

  • The Panel4D и PanelND классы были удалены (GH 13776)

  • The Panel класс удалил to_long и toLong методы (GH 19077)

  • Опции display.line_with и display.height удалены в пользу display.width и display.max_rows соответственно (GH 4391, GH 19107)

  • The labels атрибут Categorical класс был удалён в пользу Categorical.codes (GH 7768)

  • The flavor параметр был удален из to_sql() метод (GH 13611)

  • Модули pandas.tools.hashing и pandas.util.hashing были удалены (GH 16223)

  • Функции верхнего уровня pd.rolling_*, pd.expanding_* и pd.ewm* были удалены (устарели с версии v0.18). Вместо этого используйте методы DataFrame/Series rolling, expanding и ewm (GH 18723)

  • Импорты из pandas.core.common для функций, таких как is_datetime64_dtype теперь удалены. Они находятся в pandas.api.types. (GH 13634, GH 19769)

  • The infer_dst ключевое слово в Series.tz_localize(), DatetimeIndex.tz_localize() и DatetimeIndex были удалены. infer_dst=True эквивалентно ambiguous='infer', и infer_dst=False to ambiguous='raise' (GH 7963).

  • Когда .resample() было изменено с немедленной на отложенную операцию, как .groupby() в v0.18.0 мы внедрили совместимость (с FutureWarning), поэтому операции продолжали бы работать. Это теперь полностью удалено, поэтому Resampler больше не будет выполнять операции совместимости вперед (GH 20554)

  • Удалить давно устаревшие axis=None параметр из .replace() (GH 20271)

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

  • Индексаторы на Series или DataFrame больше не создает цикл ссылок (GH 17956)

  • Добавлен ключевой аргумент, cache, в to_datetime() что улучшило производительность преобразования повторяющихся аргументов даты и времени (GH 11665)

  • DateOffset производительность арифметических операций улучшена (GH 18218)

  • Преобразование Series of Timedelta объекты в дни, секунды и т.д. ускорены за счёт векторизации базовых методов (GH 18092)

  • Улучшена производительность .map() с Series/dict входные данные (GH 15081)

  • Переопределенный Timedelta свойства days, seconds и microseconds были удалены, вместо них используются их встроенные версии в Python (GH 18242)

  • Series конструкция уменьшит количество копий входных данных в некоторых случаях (GH 17449)

  • Улучшена производительность Series.dt.date() и DatetimeIndex.date() (GH 18058)

  • Улучшена производительность Series.dt.time() и DatetimeIndex.time() (GH 18461)

  • Улучшена производительность IntervalIndex.symmetric_difference() (GH 18475)

  • Улучшена производительность DatetimeIndex и Series арифметические операции с частотами Business-Month и Business-Quarter (GH 18489)

  • Series() / DataFrame() ограничение автодополнения вкладками до 100 значений для повышения производительности. (GH 18587)

  • Улучшена производительность DataFrame.median() с axis=1 когда bottleneck не установлен (GH 16468)

  • Улучшена производительность MultiIndex.get_loc() для больших индексов, за счет снижения производительности для маленьких (GH 18519)

  • Улучшена производительность MultiIndex.remove_unused_levels() когда нет неиспользуемых уровней, за счет снижения производительности, когда они есть (GH 19289)

  • Улучшена производительность Index.get_loc() для неуникальных индексов (GH 19478)

  • Улучшена производительность попарного .rolling() и .expanding() с .cov() и .corr() операции (GH 17917)

  • Улучшена производительность GroupBy.rank() (GH 15779)

  • Улучшена производительность переменной .rolling() на .min() и .max() (GH 19521)

  • Улучшена производительность GroupBy.ffill() и GroupBy.bfill() (GH 11296)

  • Улучшена производительность GroupBy.any() и GroupBy.all() (GH 15435)

  • Улучшена производительность GroupBy.pct_change() (GH 19165)

  • Улучшена производительность Series.isin() в случае категориальных типов данных (GH 20003)

  • Улучшена производительность getattr(Series, attr) когда Series имеет определенные типы индексов. Это проявлялось в медленном выводе больших Series с DatetimeIndex (GH 19764)

  • Исправлена регрессия производительности для GroupBy.nth() и GroupBy.last() с некоторыми столбцами типа object (GH 19283)

  • Улучшена производительность Categorical.from_codes() (GH 18501)

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

Спасибо всем участникам, которые приняли участие в спринте документации pandas, состоявшемся 10 марта. У нас было около 500 участников из более чем 30 мест по всему миру. Вы заметите, что многие из строки документации API значительно улучшены.

Было слишком много одновременных вкладов, чтобы включить заметку о выпуске для каждого улучшения, но это Поиск на GitHub должно дать вам представление о том, сколько строк документации было улучшено.

Особая благодарность Марк Гарсия для организации спринта. Для получения дополнительной информации прочитайте Пост в блоге NumFOCUS подведение итогов спринта.

  • Исправлено написание «numpy» на «NumPy» и «python» на «Python». (GH 19017)

  • Согласованность при введении примеров кода, используя либо двоеточие, либо точку. Переписаны некоторые предложения для большей ясности, добавлены более динамичные ссылки на функции, методы и классы.GH 18941, GH 18948, GH 18973, GH 19017)

  • Добавлена ссылка на DataFrame.assign() в разделе конкатенации документации по слиянию (GH 18665)

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

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

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

Класс ошибок был внесен в pandas 0.21 с CategoricalDtype что влияет на корректность операций, таких как merge, concat, и индексация при сравнении нескольких неупорядоченных Categorical массивы, которые имеют одинаковые категории, но в другом порядке. Мы настоятельно рекомендуем обновить или вручную выровнять ваши категории перед выполнением этих операций.

  • Ошибка в Categorical.equals возвращает неверный результат при сравнении двух неупорядоченных Categorical массивы с одинаковыми категориями, но в другом порядке (GH 16603)

  • Ошибка в pandas.api.types.union_categoricals() возвращает неправильный результат при работе с неупорядоченными категориальными данными, где категории в другом порядке. Это затрагивает pandas.concat() с категориальными данными (GH 19096).

  • Ошибка в pandas.merge() возвращает неправильный результат при соединении по несортированному Categorical которые имели те же категории, но в другом порядке (GH 19551)

  • Ошибка в CategoricalIndex.get_indexer() возвращая неверный результат, когда target был неупорядоченным Categorical который имел те же категории, что и self но в другом порядке (GH 19551)

  • Ошибка в Index.astype() с категориальным типом данных, где результирующий индекс не преобразуется в CategoricalIndex для всех типов индекса (GH 18630)

  • Ошибка в Series.astype() и Categorical.astype() где существующие категориальные данные не обновляются (GH 10696, GH 18593)

  • Ошибка в Series.str.split() с expand=True некорректно вызывает IndexError на пустых строках (GH 20002).

  • Ошибка в Index конструктор с dtype=CategoricalDtype(...) где categories и ordered не поддерживаются (GH 19032)

  • Ошибка в Series конструктор со скаляром и dtype=CategoricalDtype(...) где categories и ordered не поддерживаются (GH 19565)

  • Ошибка в Categorical.__iter__ не преобразуя в типы Python (GH 19909)

  • Ошибка в pandas.factorize() возвращая уникальные коды для uniques. Теперь возвращает Categorical с тем же типом данных, что и входные данные (GH 19721)

  • Ошибка в pandas.factorize() включая элемент для пропущенных значений в uniques возвращаемое значение (GH 19721)

  • Ошибка в Series.take() с категориальными данными, интерпретируя -1 в indices в качестве маркеров пропущенных значений, а не последнего элемента Series (GH 20664)

Datetimelike#

  • Ошибка в Series.__sub__() вычитание не-наносекундного np.datetime64 объект из Series давал некорректные результаты (GH 7996)

  • Ошибка в DatetimeIndex, TimedeltaIndex сложение и вычитание нульмерных целочисленных массивов давало некорректные результаты (GH 19012)

  • Ошибка в DatetimeIndex и TimedeltaIndex где добавление или вычитание массива из DateOffset объекты либо вызывали исключение (np.array, pd.Index) или передавались некорректно (pd.Series) (GH 18849)

  • Ошибка в Series.__add__() добавление Series с типом данных timedelta64[ns] в учитывающий часовой пояс DatetimeIndex неправильно удаленная информация о часовом поясе (GH 13905)

  • Добавление Period объект в datetime или Timestamp объект теперь правильно вызывает TypeError (GH 17983)

  • Ошибка в Timestamp где сравнение с массивом Timestamp объекты приведут к RecursionError (GH 15183)

  • Ошибка в Series целочисленное деление при работе со скаляром timedelta вызывает исключение (GH 18846)

  • Ошибка в DatetimeIndex где repr не показывал значения времени с высокой точностью в конце дня (например, 23:59:59.999999999) (GH 19030)

  • Ошибка в .astype() в нс-единицы timedelta будет содержать неправильный dtype (GH 19176, GH 19223, GH 12425)

  • Ошибка при вычитании Series из NaT некорректно возвращает NaT (GH 19158)

  • Ошибка в Series.truncate() который вызывает TypeError с монотонным PeriodIndex (GH 17717)

  • Ошибка в pct_change() используя periods и freq возвращали выходные данные разной длины (GH 7292)

  • Ошибка в сравнении DatetimeIndex против None или datetime.date объекты, вызывающие TypeError для == и != сравнения вместо всех-False и все-True, соответственно (GH 19301)

  • Ошибка в Timestamp и to_datetime() где строка, представляющая метку времени, слегка выходящую за границы, будет некорректно округлена вниз вместо вызова исключения OutOfBoundsDatetime (GH 19382)

  • Ошибка в Timestamp.floor() DatetimeIndex.floor() где временные метки далеко в будущем и прошлом округлялись некорректно (GH 19206)

  • Ошибка в to_datetime() где передача даты и времени вне допустимого диапазона с errors='coerce' и utc=True вызовет OutOfBoundsDatetime вместо разбора в NaT (GH 19612)

  • Ошибка в DatetimeIndex и TimedeltaIndex сложение и вычитание, где имя возвращаемого объекта не всегда устанавливалось последовательно. (GH 19744)

  • Ошибка в DatetimeIndex и TimedeltaIndex сложение и вычитание, где операции с массивами numpy вызывали TypeError (GH 19847)

  • Ошибка в DatetimeIndex и TimedeltaIndex где установка freq атрибут не был полностью поддерживаем (GH 20678)

Timedelta#

  • Ошибка в Timedelta.__mul__() где умножение на NaT возвращён NaT вместо вызова TypeError (GH 19819)

  • Ошибка в Series с dtype='timedelta64[ns]' где сложение или вычитание TimedeltaIndex имел результаты, приведенные к dtype='int64' (GH 17250)

  • Ошибка в Series с dtype='timedelta64[ns]' где сложение или вычитание TimedeltaIndex может возвращать Series с некорректным именем (GH 19043)

  • Ошибка в Timedelta.__floordiv__() и Timedelta.__rfloordiv__() деление на многие несовместимые объекты numpy было некорректно разрешено (GH 18846)

  • Ошибка при делении скалярного объекта типа timedelta на TimedeltaIndex выполнил обратную операцию (GH 19125)

  • Ошибка в TimedeltaIndex где деление на Series вернет TimedeltaIndex вместо Series (GH 19042)

  • Ошибка в Timedelta.__add__(), Timedelta.__sub__() где добавление или вычитание np.timedelta64 объект возвращал другой np.timedelta64 вместо Timedelta (GH 19738)

  • Ошибка в Timedelta.__floordiv__(), Timedelta.__rfloordiv__() где работа с Tick объект вызывал TypeError вместо возврата числового значения (GH 19738)

  • Ошибка в Period.asfreq() где периоды около datetime(1, 1, 1) мог быть преобразован неправильно (GH 19643, GH 19834)

  • Ошибка в Timedelta.total_seconds() вызывая ошибки точности, например Timedelta('30S').total_seconds()==30.000000000000004 (GH 19458)

  • Ошибка в Timedelta.__rmod__() где работа с numpy.timedelta64 возвращал timedelta64 объект вместо Timedelta (GH 19820)

  • Умножение TimedeltaIndex by TimedeltaIndex теперь будет вызывать TypeError вместо вызова исключения ValueError в случаях несоответствия длины (GH 19333)

  • Ошибка при индексации TimedeltaIndex с np.timedelta64 объект, который вызывал TypeError (GH 20393)

Часовые пояса#

  • Ошибка при создании Series из массива, содержащего как значения без часового пояса, так и с часовым поясом, приведет к Series , чей тип данных учитывает часовой пояс вместо object (GH 16406)

  • Ошибка при сравнении объектов с учетом часового пояса DatetimeIndex против NaT некорректное возбуждение TypeError (GH 19276)

  • Ошибка в DatetimeIndex.astype() при преобразовании между типами данных с учетом часового пояса и преобразовании из данных с учетом часового пояса в наивные (GH 18951)

  • Ошибка при сравнении DatetimeIndex, который не смог вызвать TypeError при попытке сравнить объекты datetime с часовым поясом и без часового пояса (GH 18162)

  • Ошибка в локализации наивной строки даты-времени в Series конструктор с datetime64[ns, tz] тип данных (GH 174151)

  • Timestamp.replace() matplotlibGH 18319)

  • Ошибка в tz-aware DatetimeIndex где сложение/вычитание с TimedeltaIndex или массив с dtype='timedelta64[ns]' было некорректным (GH 17558)

  • Ошибка в DatetimeIndex.insert() где вставка NaT в индекс, учитывающий часовой пояс, неправильно вызывало (GH 16357)

  • Ошибка в DataFrame конструктор, где Datetimeindex с учетом часового пояса и заданное имя столбца приведут к пустому DataFrame (GH 19157)

  • Ошибка в Timestamp.tz_localize() где локализация временной метки около минимальных или максимальных допустимых значений могла вызвать переполнение и вернуть временную метку с некорректным наносекундным значением (GH 12677)

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

  • Ошибка в DataFrame.diff() который вызвал IndexError с значениями, учитывающими часовой пояс (GH 18578)

  • Ошибка в melt() который преобразовывал типы данных с учётом часового пояса в типы без учёта часового пояса (GH 15785)

  • Ошибка в Dataframe.count() который вызвал ValueError, если Dataframe.dropna() был вызван для одного столбца со значениями с учетом часового пояса. (GH 13407)

Смещения#

  • Ошибка в WeekOfMonth и Week где сложение и вычитание выполнялись некорректно (GH 18510, GH 18672, GH 18864)

  • Ошибка в WeekOfMonth и LastWeekOfMonth где аргументы по умолчанию для конструктора вызвали ValueError (GH 19142)

  • Ошибка в FY5253Quarter, LastWeekOfMonth где поведение отката и продвижения было несогласованным с поведением сложения и вычитания (GH 18854)

  • Ошибка в FY5253 где datetime сложение и вычитание увеличивались некорректно для дат в конце года, но не нормализованных до полуночи (GH 18854)

  • Ошибка в FY5253 где date offsets могли некорректно вызывать AssertionError в арифметических операциях (GH 14774)

Числовой#

  • Ошибка в Series конструктор с int или float списком, где указание dtype=str, dtype='str' или dtype='U' не удалось преобразовать элементы данных в строки (GH 16605)

  • Ошибка в Index методы умножения и деления, которые работали с Series вернет Index объект вместо Series объект (GH 19042)

  • Ошибка в DataFrame конструктор, в котором данные, содержащие очень большие положительные или очень большие отрицательные числа, вызывали OverflowError (GH 18584)

  • Ошибка в Index конструктор с dtype='uint64' где целочисленные float не приводились к UInt64Index (GH 18400)

  • Ошибка в DataFrame гибкая арифметика (например, df.add(other, fill_value=foo)) с fill_value кроме None не удалось вызвать NotImplementedError в крайних случаях, когда либо фрейм, либо other имеет нулевую длину (GH 19522)

  • Умножение и деление числовых типов данных Index объекты с timedelta-подобными скалярами возвращают TimedeltaIndex вместо вызова исключения TypeError (GH 19333)

  • Ошибка, где NaN возвращалось вместо 0 в Series.pct_change() и DataFrame.pct_change() когда fill_method не является None (GH 19873)

Строки#

  • Ошибка в Series.str.get() со словарем в значениях и индексом не в ключах, вызывая KeyError (GH 20671)

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

  • Ошибка в Index создание из списка кортежей смешанного типа (GH 18505)

  • Ошибка в Index.drop() при передаче списка, содержащего как кортежи, так и не-кортежи (GH 18304)

  • Ошибка в DataFrame.drop(), Panel.drop(), Series.drop(), Index.drop() где нет KeyError возникает при удалении несуществующего элемента из оси, содержащей дубликаты (GH 19186)

  • Ошибка при индексировании дата-времени Index который поднял ValueError вместо IndexError (GH 18386).

  • Index.to_series() теперь принимает index и name kwargs (GH 18699)

  • DatetimeIndex.to_series() теперь принимает index и name kwargs (GH 18699)

  • Ошибка при индексации нескалярного значения из Series имеющие неуникальные Index вернет значение в плоском виде (GH 17610)

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

  • Исправлена несогласованность в .ix между списком и скалярными ключами, когда индекс имеет целочисленный тип и не включает нужные ключи (GH 20753)

  • Ошибка в __setitem__ при индексации DataFrame с двумерным логическим массивом NumPy (GH 18582)

  • Ошибка в str.extractall когда совпадений не найдено, возвращается пустой Index возвращалось вместо соответствующего MultiIndex (GH 19034)

  • Ошибка в IntervalIndex где пустые и чисто NA данные строились непоследовательно в зависимости от метода построения (GH 18421)

  • Ошибка в IntervalIndex.symmetric_difference() где симметричная разность с не-IntervalIndex не вызывал (GH 18475)

  • Ошибка в IntervalIndex где операции над множествами, возвращающие пустое IntervalIndex имел неправильный dtype (GH 19101)

  • Ошибка в DataFrame.drop_duplicates() где нет KeyError возникает при передаче столбцов, которых нет в DataFrame (GH 19726)

  • Ошибка в Index конструкторы подклассов, которые игнорируют неожиданные аргументы ключевых слов (GH 19348)

  • Ошибка в Index.difference() при вычислении разницы Index с самим собой (GH 20040)

  • Ошибка в DataFrame.first_valid_index() и DataFrame.last_valid_index() при наличии целых строк NaN среди значений (GH 20499).

  • Ошибка в IntervalIndex где некоторые операции индексирования не поддерживались для перекрывающихся или немонотонных uint64 данные (GH 20636)

  • Ошибка в Series.is_unique где показывается лишний вывод в stderr, если Series содержит объекты с __ne__ определено (GH 20661)

  • Ошибка в .loc присваивание с однозначным списком неправильно присваивает как список (GH 19474)

  • Ошибка в частичном строковом индексировании на Series/DataFrame с монотонно убывающим DatetimeIndex (GH 19362)

  • Ошибка при выполнении операций на месте на DataFrame с дублирующимся Index (GH 17105)

  • Ошибка в IntervalIndex.get_loc() и IntervalIndex.get_indexer() при использовании с IntervalIndex содержащий один интервал (GH 17284, GH 20921)

  • Ошибка в .loc с uint64 индексатор (GH 20722)

MultiIndex#

  • Ошибка в MultiIndex.__contains__() где нетуплевые ключи возвращали бы True даже если они были удалены (GH 19027)

  • Ошибка в MultiIndex.set_labels() что может привести к приведению типов (и потенциальному обрезанию) новых меток, если level аргумент не равен 0 или списку вида [0, 1, …] (GH 19057)

  • Ошибка в MultiIndex.get_level_values() что вернуло бы недопустимый индекс на уровне целых чисел с пропущенными значениями (GH 17924)

  • Ошибка в MultiIndex.unique() при вызове на пустом MultiIndex (GH 20568)

  • Ошибка в MultiIndex.unique() что не сохранит имена уровней (GH 20570)

  • Ошибка в MultiIndex.remove_unused_levels() который заполнит значения nan (GH 18417)

  • Ошибка в MultiIndex.from_tuples() что не удавалось обработать заархивированные кортежи в python3 (GH 18434)

  • Ошибка в MultiIndex.get_loc() что не позволило бы автоматически преобразовывать значения между float и int (GH 18818, GH 15994)

  • Ошибка в MultiIndex.get_loc() что привело бы к приведению булевых меток к целочисленным (GH 19086)

  • Ошибка в MultiIndex.get_loc() что не позволит найти ключи, содержащие NaN (GH 18485)

  • Ошибка в MultiIndex.get_loc() в больших MultiIndex, завершалось ошибкой, когда уровни имели разные типы данных (GH 18520)

  • Ошибка в индексации, когда вложенные индексаторы, содержащие только массивы numpy, обрабатываются некорректно (GH 19686)

Ввод-вывод#

  • read_html() теперь перематывает доступные для поиска объекты ввода-вывода после неудачного разбора, прежде чем попытаться разобрать с новым парсером. Если парсер выдает ошибку и объект недоступен для поиска, выводится информативное сообщение об ошибке, предлагающее использовать другой парсер (GH 17975)

  • DataFrame.to_html() теперь имеет опцию добавления идентификатора к ведущему тег (GH 8496)

  • Ошибка в read_msgpack() с несуществующим файлом передается в Python 2 (GH 15296)

  • Ошибка в read_csv() где MultiIndex с дублирующимися столбцами не было соответствующим образом изменено (GH 18062)

  • Ошибка в read_csv() где пропущенные значения не обрабатывались должным образом, когда keep_default_na=False со словарём na_values (GH 19227)

  • Ошибка в read_csv() вызывая повреждение кучи на 32-битных архитектурах с обратным порядком байтов (GH 20785)

  • Ошибка в read_sas() где файл с 0 переменными выдавал AttributeError неправильно. Теперь выдаёт EmptyDataError (GH 18184)

  • Ошибка в DataFrame.to_latex() где пары фигурных скобок, предназначенные служить невидимыми заполнителями, были экранированы (GH 18667)

  • Ошибка в DataFrame.to_latex() где NaN в MultiIndex вызовет IndexError или некорректный вывод (GH 14249)

  • Ошибка в DataFrame.to_latex() где нестроковое имя уровня индекса привело бы к AttributeError (GH 19981)

  • Ошибка в DataFrame.to_latex() где комбинация имени индекса и index_names=False опция приведет к некорректному выводу (GH 18326)

  • Ошибка в DataFrame.to_latex() где MultiIndex с пустой строкой в качестве имени привело бы к некорректному выводу (GH 18669)

  • Ошибка в DataFrame.to_latex() где отсутствующие пробелы вызывали неправильное экранирование и создавали невалидный latex в некоторых случаях (GH 20859)

  • Ошибка в read_json() где большие числовые значения вызывали OverflowError (GH 18842)

  • Ошибка в DataFrame.to_parquet() где исключение вызывалось, если место записи - S3 (GH 19134)

  • Interval теперь поддерживается в DataFrame.to_excel() для всех типов файлов Excel (GH 19242)

  • Timedelta теперь поддерживается в DataFrame.to_excel() для всех типов файлов Excel (GH 19242, GH 9155, GH 19900)

  • Ошибка в pandas.io.stata.StataReader.value_labels() вызов AttributeError при вызове на очень старых файлах. Теперь возвращает пустой словарь (GH 19417)

  • Ошибка в read_pickle() при распаковке объектов с TimedeltaIndex или Float64Index созданные с pandas до версии 0.20 (GH 19939)

  • Ошибка в pandas.io.json.json_normalize() где подзаписи не нормализуются должным образом, если значения любых подзаписей имеют тип NoneType (GH 20030)

  • Ошибка в usecols параметр в read_csv() где ошибка не возникает корректно при передаче строки. (GH 20529)

  • Ошибка в HDFStore.keys() при чтении файла с символической ссылкой вызывает исключение (GH 20523)

  • Ошибка в HDFStore.select_column() где ключ, который не является допустимым хранилищем, вызывал AttributeError вместо KeyError (GH 17912)

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

    • Улучшенное сообщение об ошибке при попытке построить график, но matplotlib не установлен (GH 19810).

    • DataFrame.plot() теперь вызывает ValueError когда x или y аргумент неправильно сформирован (GH 18671)

    • Ошибка в DataFrame.plot() когда x и y аргументы, заданные как позиции, вызывали некорректные ссылки на столбцы для линейных, столбчатых и площадных графиков (GH 20056)

    • Ошибка в форматировании меток делений с datetime.time() и доли секунды (GH 18478).

    • Series.plot.kde() предоставил доступ к аргументам ind и bw_method в строке документации (GH 18461). Аргумент ind теперь также может быть целым числом (количество точек выборки).

    • DataFrame.plot() теперь поддерживает несколько столбцов для y аргумент (GH 19699)

    GroupBy/resample/rolling#

    • Ошибка при группировке по одному столбцу и агрегировании с классом, таким как list или tuple (GH 18079)

    • Исправлена регрессия в DataFrame.groupby() который не выдавал ошибку при вызове с ключом-кортежем, отсутствующим в индексе (GH 18798)

    • Ошибка в DataFrame.resample() который молча игнорировал неподдерживаемые (или опечатанные) опции для label, closed и convention (GH 19303)

    • Ошибка в DataFrame.groupby() где кортежи интерпретировались как списки ключей, а не как ключи (GH 17979, GH 18249)

    • Ошибка в DataFrame.groupby() где агрегация по first/last/min/max вызывал потерю точности временных меток (GH 19526)

    • Ошибка в DataFrame.transform() где определенные агрегирующие функции некорректно приводились к соответствию с dtype(s) сгруппированных данных (GH 19200)

    • Ошибка в DataFrame.groupby() передача on= kwarg, и последующее использование .apply() (GH 17813)

    • Ошибка в DataFrame.resample().aggregate не вызывал KeyError при агрегации несуществующего столбца (GH 16766, GH 19566)

    • Ошибка в DataFrameGroupBy.cumsum() и DataFrameGroupBy.cumprod() когда skipna был передан (GH 19806)

    • Ошибка в DataFrame.resample() которая удалила информацию о часовом поясе (GH 13238)

    • Ошибка в DataFrame.groupby() где преобразования с использованием np.all и np.any вызывали ValueError (GH 20653)

    • Ошибка в DataFrame.resample() где ffill, bfill, pad, backfill, fillna, interpolate, и asfreq игнорировали loffset. (GH 20744)

    • Ошибка в DataFrame.groupby() при применении функции со смешанными типами данных, когда пользовательская функция может завершиться ошибкой на колонке группировки (GH 20949)

    • Ошибка в DataFrameGroupBy.rolling().apply() где операции выполняются против связанного DataFrameGroupBy объект может повлиять на включение сгруппированных элементов в результат (GH 14013)

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

    • Ошибка, при которой создание SparseDataFrame из плотного Series или неподдерживаемый тип вызывал неконтролируемое исключение (GH 19374)

    • Ошибка в SparseDataFrame.to_csv вызывая исключение (GH 19384)

    • Ошибка в SparseSeries.memory_usage что вызывало ошибку сегментации при доступе к неразреженным элементам (GH 19368)

    • Ошибка при построении SparseArray: если data является скаляром и index если определен, он будет преобразован в float64 независимо от dtype скаляра. (GH 19163)

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

    • Ошибка в DataFrame.merge() где ссылка на CategoricalIndex по имени, где by аргумент будет KeyError (GH 20777)

    • Ошибка в DataFrame.stack() который не может отсортировать смешанные типы уровней в Python 3 (GH 18310)

    • Ошибка в DataFrame.unstack() который преобразует int в float, если columns является MultiIndex с неиспользуемыми уровнями (GH 17845)

    • Ошибка в DataFrame.unstack() который вызывает ошибку, если index является MultiIndex с неиспользуемыми метками на неуложенном уровне (GH 18562)

    • Исправлено создание Series из dict содержащий NaN в качестве ключа (GH 18480)

    • Исправлено создание DataFrame из dict содержащий NaN в качестве ключа (GH 18455)

    • Отключено создание Series где len(index) > len(data) = 1, что ранее транслировало элемент данных, а теперь вызывает ValueError (GH 18819)

    • Подавлена ошибка при построении DataFrame из dict содержащие скалярные значения, когда соответствующие ключи не включены в переданный индекс (GH 18600)

    • Исправлено (изменено с object to float64) тип данных DataFrame инициализирован с осями, без данных и dtype=int (GH 19646)

    • Ошибка в Series.rank() где Series содержащий NaT изменяет Series inplace (GH 18521)

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

    • Ошибка в DataFrame.pivot_table() который не работает, когда aggfunc аргумент имеет тип string. Поведение теперь согласовано с другими методами, такими как agg и apply (GH 18713)

    • Ошибка в DataFrame.merge() в котором слияние с использованием Index объектов как векторов вызывало исключение (GH 19038)

    • Ошибка в DataFrame.stack(), DataFrame.unstack(), Series.unstack() которые не возвращали подклассы (GH 15563)

    • Ошибка в сравнениях часовых поясов, проявляющаяся как преобразование индекса в UTC в .concat() (GH 18523)

    • Ошибка в concat() при объединении разреженных и плотных серий возвращается только SparseDataFrame. Должен быть DataFrame. (GH 18914, GH 18686, и GH 16874)

    • Улучшено сообщение об ошибке для DataFrame.merge() когда нет общего ключа слияния (GH 19427)

    • Ошибка в DataFrame.join() который выполняет outer вместо left объединять при вызове с несколькими DataFrame и некоторые имеют неуникальные индексы (GH 19624)

    • Series.rename() теперь принимает axis в качестве аргумента ключевого слова (GH 18589)

    • Ошибка в rename() где Index кортежей одинаковой длины был преобразован в MultiIndex (GH 19497)

    • Сравнения между Series и Index вернет Series с неправильным именем, игнорируя Indexатрибут name (GH 19582)

    • Ошибка в qcut() где данные datetime и timedelta с NaT присутствие вызывало ValueError (GH 19768)

    • Ошибка в DataFrame.iterrows(), который определяет строки, не соответствующие ISO8601 в даты и время (GH 19671)

    • Ошибка в Series конструктор с Categorical где ValueError не вызывается, когда задан индекс другой длины (1.#IND)

    • Ошибка в DataFrame.astype() где метаданные столбцов теряются при преобразовании в категориальный или словарь типов данных (GH 19920)

    • Ошибка в cut() и qcut() где информация о часовом поясе была удалена (GH 19872)

    • Ошибка в Series конструктор с dtype=str, ранее возникавшая в некоторых случаях (GH 19853)

    • Ошибка в get_dummies(), и select_dtypes(), где дублирующиеся имена столбцов вызывали некорректное поведение (GH 20848)

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

    • Ошибка в concat() что вызывает ошибку при объединении DataFrame с учетом часового пояса и DataFrame с полностью значениями NaT (GH 12396)

    • Ошибка в concat() который вызывает ошибку при конкатенации пустых серий с учетом часового пояса (GH 18447)

    Другие#

    • Улучшенное сообщение об ошибке при попытке использовать ключевое слово Python в качестве идентификатора в numexpr поддерживаемый запрос (GH 18221)

    • Ошибка при доступе к pandas.get_option(), что вызывало KeyError вместо OptionError при поиске несуществующего ключа опции в некоторых случаях (GH 19789)

    • Ошибка в testing.assert_series_equal() и testing.assert_frame_equal() для Series или DataFrames с различными данными в формате unicode (GH 20503)

    Участники#

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

    • Aaron Critchley

    • AbdealiJK +

    • Adam Hooper +

    • Albert Villanova del Moral

    • Devjeet Roy +

    • Alejandro Hohmann +

    • Alex Rychyk

    • Alexander Buchkovsky

    • Alexander Lenail +

    • Александр Майкл Шаде

    • Aly Sivji +

    • Андреас Кёльтрингер +

    • Andrew

    • Andrew Bui +

    • András Novoszáth +

    • Andy Craze +

    • Andy R. Terrel

    • Anh Le +

    • Anil Kumar Pallekonda +

    • Antoine Pitrou +

    • Antonio Linde +

    • Antonio Molina +

    • Antonio Quinonez +

    • Armin Varshokar +

    • Artem Bogachev +

    • Avi Sen +

    • Azeez Oluwafemi +

    • Ben Auffarth +

    • Бернхард Тиль +

    • Bhavesh Poddar +

    • BielStela +

    • Blair +

    • Bob Haffner

    • Brett Naul +

    • Brock Mendel

    • Bryce Guinta +

    • Carlos Eduardo Moreira dos Santos +

    • Carlos García Márquez +

    • Carol Willing

    • Cheuk Ting Ho +

    • Chitrank Dixit +

    • Chris

    • Chris Burr +

    • Chris Catalfo +

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

    • Christian Chwala +

    • Cihan Ceyhan +

    • Clemens Brunner

    • Colin +

    • Cornelius Riemenschneider

    • Crystal Gong +

    • DaanVanHauwermeiren

    • Dan Dixey +

    • Daniel Frank +

    • Daniel Garrido +

    • Daniel Sakuma +

    • DataOmbudsman +

    • Дэйв Хиршфельд

    • Dave Lewis +

    • David Adrián Cañones Castellano +

    • David Arcos +

    • David C Hall +

    • David Fischer

    • David Hoese +

    • David Lutz +

    • David Polo +

    • David Stansby

    • Dennis Kamau +

    • Dillon Niederhut

    • Dimitri +

    • Dr. Irv

    • Dror Atariah

    • Eric Chea +

    • Eric Kisslinger

    • Эрик О. ЛЕБИГО (EOL) +

    • FAN-GOD +

    • Fabian Retkowski +

    • Fer Sar +

    • Gabriel de Maeztu +

    • Джанпаоло Макарио +

    • Giftlin Rajaiah

    • Gilberto Olimpio +

    • Gina +

    • Gjelt +

    • Graham Inggs +

    • Grant Roch

    • Grant Smith +

    • Grzegorz Konefał +

    • Guilherme Beltramini

    • HagaiHargil +

    • Hamish Pitkeathly +

    • Hammad Mashkoor +

    • Hannah Ferchland +

    • Hans

    • Haochen Wu +

    • Хиссаши Роча +

    • Иэн Барр +

    • Ибрагим Шараф ЭльДен +

    • Ignasi Fosch +

    • Igor Conrado Alves de Lima +

    • Igor Shelvinskyi +

    • Imanflow +

    • Ingolf Becker

    • Israel Saeta Pérez

    • Ива Коевска +

    • Якуб Новацки +

    • Jan F-F +

    • Jan Koch +

    • Ян Веркманн

    • Janelle Zoutkamp +

    • Jason Bandlow +

    • Jaume Bonet +

    • Jay Alammar +

    • Jeff Reback

    • JennaVergeynst

    • Jimmy Woo +

    • Jing Qiang Goh +

    • Иоахим Вагнер +

    • Joan Martin Miralles +

    • Joel Nothman

    • Джоун Парк +

    • John Cant +

    • Johnny Metz +

    • Jon Mease

    • Йонас Шульце +

    • Jongwony +

    • Jordi Contestí +

    • Joris Van den Bossche

    • Жозе Ф. Р. Фонсека +

    • Джовикс +

    • Julio Martinez +

    • Jörg Döpfert

    • KOBAYASHI Ittoku +

    • Kate Surta +

    • Kenneth +

    • Кевин Куль

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

    • Krzysztof Chomski

    • Ksenia +

    • Ksenia Bobrova +

    • Kunal Gosar +

    • Kurtis Kerstein +

    • Kyle Barron +

    • Laksh Arora +

    • Laurens Geffert +

    • Leif Walsh

    • Liam Marshall +

    • Liam3851 +

    • Licht Takeuchi

    • Лиудмила +

    • Ludovico Russo +

    • Mabel Villalba +

    • Manan Pal Singh +

    • Manraj Singh

    • Marc +

    • Марк Гарсия

    • Marco Hemken +

    • Мария дель Мар Бибилони +

    • Mario Corchero +

    • Mark Woodbridge +

    • Martin Journois +

    • Mason Gallo +

    • Matias Heikkilä +

    • Мэтт Бреймер-Хейс

    • Matt Kirk +

    • Matt Maybeno +

    • Matthew Kirk +

    • Мэтью Роклин +

    • Мэтью Рёшке

    • Matthias Bussonnier +

    • Max Mikhaylov +

    • Maxim Veksler +

    • Maximilian Roos

    • Максимилиано Греко +

    • Michael Penkov

    • Michael Röttger +

    • Michael Selik +

    • Майкл Васком

    • Запрос столбцов DataFrame с помощью логического выражения.

    • Mike Kutzma +

    • Мин Ли +

    • Митар +

    • Mitch Negus +

    • Montana Low +

    • Мориц Мюнст +

    • Mortada Mehyar

    • Myles Braithwaite +

    • Nate Yoder

    • Nicholas Ursa +

    • Nick Chmura

    • Nikos Karagiannakis +

    • Nipun Sadvilkar +

    • Nis Martensen +

    • Noah +

    • Noémi Éltető +

    • Olivier Bilodeau +

    • Ondrej Kokes +

    • Onno Eberhard +

    • Paul Ganssle +

    • Пол Маннино +

    • Пол Риди

    • Paulo Roberto de Oliveira Castro +

    • Pepe Flores +

    • Peter Hoffmann

    • Фил Нго +

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

    • Pranav Suri +

    • Priyanka Ojha +

    • Pulkit Maloo +

    • README Bot +

    • Ray Bell +

    • Риккардо Мальоккетти +

    • Ridhwan Luthra +

    • Роберт Мейер

    • Robin

    • Robin Kiplang’at +

    • Rohan Pandit +

    • Rok Mihevc +

    • Rouz Azari

    • Ryszard T. Kaleta +

    • Sam Cohan

    • Сэм Фу

    • Samir Musali +

    • Samuel Sinayoko +

    • Sangwoong Yoon

    • SarahJessica +

    • Sharad Vijalapuram +

    • Shubham Chaudhary +

    • SiYoungOh +

    • Sietse Brouwer

    • Simone Basso +

    • Стефания Дельпрете +

    • Stefano Cianciulli +

    • Stephen Childs +

    • StephenVoland +

    • Stijn Van Hoey +

    • Sven

    • Talitha Pumar +

    • Tarbo Fukazawa +

    • Ted Petrou +

    • Thomas A Caswell

    • Тим Хоффманн +

    • Tim Swast

    • Tom Augspurger

    • Tommy +

    • Tulio Casagrande +

    • Tushar Gupta +

    • Tushar Mittal +

    • Upkar Lidder +

    • Victor Villas +

    • Vince W +

    • Vinícius Figueiredo +

    • Vipin Kumar +

    • WBare

    • Wenhuan +

    • Wes Turner

    • William Ayd

    • Уилсон Линь +

    • Xbar

    • Yaroslav Halchenko

    • Yee Mey

    • Yeongseon Choe +

    • Yian +

    • Yimeng Zhang

    • Чжу Баохэ +

    • Цзихао Чжао +

    • adatasetaday +

    • akielbowicz +

    • akosel +

    • alinde1 +

    • amuta +

    • bolkedebruin

    • cbertinato

    • cgohlke

    • charlie0389 +

    • chris-b1

    • csfarkas +

    • dajcs +

    • deflatSOCO +

    • derestle-htwg

    • дискорд

    • dmanikowski-reef +

    • donK23 +

    • elrubio +

    • fivemok +

    • fjdiod

    • fjetter +

    • froessler +

    • gabrielclow

    • gfyoung

    • ghasemnaddaf

    • h-vetinari +

    • himanshu awasthi +

    • ignamv +

    • jayfoad +

    • jazzmuesli +

    • jbrockmendel

    • jen w +

    • jjames34 +

    • joaoavf +

    • joders +

    • jschendel

    • juan huguet +

    • l736x +

    • luzpaz +

    • mdeboc +

    • miguelmorin +

    • miker985

    • miquelcamprodon +

    • orereta +

    • ottiP +

    • peterpanmj +

    • rafarui +

    • raph-m +

    • readyready15728 +

    • rmihael +

    • samghelms +

    • scriptomation +

    • sfoo +

    • stefansimik +

    • stonebig

    • tmnhat2001 +

    • tomneep +

    • topper-123

    • tv3141 +

    • verakai +

    • xpvpc +

    • zhanghui +