Что нового в 0.24.0 (25 января 2019)#

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

Серия релизов 0.24.x будет последней, поддерживающей Python 2. Будущие релизы функций будут поддерживать только Python 3. См. Удаление Python 2.7 для получения дополнительной информации.

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

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

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

Это изменения в pandas 0.24.0. См. Примечания к выпуску для полного списка изменений, включая другие версии pandas.

Улучшения#

Опциональная поддержка целочисленных NA#

pandas получил возможность хранить целочисленные типы данных с пропущенными значениями. Эта долгожданная функция реализована с использованием расширенные типы.

Примечание

IntegerArray в настоящее время является экспериментальным. Его API или реализация могут измениться без предупреждения.

Мы можем создать Series с указанным dtype. Строка dtype Int64 является pandas ExtensionDtype. Указание списка или массива с использованием традиционного маркера пропущенных значений np.nan будет выводить целочисленный тип данных. Отображение Series также будет использовать NaN для обозначения пропущенных значений в строковых выводах. (GH 20700, GH 20747, GH 22441, GH 21789, GH 22346)

In [1]: s = pd.Series([1, 2, np.nan], dtype='Int64')

In [2]: s
Out[2]: 
0       1
1       2
2    
Length: 3, dtype: Int64

Операции над этими типами данных будут распространяться NaN как и другие операции pandas.

# arithmetic
In [3]: s + 1
Out[3]: 
0       2
1       3
2    
Length: 3, dtype: Int64

# comparison
In [4]: s == 1
Out[4]: 
0     True
1    False
2     
Length: 3, dtype: boolean

# indexing
In [5]: s.iloc[1:3]
Out[5]: 
1       2
2    
Length: 2, dtype: Int64

# operate with other dtypes
In [6]: s + s.iloc[1:3].astype('Int8')
Out[6]: 
0    
1       4
2    
Length: 3, dtype: Int64

# coerce when needed
In [7]: s + 0.01
Out[7]: 
0    1.01
1    2.01
2    
Length: 3, dtype: Float64

Эти типы данных могут работать как часть DataFrame.

In [8]: df = pd.DataFrame({'A': s, 'B': [1, 1, 3], 'C': list('aab')})

In [9]: df
Out[9]: 
      A  B  C
0     1  1  a
1     2  1  a
2    3  b

[3 rows x 3 columns]

In [10]: df.dtypes
Out[10]: 
A     Int64
B     int64
C    object
Length: 3, dtype: object

Эти типы данных могут быть объединены, преобразованы и приведены.

In [11]: pd.concat([df[['A']], df[['B', 'C']]], axis=1).dtypes
Out[11]: 
A     Int64
B     int64
C    object
Length: 3, dtype: object

In [12]: df['A'].astype(float)
Out[12]: 
0    1.0
1    2.0
2    NaN
Name: A, Length: 3, dtype: float64

Операции редукции и группировки, такие как sum работа.

In [13]: df.sum()
Out[13]: 
A      3
B      5
C    aab
Length: 3, dtype: object

In [14]: df.groupby('B').A.sum()
Out[14]: 
B
1    3
3    0
Name: A, Length: 2, dtype: Int64

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

Поддержка Integer NA в настоящее время использует версию dtype с заглавной буквой, например. Int8 по сравнению с традиционным int8. Это может быть изменено в будущем.

См. Допускающий значения null целочисленный тип данных подробнее.

Доступ к значениям в Series или Index#

Series.array и Index.array были добавлены для извлечения массива, лежащего в основе Series или Index. (GH 19954, GH 23623)

In [15]: idx = pd.period_range('2000', periods=4)

In [16]: idx.array
Out[16]: 

['2000-01-01', '2000-01-02', '2000-01-03', '2000-01-04']
Length: 4, dtype: period[D]

In [17]: pd.Series(idx).array
Out[17]: 

['2000-01-01', '2000-01-02', '2000-01-03', '2000-01-04']
Length: 4, dtype: period[D]

Исторически это делалось с помощью series.values, но с .values было неясно, будет ли возвращаемое значение фактическим массивом, каким-то его преобразованием или одним из пользовательских массивов pandas (как Categorical). Например, с PeriodIndex, .values генерирует новый ndarray объектов периода каждый раз.

In [18]: idx.values
Out[18]: 
array([Period('2000-01-01', 'D'), Period('2000-01-02', 'D'),
       Period('2000-01-03', 'D'), Period('2000-01-04', 'D')], dtype=object)

In [19]: id(idx.values)
Out[19]: 140203905696464

In [20]: id(idx.values)
Out[20]: 140204511501296

Если вам нужен настоящий массив NumPy, используйте Series.to_numpy() или Index.to_numpy().

In [21]: idx.to_numpy()
Out[21]: 
array([Period('2000-01-01', 'D'), Period('2000-01-02', 'D'),
       Period('2000-01-03', 'D'), Period('2000-01-04', 'D')], dtype=object)

In [22]: pd.Series(idx).to_numpy()
Out[22]: 
array([Period('2000-01-01', 'D'), Period('2000-01-02', 'D'),
       Period('2000-01-03', 'D'), Period('2000-01-04', 'D')], dtype=object)

Для Series и Indexes, поддерживаемых обычными массивами NumPy, Series.array вернет новый arrays.PandasArray, который является тонкой (без копирования) оболочкой вокруг numpy.ndarray. PandasArray сам по себе не особенно полезен, но предоставляет тот же интерфейс, что и любой массив расширений, определенный в pandas или сторонней библиотекой.

In [23]: ser = pd.Series([1, 2, 3])

In [24]: ser.array
Out[24]: 

[1, 2, 3]
Length: 3, dtype: int64

In [25]: ser.to_numpy()
Out[25]: array([1, 2, 3])

Мы не удалили и не объявили устаревшими Series.values или DataFrame.values, но мы настоятельно рекомендуем использовать .array или .to_numpy() вместо этого.

См. Типы данных и Атрибуты и исходные данные подробнее.

pandas.array: новый метод верхнего уровня для создания массивов#

Новый метод верхнего уровня array() добавлен для создания одномерных массивов (GH 22860). Это может быть использовано для создания любого расширенный массив, включая массивы расширений, зарегистрированные сторонние библиотеки. См. документация по типам данных подробнее о массивах расширений.

In [26]: pd.array([1, 2, np.nan], dtype='Int64')
Out[26]: 

[1, 2, ]
Length: 3, dtype: Int64

In [27]: pd.array(['a', 'b', 'c'], dtype='category')
Out[27]: 
['a', 'b', 'c']
Categories (3, object): ['a', 'b', 'c']

Передача данных, для которых нет выделенного типа расширения (например, float, integer и т.д.) вернет новый arrays.PandasArray, что является тонкой (без копирования) оболочкой вокруг numpy.ndarray который удовлетворяет интерфейсу расширенного массива pandas.

In [28]: pd.array([1, 2, 3])
Out[28]: 

[1, 2, 3]
Length: 3, dtype: Int64

Само по себе, PandasArray не является очень полезным объектом. Но если вам нужно написать низкоуровневый код, который работает универсально для любого ExtensionArray, PandasArray удовлетворяет этой потребности.

Обратите внимание, что по умолчанию, если нет dtype указан, тип данных возвращаемого массива выводится из данных. В частности, обратите внимание, что первый пример [1, 2, np.nan] вернул бы массив с плавающей точкой, поскольку NaN является числом с плавающей точкой.

In [29]: pd.array([1, 2, np.nan])
Out[29]: 

[1, 2, ]
Length: 3, dtype: Int64

Хранение данных Interval и Period в Series и DataFrame#

Interval и Period данные теперь могут храниться в Series или DataFrame, в дополнение к IntervalIndex и PeriodIndex как и ранее (GH 19453, GH 22862).

In [30]: ser = pd.Series(pd.interval_range(0, 5))

In [31]: ser
Out[31]: 
0    (0, 1]
1    (1, 2]
2    (2, 3]
3    (3, 4]
4    (4, 5]
Length: 5, dtype: interval

In [32]: ser.dtype
Out[32]: interval[int64, right]

Для периодов:

In [33]: pser = pd.Series(pd.period_range("2000", freq="D", periods=5))

In [34]: pser
Out[34]: 
0    2000-01-01
1    2000-01-02
2    2000-01-03
3    2000-01-04
4    2000-01-05
Length: 5, dtype: period[D]

In [35]: pser.dtype
Out[35]: period[D]

Ранее они приводились к массиву NumPy с типом object. В целом, это должно привести к лучшей производительности при хранении массива интервалов или периодов в Series или столбец DataFrame.

Используйте Series.array для извлечения базового массива интервалов или периодов из Series:

In [36]: ser.array
Out[36]: 

[(0, 1], (1, 2], (2, 3], (3, 4], (4, 5]]
Length: 5, dtype: interval[int64, right]

In [37]: pser.array
Out[37]: 

['2000-01-01', '2000-01-02', '2000-01-03', '2000-01-04', '2000-01-05']
Length: 5, dtype: period[D]

Они возвращают экземпляр arrays.IntervalArray или arrays.PeriodArrayновые массивы расширений, которые поддерживают интервальные и периодические данные.

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

Для обратной совместимости, Series.values продолжает возвращать массив NumPy объектов для данных Interval и Period. Рекомендуем использовать Series.array когда вам нужен массив данных, хранящихся в Series, и Series.to_numpy() когда вы знаете, что вам нужен массив NumPy.

См. Типы данных и Атрибуты и исходные данные подробнее.

Объединение с двумя мультииндексами#

DataFrame.merge() и DataFrame.join() теперь можно использовать для соединения мультииндексированных Dataframe экземпляры на перекрывающихся уровнях индекса (GH 6360)

См. Объединение, соединение и конкатенация раздел документации.

In [38]: index_left = pd.MultiIndex.from_tuples([('K0', 'X0'), ('K0', 'X1'),
   ....:                                        ('K1', 'X2')],
   ....:                                        names=['key', 'X'])
   ....: 

In [39]: left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
   ....:                      'B': ['B0', 'B1', 'B2']}, index=index_left)
   ....: 

In [40]: index_right = pd.MultiIndex.from_tuples([('K0', 'Y0'), ('K1', 'Y1'),
   ....:                                         ('K2', 'Y2'), ('K2', 'Y3')],
   ....:                                         names=['key', 'Y'])
   ....: 

In [41]: right = pd.DataFrame({'C': ['C0', 'C1', 'C2', 'C3'],
   ....:                       'D': ['D0', 'D1', 'D2', 'D3']}, index=index_right)
   ....: 

In [42]: left.join(right)
Out[42]: 
            A   B   C   D
key X  Y                 
K0  X0 Y0  A0  B0  C0  D0
    X1 Y0  A1  B1  C0  D0
K1  X2 Y1  A2  B2  C1  D1

[3 rows x 4 columns]

Для более ранних версий это можно сделать с помощью следующего.

In [43]: pd.merge(left.reset_index(), right.reset_index(),
   ....:          on=['key'], how='inner').set_index(['key', 'X', 'Y'])
   ....: 
Out[43]: 
            A   B   C   D
key X  Y                 
K0  X0 Y0  A0  B0  C0  D0
    X1 Y0  A1  B1  C0  D0
K1  X2 Y1  A2  B2  C1  D1

[3 rows x 4 columns]

Функция read_html улучшения#

read_html() ранее игнорировался colspan и rowspan атрибуты. Теперь он понимает их, рассматривая как последовательности ячеек с одинаковым значением. (GH 17054)

In [44]: from io import StringIO

In [45]: result = pd.read_html(StringIO("""
   ....:      ....:        ....:          ....:            ....:          ....:        ....:        ....:          ....:            ....:          ....:        ....:   
ABC
12
"""
)) ....:

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

In [13]: result
Out [13]:
[   A  B   C
 0  1  2 NaN]

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

In [46]: result
Out[46]: 
[   A  B  C
 0  1  1  2
 
 [1 rows x 3 columns]]

Новый Styler.pipe() метод#

The Styler класс получил pipe() метод. Это предоставляет удобный способ применения пользовательских предопределенных функций стилизации и может помочь сократить «шаблонный код» при многократном использовании функциональности стилизации DataFrame в блокноте. (GH 23229)

In [47]: df = pd.DataFrame({'N': [1250, 1500, 1750], 'X': [0.25, 0.35, 0.50]})

In [48]: def format_and_align(styler):
   ....:     return (styler.format({'N': '{:,}', 'X': '{:.1%}'})
   ....:                   .set_properties(**{'text-align': 'right'}))
   ....: 

In [49]: df.style.pipe(format_and_align).set_caption('Summary of results.')
Out[49]: 

Аналогичные методы уже существуют для других классов в pandas, включая DataFrame.pipe(), GroupBy.pipe(), и Resampler.pipe().

Переименование имен в MultiIndex#

DataFrame.rename_axis() теперь поддерживает index и columns аргументы и Series.rename_axis() поддерживает index аргумент (GH 19978).

Это изменение позволяет передавать словарь, чтобы некоторые имена в MultiIndex может быть изменен.

Пример:

In [50]: mi = pd.MultiIndex.from_product([list('AB'), list('CD'), list('EF')],
   ....:                                 names=['AB', 'CD', 'EF'])
   ....: 

In [51]: df = pd.DataFrame(list(range(len(mi))), index=mi, columns=['N'])

In [52]: df
Out[52]: 
          N
AB CD EF   
A  C  E   0
      F   1
   D  E   2
      F   3
B  C  E   4
      F   5
   D  E   6
      F   7

[8 rows x 1 columns]

In [53]: df.rename_axis(index={'CD': 'New'})
Out[53]: 
           N
AB New EF   
A  C   E   0
       F   1
   D   E   2
       F   3
B  C   E   4
       F   5
   D   E   6
       F   7

[8 rows x 1 columns]

См. Расширенная документация по переименованию для получения дополнительной информации.

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

  • merge() теперь напрямую позволяет объединять объекты типа DataFrame и названный Series, без необходимости преобразования Series объект в DataFrame заранее (GH 21220)

  • ExcelWriter теперь принимает mode как аргумент ключевого слова, позволяя добавлять к существующим рабочим книгам при использовании openpyxl движок (GH 3441)

  • FrozenList получил .union() и .difference() методы. Эта функциональность значительно упрощает группировки, которые полагаются на явное исключение определенных столбцов. См. Разделение объекта на группы для получения дополнительной информации (GH 15475, GH 15506).

  • DataFrame.to_parquet() теперь принимает index в качестве аргумента, позволяя пользователю переопределить поведение движка по умолчанию для включения или исключения индексов датафрейма из результирующего файла Parquet. (GH 20768)

  • read_feather() теперь принимает columns в качестве аргумента, позволяя пользователю указать, какие столбцы должны быть прочитаны. (GH 24025)

  • DataFrame.corr() и Series.corr() теперь принимает вызываемый объект для общих методов вычисления корреляции, например, пересечение гистограмм (GH 22684)

  • DataFrame.to_string() теперь принимает decimal в качестве аргумента, позволяя пользователю указать, какой десятичный разделитель должен использоваться в выводе. (GH 23614)

  • DataFrame.to_html() теперь принимает render_links в качестве аргумента, позволяя пользователю генерировать HTML со ссылками на любые URL, появляющиеся в DataFrame. См. раздел о записи HTML в документации по вводу-выводу для примера использования. (GH 2679)

  • pandas.read_csv() теперь поддерживает типы расширений pandas в качестве аргумента для dtype, позволяя пользователю использовать типы расширений pandas при чтении CSV. (GH 23228)

  • The shift() метод теперь принимает fill_value в качестве аргумента, позволяя пользователю указать значение, которое будет использоваться вместо NA/NaT в пустых периодах. (GH 15486)

  • to_datetime() теперь поддерживает %Z и %z директива при передаче в format (GH 13486)

  • Series.mode() и DataFrame.mode() теперь поддерживают dropna параметр, который можно использовать для указания, следует ли NaN/NaT значения должны считаться (GH 17534)

  • DataFrame.to_csv() и Series.to_csv() теперь поддерживают compression ключевое слово при передаче файлового дескриптора. (GH 21227)

  • Index.droplevel() теперь также реализован для плоских индексов, для совместимости с MultiIndex (GH 21115)

  • Series.droplevel() и DataFrame.droplevel() теперь реализованы (GH 20342)

  • Добавлена поддержка чтения из/записи в Google Cloud Storage через gcsfs библиотека (GH 19454, GH 23094)

  • DataFrame.to_gbq() и read_gbq() сигнатура и документация обновлены, чтобы отразить изменения из версия библиотеки pandas-gbq 0.8.0. Добавляет credentials аргумент, который позволяет использовать любой вид учетные данные google-auth. (GH 21627, GH 22557, GH 23662)

  • Новый метод HDFStore.walk() будет рекурсивно обходить иерархию групп файла HDF5 (GH 10932)

  • read_html() копирует данные ячеек через colspan и rowspan, и он обрабатывает все-th строки таблицы в качестве заголовков, если header kwarg не указан и нет thead (GH 17054)

  • Series.nlargest(), Series.nsmallest(), DataFrame.nlargest(), и DataFrame.nsmallest() теперь принимают значение "all" для keep аргумент. Это сохраняет все совпадения для n-го наибольшего/наименьшего значения (GH 16818)

  • IntervalIndex получил set_closed() метод для изменения существующего closed значение (GH 21670)

  • to_csv(), to_csv(), to_json(), и to_json() теперь поддерживает compression='infer' для определения сжатия на основе расширения имени файла (GH 15008). Сжатие по умолчанию для to_csv, to_json, и to_pickle методы были обновлены для 'infer' (GH 22004).

  • DataFrame.to_sql() теперь поддерживает запись TIMESTAMP WITH TIME ZONE типы для поддерживаемых баз данных. Для баз данных, которые не поддерживают часовые пояса, данные datetime будут храниться как локальные метки времени без учета часового пояса. См. Типы данных даты и времени для последствий (GH 9086).

  • to_timedelta() теперь поддерживает строки timedelta в iso-формате (GH 21877)

  • Series и DataFrame теперь поддерживает Iterable объектов в конструкторе (GH 2193)

  • DatetimeIndex получил DatetimeIndex.timetz атрибут. Это возвращает местное время с информацией о часовом поясе. (GH 21358)

  • round(), ceil(), и floor() для DatetimeIndex и Timestamp теперь поддерживают ambiguous аргумент для обработки дат и времени, округленных до неоднозначных времен (GH 18946) и nonexistent аргумент для обработки дат и времени, которые округляются до несуществующих времен. См. Несуществующее время при локализации (GH 22647)

  • Результат resample() теперь итерируемо, аналогично groupby() (GH 15314).

  • Series.resample() и DataFrame.resample() получили Resampler.quantile() (GH 15023).

  • DataFrame.resample() и Series.resample() с PeriodIndex теперь будет учитывать base аргумент таким же образом, как с DatetimeIndex. (GH 23882)

  • pandas.api.types.is_list_like() получил ключевое слово allow_sets который является True по умолчанию; если False, все экземпляры set больше не будет считаться "похожим на список" (GH 23061)

  • Index.to_frame() теперь поддерживает переопределение имени(ён) столбца(ов) (GH 22580).

  • Categorical.from_codes() теперь может принимать dtype параметр как альтернатива передаче categories и ordered (GH 24398).

  • Новый атрибут __git_version__ будет возвращать SHA коммита git текущей сборки (GH 21295).

  • Совместимость с Matplotlib 3.0 (GH 22790).

  • Добавлен Interval.overlaps(), arrays.IntervalArray.overlaps(), и IntervalIndex.overlaps() для определения перекрытий между интервальными объектами (GH 21998)

  • read_fwf() теперь принимает ключевое слово infer_nrows (GH 15138).

  • to_parquet() теперь поддерживает запись DataFrame в виде директории файлов parquet, разделенных по подмножеству столбцов, когда engine = 'pyarrow' (GH 23283)

  • Timestamp.tz_localize(), DatetimeIndex.tz_localize(), и Series.tz_localize() получили nonexistent аргумент для альтернативной обработки несуществующих времён. См. Несуществующее время при локализации (GH 8917, GH 24466)

  • Index.difference(), Index.intersection(), Index.union(), и Index.symmetric_difference() теперь имеют необязательный sort параметр для контроля сортировки результатов, если это возможно (GH 17839, GH 24471)

  • read_excel() теперь принимает usecols как список имён столбцов или вызываемый объект (GH 18273)

  • MultiIndex.to_flat_index() был добавлен для сведения нескольких уровней в одноуровневый Index объект.

  • DataFrame.to_stata() и pandas.io.stata.StataWriter117 может записывать смешанные строковые столбцы в формат Stata strl (GH 23633)

  • DataFrame.between_time() и DataFrame.at_time() получили axis параметр (GH 8839)

  • DataFrame.to_records() теперь принимает index_dtypes и column_dtypes параметры для разрешения различных типов данных в хранимых записях столбцов и индексов (GH 18146)

  • IntervalIndex получил is_overlapping атрибут для указания, если IntervalIndex содержит любые перекрывающиеся интервалы (GH 23309)

  • pandas.DataFrame.to_sql() получил method аргумент для управления SQL-предложением вставки. См. метод вставки раздел в документации. (GH 8953)

  • DataFrame.corrwith() теперь поддерживает ранговую корреляцию Спирмена, тау Кендалла, а также вызываемые методы корреляции. (GH 21925)

  • DataFrame.to_json(), DataFrame.to_csv(), DataFrame.to_pickle(), и другие методы экспорта теперь поддерживают тильду(~) в аргументе пути. (GH 23473)

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

pandas 0.24.0 включает ряд изменений, нарушающих обратную совместимость API.

Повышенные минимальные версии для зависимостей#

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

Пакет

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

Обязательно

numpy

1.12.0

X

bottleneck

1.2.0

fastparquet

0.2.1

matplotlib

2.0.0

numexpr

2.6.1

pandas-gbq

0.8.0

pyarrow

0.9.0

pytables

3.4.2

scipy

0.18.1

xlrd

1.0.0

pytest (разработка)

3.6

Кроме того, мы больше не зависим от feather-format для хранения на основе feather и заменил его ссылками на pyarrow (GH 21639 и GH 23053).

os.linesep используется для line_terminator of DataFrame.to_csv#

DataFrame.to_csv() теперь использует os.linesep() вместо '\n' для терминатора строки по умолчанию (GH 20353). Это изменение затрагивает только работу в Windows, где '\r\n' использовался для терминатора строки, даже когда '\n' был передан line_terminator.

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

In [1]: data = pd.DataFrame({"string_with_lf": ["a\nbc"],
   ...:                      "string_with_crlf": ["a\r\nbc"]})

In [2]: # When passing file PATH to to_csv,
   ...: # line_terminator does not work, and csv is saved with '\r\n'.
   ...: # Also, this converts all '\n's in the data to '\r\n'.
   ...: data.to_csv("test.csv", index=False, line_terminator='\n')

In [3]: with open("test.csv", mode='rb') as f:
   ...:     print(f.read())
Out[3]: b'string_with_lf,string_with_crlf\r\n"a\r\nbc","a\r\r\nbc"\r\n'

In [4]: # When passing file OBJECT with newline option to
   ...: # to_csv, line_terminator works.
   ...: with open("test2.csv", mode='w', newline='\n') as f:
   ...:     data.to_csv(f, index=False, line_terminator='\n')

In [5]: with open("test2.csv", mode='rb') as f:
   ...:     print(f.read())
Out[5]: b'string_with_lf,string_with_crlf\n"a\nbc","a\r\nbc"\n'

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

Передача line_terminator явно, установите line terminator к этому символу.

In [1]: data = pd.DataFrame({"string_with_lf": ["a\nbc"],
   ...:                      "string_with_crlf": ["a\r\nbc"]})

In [2]: data.to_csv("test.csv", index=False, line_terminator='\n')

In [3]: with open("test.csv", mode='rb') as f:
   ...:     print(f.read())
Out[3]: b'string_with_lf,string_with_crlf\n"a\nbc","a\r\nbc"\n'

В Windows значение os.linesep является '\r\n', поэтому если line_terminator не установлен, '\r\n' используется для терминатора строки.

In [1]: data = pd.DataFrame({"string_with_lf": ["a\nbc"],
   ...:                      "string_with_crlf": ["a\r\nbc"]})

In [2]: data.to_csv("test.csv", index=False)

In [3]: with open("test.csv", mode='rb') as f:
   ...:     print(f.read())
Out[3]: b'string_with_lf,string_with_crlf\r\n"a\nbc","a\r\nbc"\r\n'

Для файловых объектов указание newline недостаточно для установки терминатора строки. Вы должны передать line_terminator явно, даже в этом случае.

In [1]: data = pd.DataFrame({"string_with_lf": ["a\nbc"],
   ...:                      "string_with_crlf": ["a\r\nbc"]})

In [2]: with open("test2.csv", mode='w', newline='\n') as f:
   ...:     data.to_csv(f, index=False)

In [3]: with open("test2.csv", mode='rb') as f:
   ...:     print(f.read())
Out[3]: b'string_with_lf,string_with_crlf\r\n"a\nbc","a\r\nbc"\r\n'

Правильная обработка np.nan в столбце строкового типа данных с движком Python#

Была ошибка в read_excel() и read_csv() с Python движком, где отсутствующие значения превращались в 'nan' с dtype=str и na_filter=True. Теперь эти пропущенные значения преобразуются в строковый индикатор пропуска, np.nan. (GH 20377)

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

In [5]: data = 'a,b,c\n1,,3\n4,5,6'
In [6]: df = pd.read_csv(StringIO(data), engine='python', dtype=str, na_filter=True)
In [7]: df.loc[0, 'b']
Out[7]:
'nan'

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

In [54]: data = 'a,b,c\n1,,3\n4,5,6'

In [55]: df = pd.read_csv(StringIO(data), engine='python', dtype=str, na_filter=True)

In [56]: df.loc[0, 'b']
Out[56]: nan

Обратите внимание, как мы теперь вместо этого выводим np.nan самого себя вместо строкового представления.

Разбор строк даты и времени со смещениями часовых поясов#

Ранее, разбор строк даты-времени со смещениями UTC с to_datetime() или DatetimeIndex автоматически преобразует дату и время в UTC без локализации часового пояса. Это не согласуется с разбором той же строки даты и времени с помощью Timestamp что сохранило бы смещение UTC в tz атрибут. Теперь, to_datetime() сохраняет смещение UTC в tz атрибут, когда все строки datetime имеют одинаковое смещение UTC (GH 17697, GH 11736, GH 22457)

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

In [2]: pd.to_datetime("2015-11-18 15:30:00+05:30")
Out[2]: Timestamp('2015-11-18 10:00:00')

In [3]: pd.Timestamp("2015-11-18 15:30:00+05:30")
Out[3]: Timestamp('2015-11-18 15:30:00+0530', tz='pytz.FixedOffset(330)')

# Different UTC offsets would automatically convert the datetimes to UTC (without a UTC timezone)
In [4]: pd.to_datetime(["2015-11-18 15:30:00+05:30", "2015-11-18 16:30:00+06:30"])
Out[4]: DatetimeIndex(['2015-11-18 10:00:00', '2015-11-18 10:00:00'], dtype='datetime64[ns]', freq=None)

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

In [57]: pd.to_datetime("2015-11-18 15:30:00+05:30")
Out[57]: Timestamp('2015-11-18 15:30:00+0530', tz='UTC+05:30')

In [58]: pd.Timestamp("2015-11-18 15:30:00+05:30")
Out[58]: Timestamp('2015-11-18 15:30:00+0530', tz='UTC+05:30')

переданы нечисловые значения tz

In [59]: pd.to_datetime(["2015-11-18 15:30:00+05:30"] * 2)
Out[59]: DatetimeIndex(['2015-11-18 15:30:00+05:30', '2015-11-18 15:30:00+05:30'], dtype='datetime64[ns, UTC+05:30]', freq=None)

Разбор строк даты и времени с разными смещениями UTC теперь создаст индекс из datetime.datetime объекты с разными смещениями UTC

In [59]: idx = pd.to_datetime(["2015-11-18 15:30:00+05:30",
                               "2015-11-18 16:30:00+06:30"])

In[60]: idx
Out[60]: Index([2015-11-18 15:30:00+05:30, 2015-11-18 16:30:00+06:30], dtype='object')

In[61]: idx[0]
Out[61]: Timestamp('2015-11-18 15:30:00+0530', tz='UTC+05:30')

In[62]: idx[1]
Out[62]: Timestamp('2015-11-18 16:30:00+0630', tz='UTC+06:30')

Передача utc=True будет имитировать предыдущее поведение, но будет правильно указывать, что даты были преобразованы в UTC

In [60]: pd.to_datetime(["2015-11-18 15:30:00+05:30",
   ....:                 "2015-11-18 16:30:00+06:30"], utc=True)
   ....: 
Out[60]: DatetimeIndex(['2015-11-18 10:00:00+00:00', '2015-11-18 10:00:00+00:00'], dtype='datetime64[ns, UTC]', freq=None)

Разбор смешанных часовых поясов с read_csv()#

read_csv() больше не преобразует молча столбцы со смешанными часовыми поясами в UTC (GH 24987).

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

>>> import io
>>> content = """\
... a
... 2000-01-01T00:00:00+05:00
... 2000-01-01T00:00:00+06:00"""
>>> df = pd.read_csv(io.StringIO(content), parse_dates=['a'])
>>> df.a
0   1999-12-31 19:00:00
1   1999-12-31 18:00:00
Name: a, dtype: datetime64[ns]

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

In[64]: import io

In[65]: content = """\
   ...: a
   ...: 2000-01-01T00:00:00+05:00
   ...: 2000-01-01T00:00:00+06:00"""

In[66]: df = pd.read_csv(io.StringIO(content), parse_dates=['a'])

In[67]: df.a
Out[67]:
0   2000-01-01 00:00:00+05:00
1   2000-01-01 00:00:00+06:00
Name: a, Length: 2, dtype: object

Как видно, dtype имеет тип object; каждое значение в столбце является строкой. Чтобы преобразовать строки в массив дат и времени, date_parser аргумент

In [3]: df = pd.read_csv(
   ...:     io.StringIO(content),
   ...:     parse_dates=['a'],
   ...:     date_parser=lambda col: pd.to_datetime(col, utc=True),
   ...: )

In [4]: df.a
Out[4]:
0   1999-12-31 19:00:00+00:00
1   1999-12-31 18:00:00+00:00
Name: a, dtype: datetime64[ns, UTC]

См. Разбор строк даты и времени со смещениями часовых поясов подробнее.

Временные значения в dt.end_time и to_timestamp(how='end')#

Временные значения в Period и PeriodIndex объекты теперь устанавливаются в '23:59:59.999999999' при вызове Series.dt.end_time, Period.end_time, PeriodIndex.end_time, Period.to_timestamp() с how='end', или PeriodIndex.to_timestamp() с how='end' (GH 17157)

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

In [2]: p = pd.Period('2017-01-01', 'D')
In [3]: pi = pd.PeriodIndex([p])

In [4]: pd.Series(pi).dt.end_time[0]
Out[4]: Timestamp(2017-01-01 00:00:00)

In [5]: p.end_time
Out[5]: Timestamp(2017-01-01 23:59:59.999999999)

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

Вызов Series.dt.end_time теперь приведёт к времени ‘23:59:59.999999999’, как в случае с Period.end_time, например

In [61]: p = pd.Period('2017-01-01', 'D')

In [62]: pi = pd.PeriodIndex([p])

In [63]: pd.Series(pi).dt.end_time[0]
Out[63]: Timestamp('2017-01-01 23:59:59.999999999')

In [64]: p.end_time
Out[64]: Timestamp('2017-01-01 23:59:59.999999999')

Series.unique для данных с учетом часового пояса#

Тип возвращаемого значения Series.unique() для datetime со значениями часового пояса изменилось с numpy.ndarray of Timestamp объектов в arrays.DatetimeArray (GH 24024).

In [65]: ser = pd.Series([pd.Timestamp('2000', tz='UTC'),
   ....:                  pd.Timestamp('2000', tz='UTC')])
   ....: 

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

In [3]: ser.unique()
Out[3]: array([Timestamp('2000-01-01 00:00:00+0000', tz='UTC')], dtype=object)

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

In [66]: ser.unique()
Out[66]: 

['2000-01-01 00:00:00+00:00']
Length: 1, dtype: datetime64[ns, UTC]

Рефакторинг структуры разреженных данных#

SparseArray, массив, лежащий в основе SparseSeries и столбцы в SparseDataFrame, теперь является массивом расширений (GH 21978, GH 19056, GH 22835). Чтобы соответствовать этому интерфейсу и для согласованности с остальной частью pandas, были внесены некоторые критические изменения API:

  • SparseArray больше не является подклассом numpy.ndarray. Для преобразования SparseArray в массив NumPy, используйте numpy.asarray().

  • SparseArray.dtype и SparseSeries.dtype теперь являются экземплярами SparseDtype, а не np.dtype. Доступ к базовому типу данных с помощью SparseDtype.subtype.

  • numpy.asarray(sparse_array) теперь возвращает плотный массив со всеми значениями, а не только со значениями, отличными от fill-value (GH 14167)

  • SparseArray.take теперь соответствует API pandas.api.extensions.ExtensionArray.take() (GH 19506):

    • Значение по умолчанию для allow_fill изменился с False to True.

    • The out и mode параметры больше не принимаются (ранее это вызывало ошибку, если они были указаны).

    • Передача скаляра для indices больше не разрешено.

  • Результат concat() со смесью разреженных и плотных Series — это Series с разреженными значениями, а не SparseSeries.

  • SparseDataFrame.combine и DataFrame.combine_first больше не поддерживает объединение разреженного столбца с плотным столбцом с сохранением подтипа разреженности. Результатом будет SparseArray с типом объекта.

  • Установка SparseArray.fill_value заполнение значением с другим типом данных теперь разрешено.

  • DataFrame[column] теперь является Series с разреженными значениями, а не с SparseSeries, при срезе одного столбца с разреженными значениями (GH 23559).

  • Результат Series.where() теперь является Series с разреженными значениями, как и с другими массивами расширений (GH 24077)

Выдаются новые предупреждения для операций, требующих или вероятно материализующих большой плотный массив:

  • A errors.PerformanceWarning вызывается при использовании fillna с method, так как для создания заполненного массива строится плотный массив. Заполнение с помощью value является эффективным способом заполнения разреженного массива.

  • A errors.PerformanceWarning теперь выдается при конкатенации разреженных Series с различными значениями заполнения. Значение заполнения из первого разреженного массива продолжает использоваться.

В дополнение к этим изменениям, нарушающим API, многие Улучшения производительности и исправления ошибок были сделаны.

Наконец, Series.sparse аксессор был добавлен для предоставления специфичных для разреженных данных методов, таких как Series.sparse.from_coo().

In [67]: s = pd.Series([0, 0, 1, 1, 1], dtype='Sparse[int]')

In [68]: s.sparse.density
Out[68]: 0.6

get_dummies() всегда возвращает DataFrame#

Ранее, когда sparse=True был передан в get_dummies(), возвращаемое значение может быть либо DataFrame или SparseDataFrame, в зависимости от того, были ли все или только подмножество столбцов преобразованы в фиктивные переменные. Теперь DataFrame всегда возвращается (GH 24284).

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

Первый get_dummies() возвращает DataFrame потому что столбец A не закодирован фиктивно. Когда просто ["B", "C"] передаются в get_dummies, затем все столбцы кодируются фиктивно, и SparseDataFrame был возвращен.

In [2]: df = pd.DataFrame({"A": [1, 2], "B": ['a', 'b'], "C": ['a', 'a']})

In [3]: type(pd.get_dummies(df, sparse=True))
Out[3]: pandas.core.frame.DataFrame

In [4]: type(pd.get_dummies(df[['B', 'C']], sparse=True))
Out[4]: pandas.core.sparse.frame.SparseDataFrame

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

Теперь тип возвращаемого значения всегда DataFrame.

In [69]: type(pd.get_dummies(df, sparse=True))
Out[69]: pandas.core.frame.DataFrame

In [70]: type(pd.get_dummies(df[['B', 'C']], sparse=True))
Out[70]: pandas.core.frame.DataFrame

Примечание

Нет разницы в использовании памяти между SparseDataFrame и DataFrame со разреженными значениями. Использование памяти будет таким же, как в предыдущей версии pandas.

Вызвать ValueError в DataFrame.to_dict(orient='index')#

Ошибка в DataFrame.to_dict() вызывает ValueError при использовании с orient='index' и не уникальный индекс вместо потери данных (GH 22801)

In [71]: df = pd.DataFrame({'a': [1, 2], 'b': [0.5, 0.75]}, index=['A', 'A'])

In [72]: df
Out[72]: 
   a     b
A  1  0.50
A  2  0.75

[2 rows x 2 columns]

In [73]: df.to_dict(orient='index')
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[73], line 1
----> 1 df.to_dict(orient='index')

File ~/work/pandas/pandas/pandas/util/_decorators.py:333, in deprecate_nonkeyword_arguments..decorate..wrapper(*args, **kwargs)
    327 if len(args) > num_allow_args:
    328     warnings.warn(
    329         msg.format(arguments=_format_argument_list(allow_args)),
    330         FutureWarning,
    331         stacklevel=find_stack_level(),
    332     )
--> 333 return func(*args, **kwargs)

File ~/work/pandas/pandas/pandas/core/frame.py:2187, in DataFrame.to_dict(self, orient, into, index)
   2084 """
   2085 Convert the DataFrame to a dictionary.
   2086 
   (...)
   2183  defaultdict(, {'col1': 2, 'col2': 0.75})]
   2184 """
   2185 from pandas.core.methods.to_dict import to_dict
-> 2187 return to_dict(self, orient, into=into, index=index)

File ~/work/pandas/pandas/pandas/core/methods/to_dict.py:242, in to_dict(df, orient, into, index)
    240 elif orient == "index":
    241     if not df.index.is_unique:
--> 242         raise ValueError("DataFrame index must be unique for orient='index'.")
    243     columns = df.columns.tolist()
    244     if are_all_object_dtype_cols:

ValueError: DataFrame index must be unique for orient='index'.

Ограничения нормализации Tick DateOffset#

Создание Tick объект (Day, Hour, Minute, Second, Milli, Micro, Nano) с normalize=True больше не поддерживается. Это предотвращает неожиданное поведение, при котором сложение могло не быть монотонным или ассоциативным. (GH 21427)

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

In [2]: ts = pd.Timestamp('2018-06-11 18:01:14')

In [3]: ts
Out[3]: Timestamp('2018-06-11 18:01:14')

In [4]: tic = pd.offsets.Hour(n=2, normalize=True)
   ...:

In [5]: tic
Out[5]: <2 * Hours>

In [6]: ts + tic
Out[6]: Timestamp('2018-06-11 00:00:00')

In [7]: ts + tic + tic + tic == ts + (tic + tic + tic)
Out[7]: False

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

In [74]: ts = pd.Timestamp('2018-06-11 18:01:14')

In [75]: tic = pd.offsets.Hour(n=2)

In [76]: ts + tic + tic + tic == ts + (tic + tic + tic)
Out[76]: True

Вычитание периодов#

Вычитание Period из другого Period даст DateOffset. вместо целого числа (GH 21314)

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

In [2]: june = pd.Period('June 2018')

In [3]: april = pd.Period('April 2018')

In [4]: june - april
Out [4]: 2

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

In [77]: june = pd.Period('June 2018')

In [78]: april = pd.Period('April 2018')

In [79]: june - april
Out[79]: <2 * MonthEnds>

Аналогично, вычитание Period из PeriodIndex теперь будет возвращать Index of DateOffset объекты вместо Int64Index

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

In [2]: pi = pd.period_range('June 2018', freq='M', periods=3)

In [3]: pi - pi[0]
Out[3]: Int64Index([0, 1, 2], dtype='int64')

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

In [80]: pi = pd.period_range('June 2018', freq='M', periods=3)

In [81]: pi - pi[0]
Out[81]: Index([<0 * MonthEnds>, , <2 * MonthEnds>], dtype='object')

Сложение/вычитание NaN из DataFrame#

Сложение или вычитание NaN из DataFrame столбец с timedelta64[ns] dtype теперь будет вызывать TypeError вместо возврата всех-NaT. Это для совместимости с TimedeltaIndex и Series поведение (GH 22163)

In [82]: df = pd.DataFrame([pd.Timedelta(days=1)])

In [83]: df
Out[83]: 
       0
0 1 days

[1 rows x 1 columns]

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

In [4]: df = pd.DataFrame([pd.Timedelta(days=1)])

In [5]: df - np.nan
Out[5]:
    0
0 NaT

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

In [2]: df - np.nan
...
TypeError: unsupported operand type(s) for -: 'TimedeltaIndex' and 'float'

Изменения в операциях сравнения DataFrame с вещанием#

Ранее поведение трансляции DataFrame операции сравнения (==, !=, …) было несовместимо с поведением арифметических операций (+, -, …). Поведение операций сравнения было изменено, чтобы соответствовать арифметическим операциям в этих случаях. (GH 22880)

Затронутые случаи:

  • работа с двумерным np.ndarray с 1 строкой или 1 столбцом теперь будет транслироваться так же, как np.ndarray будет (GH 23000).

  • список или кортеж с длиной, соответствующей количеству строк в DataFrame теперь будет вызывать ValueError вместо работы по столбцам (GH 22880.

  • список или кортеж с длиной, соответствующей количеству столбцов в DataFrame теперь будет работать построчно вместо вызова исключения ValueError (GH 22880).

In [84]: arr = np.arange(6).reshape(3, 2)

In [85]: df = pd.DataFrame(arr)

In [86]: df
Out[86]: 
   0  1
0  0  1
1  2  3
2  4  5

[3 rows x 2 columns]

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

In [5]: df == arr[[0], :]
    ...: # comparison previously broadcast where arithmetic would raise
Out[5]:
       0      1
0   True   True
1  False  False
2  False  False
In [6]: df + arr[[0], :]
...
ValueError: Unable to coerce to DataFrame, shape must be (3, 2): given (1, 2)

In [7]: df == (1, 2)
    ...: # length matches number of columns;
    ...: # comparison previously raised where arithmetic would broadcast
...
ValueError: Invalid broadcasting comparison [(1, 2)] with block values
In [8]: df + (1, 2)
Out[8]:
   0  1
0  1  3
1  3  5
2  5  7

In [9]: df == (1, 2, 3)
    ...:  # length matches number of rows
    ...:  # comparison previously broadcast where arithmetic would raise
Out[9]:
       0      1
0  False   True
1   True  False
2  False  False
In [10]: df + (1, 2, 3)
...
ValueError: Unable to coerce to Series, length must be 2: given 3

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

# Comparison operations and arithmetic operations both broadcast.
In [87]: df == arr[[0], :]
Out[87]: 
       0      1
0   True   True
1  False  False
2  False  False

[3 rows x 2 columns]

In [88]: df + arr[[0], :]
Out[88]: 
   0  1
0  0  2
1  2  4
2  4  6

[3 rows x 2 columns]
# Comparison operations and arithmetic operations both broadcast.
In [89]: df == (1, 2)
Out[89]: 
       0      1
0  False  False
1  False  False
2  False  False

[3 rows x 2 columns]

In [90]: df + (1, 2)
Out[90]: 
   0  1
0  1  3
1  3  5
2  5  7

[3 rows x 2 columns]
# Comparison operations and arithmetic operations both raise ValueError.
In [6]: df == (1, 2, 3)
...
ValueError: Unable to coerce to Series, length must be 2: given 3

In [7]: df + (1, 2, 3)
...
ValueError: Unable to coerce to Series, length must be 2: given 3

Изменения в операциях арифметики DataFrame с широковещанием#

DataFrame арифметические операции при работе с двумерными np.ndarray объекты теперь транслируются так же, как np.ndarray broadcast. (GH 23000)

In [91]: arr = np.arange(6).reshape(3, 2)

In [92]: df = pd.DataFrame(arr)

In [93]: df
Out[93]: 
   0  1
0  0  1
1  2  3
2  4  5

[3 rows x 2 columns]

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

In [5]: df + arr[[0], :]   # 1 row, 2 columns
...
ValueError: Unable to coerce to DataFrame, shape must be (3, 2): given (1, 2)
In [6]: df + arr[:, [1]]   # 1 column, 3 rows
...
ValueError: Unable to coerce to DataFrame, shape must be (3, 2): given (3, 1)

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

In [94]: df + arr[[0], :]   # 1 row, 2 columns
Out[94]: 
   0  1
0  0  2
1  2  4
2  4  6

[3 rows x 2 columns]

In [95]: df + arr[:, [1]]   # 1 column, 3 rows
Out[95]: 
   0   1
0  1   2
1  5   6
2  9  10

[3 rows x 2 columns]

Несовместимости типов данных Series и Index#

Series и Index конструкторы теперь вызывают ошибку, когда данные несовместимы с переданным dtype= (GH 15832)

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

In [4]: pd.Series([-1], dtype="uint64")
Out [4]:
0    18446744073709551615
dtype: uint64

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

In [4]: pd.Series([-1], dtype="uint64")
Out [4]:
...
OverflowError: Trying to coerce negative values to unsigned integers

Конкатенация изменяет#

Вызов pandas.concat() на Categorical целых чисел со значениями NA теперь приводит к их обработке как объектов при объединении с чем-либо, кроме другого Categorical целых чисел (GH 19214)

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

In [97]: c = pd.Series([0, 1, np.nan], dtype="category")

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

In [3]: pd.concat([s, c])
Out[3]:
0    0.0
1    1.0
2    NaN
0    0.0
1    1.0
2    NaN
dtype: float64

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

In [98]: pd.concat([s, c])
Out[98]: 
0    0.0
1    1.0
2    NaN
0    0.0
1    1.0
2    NaN
Length: 6, dtype: float64

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

  • Для DatetimeIndex и TimedeltaIndex с не-None freq атрибут, сложение или вычитание массива с целочисленным типом данных или Index вернет объект того же класса (GH 19959)

  • DateOffset объекты теперь неизменяемы. Попытка изменить один из них теперь вызовет AttributeError (GH 21341)

  • PeriodIndex вычитание другого PeriodIndex теперь будет возвращать объект типа object-dtype Index of DateOffset объекты вместо вызова TypeError (GH 20049)

  • cut() и qcut() теперь возвращает DatetimeIndex или TimedeltaIndex корзины, когда входные данные имеют тип datetime или timedelta соответственно, и retbins=True (GH 19891)

  • DatetimeIndex.to_period() и Timestamp.to_period() будет выдавать предупреждение, когда информация о часовом поясе будет потеряна (GH 21333)

  • PeriodIndex.tz_convert() и PeriodIndex.tz_localize() были удалены (GH 21781)

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

  • Новый пустой конструктор DataFrame с целым числом в качестве dtype теперь будет приведен только к float64 if index указан (GH 22858)

  • Series.str.cat() теперь будет вызывать исключение, если others является set (GH 23009)

  • Передача скалярных значений в DatetimeIndex или TimedeltaIndex теперь будет вызывать TypeError вместо ValueError (GH 23539)

  • max_rows и max_cols параметры удалены из HTMLFormatter поскольку усечение обрабатывается DataFrameFormatter (GH 23818)

  • read_csv() теперь вызовет ValueError если столбец с пропущенными значениями объявлен как имеющий тип данных bool (GH 20591)

  • Порядок столбцов в результирующем DataFrame из MultiIndex.to_frame() теперь гарантированно соответствует MultiIndex.names порядок. (GH 22420)

  • Некорректная передача DatetimeIndex to MultiIndex.from_tuples(), а не последовательность кортежей, теперь вызывает TypeError а не ValueError (GH 24024)

  • pd.offsets.generate_range() аргумент time_rule был удален; используйте offset вместо (GH 24157)

  • В версии 0.23.x pandas вызывал ValueError при слиянии числового столбца (например, int столбец с типом данных) и object столбец с типом данных (GH 9780). Мы снова включили возможность слияния object и другие типы данных; pandas по-прежнему будет вызывать ошибку при слиянии числового и object столбец типа данных, состоящий только из строк (GH 21681)

  • Доступ к уровню MultiIndex с дублирующимся именем (например, в get_level_values()) теперь вызывает ValueError вместо KeyError (GH 21678).

  • Некорректное создание IntervalDtype теперь всегда вызывает TypeError а не ValueError если подтип недопустим (GH 21185)

  • Попытка переиндексировать DataFrame с не уникальным MultiIndex теперь вызывает ValueError вместо Exception (GH 21770)

  • Index вычитание попытается выполнить поэлементную операцию вместо вызова TypeError (GH 19369)

  • pandas.io.formats.style.Styler поддерживает number-format свойство при использовании to_excel() (GH 22015)

  • DataFrame.corr() и Series.corr() теперь вызывает ValueError вместе с полезным сообщением об ошибке вместо KeyError при передаче недопустимого метода (GH 22298)

  • shift() теперь всегда будет возвращать копию, вместо предыдущего поведения возврата self при сдвиге на 0 (GH 22397)

  • DataFrame.set_index() теперь выдает более понятную (и менее частую) ошибку KeyError, вызывает ValueError для некорректных типов и не будет завершаться ошибкой при дублировании имен столбцов с drop=True. (GH 22484)

  • При срезе одной строки DataFrame с несколькими ExtensionArrays одного типа теперь сохраняется dtype, а не преобразуется в object (GH 22784)

  • DateOffset атрибут _cacheable и метод _should_cache были удалены (GH 23118)

  • Series.searchsorted(), при передаче скалярного значения для поиска, теперь возвращает скаляр вместо массива (GH 23801).

  • Categorical.searchsorted(), при передаче скалярного значения для поиска, теперь возвращает скаляр вместо массива (GH 23466).

  • Categorical.searchsorted() теперь вызывает KeyError а не ValueError, если искомый ключ не найден в его категориях (GH 23466).

  • Index.hasnans() и Series.hasnans() теперь всегда возвращает логическое значение Python. Ранее могло возвращаться логическое значение Python или NumPy, в зависимости от обстоятельств (GH 23294).

  • Порядок аргументов DataFrame.to_html() и DataFrame.to_string() переупорядочивается для согласованности друг с другом. (GH 23614)

  • CategoricalIndex.reindex() теперь вызывает ValueError если целевой индекс не уникален и не равен текущему индексу. Ранее ошибка возникала только если целевой индекс не был категориального типа (GH 23963).

  • Series.to_list() и Index.to_list() теперь являются алиасами Series.tolist соответственно Index.tolist (GH 8826)

  • Результат SparseSeries.unstack теперь является DataFrame с разреженными значениями, а не с SparseDataFrame (GH 24372).

  • DatetimeIndex и TimedeltaIndex больше не игнорируют точность dtype. Передача dtype с разрешением не в наносекундах вызовет ValueError (GH 24753)

Изменения типов расширений#

Равенство и хэшируемость

pandas теперь требует, чтобы типы данных расширений были хэшируемыми (т.е. соответствующие ExtensionDtype объекты; хэшируемость не является требованием для значений соответствующих ExtensionArray). Базовый класс реализует значение по умолчанию __eq__ и __hash__. Если у вас параметризованный dtype, вам следует обновить ExtensionDtype._metadata кортеж для соответствия сигнатуре вашего __init__ метод. См. pandas.api.extensions.ExtensionDtype для получения дополнительной информации (GH 22476).

Новые и измененные методы

  • dropna() был добавлен (GH 21185)

  • repeat() был добавлен (GH 24349)

  • The ExtensionArray конструктор, _from_sequence теперь принимают аргумент ключевого слова copy=False (GH 21185)

  • pandas.api.extensions.ExtensionArray.shift() добавлен как часть базового ExtensionArray интерфейс (GH 22387).

  • searchsorted() был добавлен (GH 24350)

  • Поддержка операций редукции, таких как sum, mean через опциональное переопределение метода базового класса (GH 22762)

  • ExtensionArray.isna() разрешено возвращать ExtensionArray (GH 22325).

Изменения dtype

  • ExtensionDtype приобрёл возможность создания из строковых типов, например decimal создаст зарегистрированный DecimalDtype; кроме того ExtensionDtype получил метод construct_array_type (GH 21185)

  • Добавлен ExtensionDtype._is_numeric для управления тем, считается ли тип данных расширения числовым (GH 22290).

  • Добавлен pandas.api.types.register_extension_dtype() для регистрации типа расширения в pandas (GH 22664)

  • Обновлён .type атрибут для PeriodDtype, DatetimeTZDtype, и IntervalDtype быть экземплярами типа данных (Period, Timestamp, и Interval соответственно) (GH 22938)

Поддержка операторов

A Series на основе ExtensionArray теперь поддерживает арифметические и операторы сравнения (GH 19577). Существует два подхода для предоставления поддержки операторов для ExtensionArray:

  1. Определите каждый из операторов на вашем ExtensionArray подкласс.

  2. Использовать реализацию оператора из pandas, которая зависит от операторов, уже определенных на базовых элементах (скалярах) ExtensionArray.

См. Поддержка операторов ExtensionArray раздел документации для подробностей об обоих способах добавления поддержки операторов.

Прочие изменения

  • Стандартное представление для pandas.api.extensions.ExtensionArray теперь предоставляется (GH 23601).

  • ExtensionArray._formatting_values() устарел. Используйте ExtensionArray._formatter вместо этого. (GH 23601)

  • An ExtensionArray с булевым типом данных теперь корректно работает как булевый индексатор. pandas.api.types.is_bool_dtype() теперь правильно рассматривает их как булевы (GH 22326)

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

  • Ошибка в Series.get() для Series используя ExtensionArray и целочисленный индекс (GH 21257)

  • shift() теперь делегирует в ExtensionArray.shift() (GH 22386)

  • Series.combine() работает корректно с ExtensionArray внутри Series (GH 20825)

  • Series.combine() со скалярным аргументом теперь работает для любого типа функции (GH 21248)

  • Series.astype() и DataFrame.astype() теперь перенаправляют на ExtensionArray.astype() (GH 21185).

  • Срез одной строки DataFrame с несколькими ExtensionArrays одного типа теперь сохраняет dtype, а не приводит к object (GH 22784)

  • Ошибка при объединении нескольких Series с разными типами расширений, не приводящими к типу object (GH 22994)

  • Series, поддерживаемый ExtensionArray теперь работают с util.hash_pandas_object() (GH 23066)

  • DataFrame.stack() больше не преобразует в тип object для DataFrame, где каждый столбец имеет одинаковый тип расширения. Выходной Series будет иметь тот же тип, что и столбцы (GH 23077).

  • Series.unstack() и DataFrame.unstack() больше не преобразует массивы расширений в ndarrays с типом object. Каждый столбец в выводе DataFrame теперь будет иметь тот же тип данных, что и входные данные (GH 23077).

  • Ошибка при группировке Dataframe.groupby() и агрегирование по ExtensionArray он не возвращал фактический ExtensionArray тип данных (GH 23227).

  • Ошибка в pandas.merge() при слиянии по столбцу на основе массива расширения (GH 23020).

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

  • MultiIndex.labels был устаревшим и заменен на MultiIndex.codes. Функциональность не изменилась. Новое название лучше отражает природу этих кодов и делает MultiIndex API более похожий на API для CategoricalIndex (GH 13443). Как следствие, другие использования имени labels в MultiIndex также устарели и заменены на codes:

    • Вы должны инициализировать MultiIndex экземпляр с использованием параметра с именем codes вместо labels.

    • MultiIndex.set_labels был объявлен устаревшим в пользу MultiIndex.set_codes().

    • Для метода MultiIndex.copy(), labels параметр устарел и заменён на codes параметр.

  • DataFrame.to_stata(), read_stata(), StataReader и StataWriter устарели encoding аргумент. Кодировка файла Stata dta определяется типом файла и не может быть изменена (GH 21244)

  • MultiIndex.to_hierarchical() устарел и будет удален в будущей версии (GH 21613)

  • Series.ptp() устарел. Используйте numpy.ptp вместо (GH 21614)

  • Series.compress() устарел. Используйте Series[condition] вместо (GH 18262)

  • Сигнатура Series.to_csv() был унифицирован с DataFrame.to_csv(): имя первого аргумента теперь path_or_buf, порядок последующих аргументов изменился, header аргумент теперь по умолчанию True. (GH 19715)

  • Categorical.from_codes() устарело предоставление значений с плавающей точкой для codes аргумент. (GH 21767)

  • pandas.read_table() устарел. Вместо этого используйте read_csv() передача sep='\t' при необходимости. Это устаревание было удалено в 0.25.0. (GH 21948)

  • Series.str.cat() устарело использование произвольных list-likes внутри спископодобные объекты. Спископодобный контейнер может все еще содержать много Series, Index или одномерный np.ndarray, или, альтернативно, только скалярные значения. (GH 21950)

  • FrozenNDArray.searchsorted() устарел v параметр в пользу value (GH 14645)

  • DatetimeIndex.shift() и PeriodIndex.shift() теперь принимают periods аргумент вместо n для согласованности с Index.shift() и Series.shift(). Использование n выдает предупреждение об устаревании (GH 22458, GH 22912)

  • The fastpath ключевое слово различных конструкторов Index устарело (GH 23110).

  • Timestamp.tz_localize(), DatetimeIndex.tz_localize(), и Series.tz_localize() устарели errors аргумент в пользу nonexistent аргумент (GH 8917)

  • Класс FrozenNDArray был объявлен устаревшим. При распаковке, FrozenNDArray будет распакован в np.ndarray после удаления этого класса (GH 9031)

  • Методы DataFrame.update() и Panel.update() устарели raise_conflict=False|True ключевое слово в пользу errors='ignore'|'raise' (GH 23585)

  • Методы Series.str.partition() и Series.str.rpartition() устарели pat ключевое слово в пользу sep (GH 22676)

  • Устарел nthreads ключевое слово pandas.read_feather() в пользу use_threads чтобы отразить изменения в pyarrow>=0.11.0. (GH 23053)

  • pandas.read_excel() устарело принятие usecols как целое число. Пожалуйста, передайте список целых чисел от 0 до usecols включительно вместо (GH 23527)

  • Создание TimedeltaIndex из данных с datetime64-типизированные данные устарели, будут вызывать TypeError в будущей версии (GH 23539)

  • Создание DatetimeIndex из данных с timedelta64-типизированные данные устарели, будут вызывать TypeError в будущей версии (GH 23675)

  • The keep_tz=False опция (по умолчанию) из keep_tz ключевое слово DatetimeIndex.to_series() устарел (GH 17832).

  • Преобразование часового пояса для tz-aware datetime.datetime или Timestamp с Timestamp и tz аргумент теперь устарел. Вместо этого используйте Timestamp.tz_convert() (GH 23579)

  • pandas.api.types.is_period() устарел в пользу pandas.api.types.is_period_dtype (GH 23917)

  • pandas.api.types.is_datetimetz() устарел в пользу pandas.api.types.is_datetime64tz (GH 23917)

  • Создание TimedeltaIndex, DatetimeIndex, или PeriodIndex путем передачи аргументов диапазона start, end, и periods устарел в пользу timedelta_range(), date_range(), или period_range() (GH 23919)

  • Передача строкового псевдонима, такого как 'datetime64[ns, UTC]' как unit параметр для DatetimeTZDtype устарел. Используйте DatetimeTZDtype.construct_from_string вместо (GH 23990).

  • The skipna параметр infer_dtype() переключится на True по умолчанию в будущей версии pandas (GH 17066, GH 24050)

  • В Series.where() с категориальными данными, предоставляя other который отсутствует в категориях, устарел. Преобразуйте категориальный тип в другой тип данных или добавьте other к категориям сначала (GH 24077).

  • Series.clip_lower(), Series.clip_upper(), DataFrame.clip_lower() и DataFrame.clip_upper() устарели и будут удалены в будущей версии. Используйте Series.clip(lower=threshold), Series.clip(upper=threshold) и эквивалентный DataFrame методы (GH 24203)

  • Series.nonzero() устарел и будет удален в будущей версии (GH 18262)

  • Передача целого числа в Series.fillna() и DataFrame.fillna() с timedelta64[ns] dtypes устарели, будет вызывать TypeError в будущей версии. Используйте obj.fillna(pd.Timedelta(...)) вместо (GH 24694)

  • Series.cat.categorical, Series.cat.name и Series.cat.index были устаревшими. Используйте атрибуты на Series.cat или Series напрямую. (GH 24751).

  • Передача типа данных без точности, например np.dtype('datetime64') или timedelta64 to Index, DatetimeIndex и TimedeltaIndex теперь устарел. Используйте вместо этого тип данных с наносекундной точностью (GH 24753).

Целочисленное сложение/вычитание с датами и временными дельтами устарело#

В прошлом пользователи могли — в некоторых случаях — добавлять или вычитать целые числа или массивы целочисленного типа данных из Timestamp, DatetimeIndex и TimedeltaIndex.

Это использование теперь устарело. Вместо этого добавляйте или вычитайте целые кратные объекта freq атрибут (GH 21939, GH 23878).

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

In [5]: ts = pd.Timestamp('1994-05-06 12:15:16', freq=pd.offsets.Hour())
In [6]: ts + 2
Out[6]: Timestamp('1994-05-06 14:15:16', freq='H')

In [7]: tdi = pd.timedelta_range('1D', periods=2)
In [8]: tdi - np.array([2, 1])
Out[8]: TimedeltaIndex(['-1 days', '1 days'], dtype='timedelta64[ns]', freq=None)

In [9]: dti = pd.date_range('2001-01-01', periods=2, freq='7D')
In [10]: dti + pd.Index([1, 2])
Out[10]: DatetimeIndex(['2001-01-08', '2001-01-22'], dtype='datetime64[ns]', freq=None)

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

In [108]: ts = pd.Timestamp('1994-05-06 12:15:16', freq=pd.offsets.Hour())

In[109]: ts + 2 * ts.freq
Out[109]: Timestamp('1994-05-06 14:15:16', freq='H')

In [110]: tdi = pd.timedelta_range('1D', periods=2)

In [111]: tdi - np.array([2 * tdi.freq, 1 * tdi.freq])
Out[111]: TimedeltaIndex(['-1 days', '1 days'], dtype='timedelta64[ns]', freq=None)

In [112]: dti = pd.date_range('2001-01-01', periods=2, freq='7D')

In [113]: dti + pd.Index([1 * dti.freq, 2 * dti.freq])
Out[113]: DatetimeIndex(['2001-01-08', '2001-01-22'], dtype='datetime64[ns]', freq=None)

Передача целочисленных данных и часового пояса в DatetimeIndex#

Поведение DatetimeIndex при передаче целочисленных данных и изменении часового пояса в будущей версии pandas. Ранее они интерпретировались как настенные времена в желаемом часовом поясе. В будущем они будут интерпретироваться как настенные времена в UTC, которые затем преобразуются в желаемый часовой пояс (GH 24559).

Поведение по умолчанию остаётся прежним, но выдаётся предупреждение:

In [3]: pd.DatetimeIndex([946684800000000000], tz="US/Central")
/bin/ipython:1: FutureWarning:
    Passing integer-dtype data and a timezone to DatetimeIndex. Integer values
    will be interpreted differently in a future version of pandas. Previously,
    these were viewed as datetime64[ns] values representing the wall time
    *in the specified timezone*. In the future, these will be viewed as
    datetime64[ns] values representing the wall time *in UTC*. This is similar
    to a nanosecond-precision UNIX epoch. To accept the future behavior, use

        pd.to_datetime(integer_data, utc=True).tz_convert(tz)

    To keep the previous behavior, use

        pd.to_datetime(integer_data).tz_localize(tz)

 #!/bin/python3
 Out[3]: DatetimeIndex(['2000-01-01 00:00:00-06:00'], dtype='datetime64[ns, US/Central]', freq=None)

Как объясняется в предупреждении, включите будущее поведение, указав, что целочисленные значения являются UTC, а затем преобразуйте в конечный часовой пояс:

In [99]: pd.to_datetime([946684800000000000], utc=True).tz_convert('US/Central')
Out[99]: DatetimeIndex(['1999-12-31 18:00:00-06:00'], dtype='datetime64[ns, US/Central]', freq=None)

Старое поведение можно сохранить, локализуя непосредственно в конечный часовой пояс:

In [100]: pd.to_datetime([946684800000000000]).tz_localize('US/Central')
Out[100]: DatetimeIndex(['2000-01-01 00:00:00-06:00'], dtype='datetime64[ns, US/Central]', freq=None)

Преобразование Series и Index с учётом часового пояса в массивы NumPy#

Преобразование из Series или Index с данными datetime с учетом часового пояса будет изменено для сохранения часовых поясов по умолчанию (GH 23569).

NumPy не имеет специального dtype для дат с учетом часового пояса. В прошлом преобразование Series или DatetimeIndex с датами с учётом часового пояса преобразуются в массив NumPy с помощью

  1. преобразование данных с информацией о часовом поясе в UTC

  2. удаление информации о часовом поясе

  3. возвращая numpy.ndarray с datetime64[ns] dtype

Будущие версии pandas будут сохранять информацию о часовом поясе, возвращая массив NumPy типа object, где каждое значение является Timestamp с корректным прикрепленным часовым поясом

In [101]: ser = pd.Series(pd.date_range('2000', periods=2, tz="CET"))

In [102]: ser
Out[102]: 
0   2000-01-01 00:00:00+01:00
1   2000-01-02 00:00:00+01:00
Length: 2, dtype: datetime64[ns, CET]

Поведение по умолчанию остается прежним, но выдает предупреждение

In [8]: np.asarray(ser)
/bin/ipython:1: FutureWarning: Converting timezone-aware DatetimeArray to timezone-naive
      ndarray with 'datetime64[ns]' dtype. In the future, this will return an ndarray
      with 'object' dtype where each element is a 'pandas.Timestamp' with the correct 'tz'.

        To accept the future behavior, pass 'dtype=object'.
        To keep the old behavior, pass 'dtype="datetime64[ns]"'.
  #!/bin/python3
Out[8]:
array(['1999-12-31T23:00:00.000000000', '2000-01-01T23:00:00.000000000'],
      dtype='datetime64[ns]')

Предыдущее или будущее поведение можно получить без каких-либо предупреждений, указав dtype

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

In [103]: np.asarray(ser, dtype='datetime64[ns]')
Out[103]: 
array(['1999-12-31T23:00:00.000000000', '2000-01-01T23:00:00.000000000'],
      dtype='datetime64[ns]')

Будущее поведение

# New behavior
In [104]: np.asarray(ser, dtype=object)
Out[104]: 
array([Timestamp('2000-01-01 00:00:00+0100', tz='CET'),
       Timestamp('2000-01-02 00:00:00+0100', tz='CET')], dtype=object)

Или с помощью Series.to_numpy()

In [105]: ser.to_numpy()
Out[105]: 
array([Timestamp('2000-01-01 00:00:00+0100', tz='CET'),
       Timestamp('2000-01-02 00:00:00+0100', tz='CET')], dtype=object)

In [106]: ser.to_numpy(dtype="datetime64[ns]")
Out[106]: 
array(['1999-12-31T23:00:00.000000000', '2000-01-01T23:00:00.000000000'],
      dtype='datetime64[ns]')

Все вышесказанное относится к DatetimeIndex с значениями, учитывающими часовой пояс.

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

  • The LongPanel и WidePanel классы были удалены (GH 10892)

  • Series.repeat() переименовал reps аргумент для repeats (GH 14645)

  • Несколько приватных функций были удалены из (непубличного) модуля pandas.core.common (GH 22001)

  • Удаление ранее устаревшего модуля pandas.core.datetools (GH 14105, GH 14094)

  • Строки, переданные в DataFrame.groupby() которые ссылаются как на уровни столбцов, так и на уровни индекса, вызовут ValueError (GH 14432)

  • Index.repeat() и MultiIndex.repeat() переименовали n аргумент для repeats (GH 14645)

  • The Series конструкторе и .astype метод теперь будет вызывать ValueError если передаются типы данных временных меток без единицы измерения (например, np.datetime64) для dtype параметр (GH 15987)

  • Удаление ранее устаревших as_indexer ключевое слово полностью из str.match() (GH 22356, GH 6581)

  • Модули pandas.types, pandas.computation, и pandas.util.decorators были удалены (GH 16157, GH 16250)

  • Удалён pandas.formats.style обёртка для pandas.io.formats.style.Styler (GH 16059)

  • pandas.pnow, pandas.match, pandas.groupby, pd.get_store, pd.Expr, и pd.Term были удалены (GH 15538, GH 15940)

  • Categorical.searchsorted() и Series.searchsorted() переименовали v аргумент для value (GH 14645)

  • pandas.parser, pandas.lib, и pandas.tslib были удалены (GH 15537)

  • Index.searchsorted() переименовали key аргумент для value (GH 14645)

  • DataFrame.consolidate и Series.consolidate были удалены (GH 15501)

  • Удаление ранее устаревшего модуля pandas.json (GH 19944)

  • Модуль pandas.tools был удален (GH 15358, GH 16005)

  • SparseArray.get_values() и SparseArray.to_dense() удалили fill параметр (GH 14686)

  • DataFrame.sortlevel и Series.sortlevel были удалены (GH 15099)

  • SparseSeries.to_dense() удалил sparse_only параметр (GH 14686)

  • DataFrame.astype() и Series.astype() переименовали raise_on_error аргумент для errors (GH 14967)

  • is_sequence, is_any_int_dtype, и is_floating_dtype были удалены из pandas.api.types (GH 16163, GH 16189)

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

  • Срез Series и DataFrames с монотонно возрастающим CategoricalIndex теперь очень быстрый и имеет скорость, сравнимую с срезом с Int64Index. Увеличение скорости происходит как при индексации по метке (используя .loc), так и по позиции (.iloc) (GH 20395) Срез монотонно возрастающего CategoricalIndex самого себя (т.е. ci[1000:2000]) показывает аналогичные улучшения скорости, как указано выше (GH 21659)

  • Улучшена производительность CategoricalIndex.equals() при сравнении с другим CategoricalIndex (GH 24023)

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

  • Улучшена производительность GroupBy.rank() при работе со связанными рангами (GH 21237)

  • Улучшена производительность DataFrame.set_index() со столбцами, состоящими из Period объекты (GH 21582, GH 21606)

  • Улучшена производительность Series.at() и Index.get_value() для значений Extension Arrays (например, Categorical) (GH 24204)

  • Улучшена производительность проверок принадлежности в Categorical и CategoricalIndex (т.е. x in cat-style проверки намного быстрее). CategoricalIndex.contains() также значительно быстрее (GH 21369, GH 21508)

  • Улучшена производительность HDFStore.groups() (и зависимые функции, такие как HDFStore.keys(). (т.е. x in store проверки выполняются намного быстрее) (GH 21372)

  • Улучшена производительность pandas.get_dummies() с sparse=True (GH 21997)

  • Улучшена производительность IndexEngine.get_indexer_non_unique() для отсортированных, неуникальных индексов (GH 9466)

  • Улучшена производительность PeriodIndex.unique() (GH 23083)

  • Улучшена производительность concat() для Series объекты (GH 23404)

  • Улучшена производительность DatetimeIndex.normalize() и Timestamp.normalize() для наивных по часовому поясу или UTC дат и времени (GH 23634)

  • Улучшена производительность DatetimeIndex.tz_localize() и различные DatetimeIndex атрибуты с часовым поясом UTC dateutil (GH 23772)

  • Исправлена регрессия производительности в Windows с Python 3.7 для read_csv() (GH 23516)

  • Улучшена производительность Categorical конструктор для Series объекты (GH 23814)

  • Улучшена производительность where() для категориальных данных (GH 24077)

  • Улучшена производительность итерации по Series. Использование DataFrame.itertuples() теперь создает итераторы без внутреннего выделения списков всех элементов (GH 20783)

  • Улучшена производительность Period конструктор, дополнительно получая выгоду PeriodArray и PeriodIndex создание (GH 24084, GH 24118)

  • Улучшена производительность с учетом часового пояса DatetimeArray бинарные операции (GH 24491)

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

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

  • Ошибка в Categorical.from_codes() где NaN значения в codes были молча преобразованы в 0 (GH 21767). В будущем это вызовет ValueError. Также изменяет поведение .from_codes([1.1, 2.0]).

  • Ошибка в Categorical.sort_values() где NaN значения всегда располагались впереди независимо от na_position значение. (GH 22556).

  • Ошибка при индексации с логическим Categorical. Теперь булево значение Categorical рассматривается как булева маска (GH 22665)

  • Создание CategoricalIndex с пустыми значениями и булевыми категориями вызывал ValueError после изменения приведения типов (GH 22702).

  • Ошибка в Categorical.take() с предоставленным пользователем fill_value не кодируя fill_value, что может привести к ValueErrorневерные результаты или ошибка сегментации (GH 23296).

  • В Series.unstack(), указание fill_value отсутствие в категориях теперь вызывает TypeError вместо игнорирования fill_value (GH 23284)

  • Ошибка при ресемплинге DataFrame.resample() и агрегировании по категориальным данным, категориальный тип данных терялся. (GH 23227)

  • Ошибка во многих методах .str-аксессор, который всегда завершался ошибкой при вызове CategoricalIndex.str конструктор (GH 23555, GH 23556)

  • Ошибка в Series.where() потеря категориального типа данных для категориальных данных (GH 24077)

  • Ошибка в Categorical.apply() где NaN значения могли обрабатываться непредсказуемо. Теперь они остаются неизменными (GH 24241)

  • Ошибка в Categorical методы сравнения ошибочно вызывают ValueError при работе с DataFrame (GH 24630)

  • Ошибка в Categorical.set_categories() где установка меньшего количества новых категорий с rename=True вызывал ошибку сегментации (GH 24675)

Datetimelike#

  • Исправлена ошибка, когда два DateOffset объекты с разными normalize атрибуты могли оцениваться как равные (GH 21404)

  • Исправлена ошибка, где Timestamp.resolution() неправильно возвращал 1 микросекунду timedelta вместо 1-наносекунды Timedelta (GH 21336, GH 21365)

  • Ошибка в to_datetime() которая не всегда возвращала Index когда box=True был указан (GH 21864)

  • Ошибка в DatetimeIndex сравнения, где строковые сравнения некорректно вызывают TypeError (GH 22074)

  • Ошибка в DatetimeIndex сравнения при сравнении с timedelta64[ns] массивы с определённым типом данных; в некоторых случаях TypeError было некорректно вызвано, в других случаях некорректно не вызвало (GH 22074)

  • Ошибка в DatetimeIndex сравнения при сравнении с массивами object-dtyped (GH 22074)

  • Ошибка в DataFrame с datetime64[ns] сложение и вычитание типов данных с Timedelta-подобные объекты (GH 22005, GH 22163)

  • Ошибка в DataFrame с datetime64[ns] сложение и вычитание типов данных с DateOffset объекты, возвращающие object dtype вместо datetime64[ns] тип данных (GH 21610, GH 22163)

  • Ошибка в DataFrame с datetime64[ns] dtype при сравнении с NaT некорректно (GH 22242, GH 22163)

  • Ошибка в DataFrame с datetime64[ns] dtype вычитания Timestamp-подобный объект возвращался некорректно datetime64[ns] dtype вместо timedelta64[ns] тип данных (GH 8554, GH 22163)

  • Ошибка в DataFrame с datetime64[ns] dtype вычитания np.datetime64 объект с единицей измерения, отличной от наносекунды, не может быть преобразован в наносекунды (GH 18874, GH 22163)

  • Ошибка в DataFrame сравнения с Timestamp-подобные объекты не вызывали TypeError для проверок неравенства с несовпадающими типами (GH 8932, GH 22163)

  • Ошибка в DataFrame со смешанными типами данных, включая datetime64[ns] некорректное возбуждение TypeError при сравнениях на равенство (GH 13128, GH 22163)

  • Ошибка в DataFrame.values возвращая DatetimeIndex для одностолбцового DataFrame с datetime-значениями, учитывающими часовой пояс. Теперь 2-D numpy.ndarray of Timestamp объектов возвращается (GH 24024)

  • Ошибка в DataFrame.eq() сравнение с NaT некорректно возвращает True или NaN (GH 15697, GH 22163)

  • Ошибка в DatetimeIndex вычитание, которое некорректно не вызывало OverflowError (GH 22492, GH 22508)

  • Ошибка в DatetimeIndex неправильно разрешает индексацию с помощью Timedelta объект (GH 20464)

  • Ошибка в DatetimeIndex где частота устанавливалась, если исходная частота была None (GH 22150)

  • Ошибка в методах округления DatetimeIndex (round(), ceil(), floor()) и Timestamp (round(), ceil(), floor()) может привести к потере точности (GH 22591)

  • Ошибка в to_datetime() с Index аргумент, который удалил бы name из результата (GH 21697)

  • Ошибка в PeriodIndex где добавление или вычитание timedelta или Tick объект выдавал некорректные результаты (GH 22988)

  • Ошибка в Series repr с данными типа period-dtype, в которых отсутствует пробел перед данными (GH 23601)

  • Ошибка в date_range() при уменьшении начальной даты до прошлой конечной даты с отрицательной частотой (GH 23270)

  • Ошибка в Series.min() который вернёт NaN вместо NaT при вызове на серии NaT (GH 23282)

  • Ошибка в Series.combine_first() неправильное выравнивание категориальных данных, так что пропущенные значения в self где не заполнено допустимыми значениями из other (GH 24147)

  • Ошибка в DataFrame.combine() с значениями типа даты и времени, вызывающими TypeError (GH 23079)

  • Ошибка в date_range() с частотой Day или выше, где даты, достаточно далёкие в будущем, могут перейти в прошлое вместо вызова исключения OutOfBoundsDatetime (GH 14187)

  • Ошибка в period_range() игнорируя частоту start и end когда они предоставлены как Period объекты (GH 20535).

  • Ошибка в PeriodIndex с атрибутом freq.n больше 1, где добавление DateOffset объект возвращал некорректные результаты (GH 23215)

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

  • Ошибка в DataFrame при создании нового столбца из ndarray типа Timestamp объекты с часовыми поясами создают столбец типа object, а не datetime с часовым поясом (GH 23932)

  • Ошибка в Timestamp конструктор, который удалит частоту входных данных Timestamp (GH 22311)

  • Ошибка в DatetimeIndex где вызов np.array(dtindex, dtype=object) некорректно возвращал массив long объекты (GH 23524)

  • Ошибка в Index где передача данных с учётом часового пояса DatetimeIndex и dtype=object неправильно вызывал бы ValueError (GH 23524)

  • Ошибка в Index где вызов np.array(dtindex, dtype=object) на timezone-naive DatetimeIndex вернет массив из datetime объекты вместо Timestamp объектов, потенциально теряя наносекундные части временных меток (GH 23524)

  • Ошибка в Categorical.__setitem__ не разрешает установку с другим Categorical когда оба неупорядочены и имеют одинаковые категории, но в другом порядке (GH 24142)

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

  • Ошибка в DatetimeIndex где построение DatetimeIndex из Categorical или CategoricalIndex некорректно удалял информацию о часовом поясе (GH 18664)

  • Ошибка в DatetimeIndex и TimedeltaIndex где индексирование с Ellipsis неправильно терял индекс freq атрибут (GH 21282)

  • Уточнено сообщение об ошибке при передаче некорректного freq аргумент для DatetimeIndex с NaT в качестве первой записи в переданных данных (GH 11587)

  • Ошибка в to_datetime() где box и utc аргументы игнорировались при передаче DataFrame или dict отображений единиц (GH 23760)

  • Ошибка в Series.dt где кэш не обновлялся корректно после операции на месте (GH 24408)

  • Ошибка в PeriodIndex где сравнения с объектом, подобным массиву, длиной 1 не удалось вызвать ValueError (GH 23078)

  • Ошибка в DatetimeIndex.astype(), PeriodIndex.astype() и TimedeltaIndex.astype() игнорируя знак dtype для беззнаковых целочисленных типов данных (GH 24405).

  • Исправлена ошибка в Series.max() с datetime64[ns]-dtype не возвращает NaT когда присутствуют нулевые значения и skipna=False передается (GH 24265)

  • Ошибка в to_datetime() где массивы datetime объекты, содержащие как объекты с часовым поясом, так и без него datetimes не удалось вызвать исключение ValueError (GH 24569)

  • Ошибка в to_datetime() с неверным форматом даты и времени не приводит к преобразованию входных данных в NaT даже если errors='coerce' (GH 24763)

Timedelta#

  • Ошибка в DataFrame с timedelta64[ns] деление по dtype Timedelta-подобный скаляр, некорректно возвращающий timedelta64[ns] dtype вместо float64 тип данных (GH 20088, GH 22163)

  • Ошибка при добавлении Index с типом данных object в Series с timedelta64[ns] dtype некорректно вызывает (GH 22390)

  • Ошибка при умножении Series с числовым типом данных против timedelta объект (GH 22390)

  • Ошибка в Series с числовым dtype при добавлении или вычитании массива или Series с timedelta64 тип данных (GH 22390)

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

  • Ошибка в TimedeltaIndex неправильно разрешает индексацию с помощью Timestamp объект (GH 20464)

  • Исправлена ошибка, при которой вычитание Timedelta из массива с типом object вызывало бы исключение TypeError (GH 21980)

  • Исправлена ошибка при добавлении DataFrame со всеми-timedelta64[ns] типы данных в DataFrame с полностью целочисленными типами данных, возвращающими некорректные результаты вместо вызова исключения TypeError (GH 22696)

  • Ошибка в TimedeltaIndex где добавление скаляра дата-время с часовым поясом некорректно возвращало дата-время без часового пояса DatetimeIndex (GH 23215)

  • Ошибка в TimedeltaIndex где добавление np.timedelta64('NaT') некорректно возвращал полностью-NaT DatetimeIndex вместо всех-NaT TimedeltaIndex (GH 23215)

  • Ошибка в Timedelta и to_timedelta() имеют несоответствия в поддерживаемых строковых единицах (GH 21762)

  • Ошибка в TimedeltaIndex деление, где деление на другое TimedeltaIndex вызвано TypeError вместо возврата Float64Index (GH 23829, GH 22631)

  • Ошибка в TimedeltaIndex операции сравнения, где сравнение с не-Timedelta-подобные объекты вызывали бы TypeError вместо возврата всех-False для __eq__ и все-True для __ne__ (GH 24056)

  • Ошибка в Timedelta сравнения при сравнении с Tick объект некорректно вызывает TypeError (GH 24710)

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

  • Ошибка в Index.shift() где AssertionError вызывал бы при сдвиге через DST (GH 8616)

  • Ошибка в Timestamp конструктор, где передача недопустимого обозначения смещения часового пояса (Z) не вызовет ValueError (GH 8910)

  • Ошибка в Timestamp.replace() где замена на границе перехода на летнее время сохраняла некорректное смещение (GH 7825)

  • Ошибка в Series.replace() с datetime64[ns, tz] данные при замене NaT (GH 11792)

  • Ошибка в Timestamp при передаче различных строковых форматов дат со смещением часового пояса могли получаться разные смещения часовых поясов (GH 12064)

  • Ошибка при сравнении tz-naive Timestamp в tz-aware DatetimeIndex что привело бы к приведению DatetimeIndex в tz-наивные (GH 12601)

  • Ошибка в Series.truncate() с tz-aware DatetimeIndex что вызывало дамп памяти (GH 9243)

  • Ошибка в Series конструктор, который бы преобразовывал tz-aware и tz-naive Timestamp в tz-aware (GH 13051)

  • Ошибка в Index с datetime64[ns, tz] тип данных, который неправильно локализовал целочисленные данные (GH 20964)

  • Ошибка в DatetimeIndex где создание с целым числом и tz не локализовалось корректно (GH 12619)

  • Исправлена ошибка, где DataFrame.describe() и Series.describe() на tz-осведомленных датах и времени не показывал first и last результат (GH 21328)

  • Ошибка в DatetimeIndex сравнения не вызывали TypeError при сравнении с учётом часового пояса DatetimeIndex против np.datetime64 (GH 22074)

  • Ошибка в DataFrame присваивание с использованием скаляра с учетом часового пояса (GH 19843)

  • Ошибка в DataFrame.asof() который вызывал TypeError при попытке сравнить временные метки без часового пояса и с часовым поясом (GH 21194)

  • Ошибка при создании DatetimeIndex с Timestamp созданный с помощью replace метод через DST (GH 18785)

  • Ошибка при установке нового значения с DataFrame.loc() с DatetimeIndex с переходом на летнее время (GH 18308, GH 20724)

  • Ошибка в Index.unique() который неправильно перелокализовал даты с учётом часового пояса (GH 21737)

  • Ошибка при индексировании Series с переходом на летнее время (GH 21846)

  • Ошибка в DataFrame.resample() и Series.resample() где AmbiguousTimeError или NonExistentTimeError вызывало ошибку, если временной ряд с учетом часового пояса заканчивался на переходе на летнее время (GH 19375, GH 10117)

  • Ошибка в DataFrame.drop() и Series.drop() при указании ключа Timestamp с часовым поясом для удаления из DatetimeIndex с переходом на летнее время (GH 21761)

  • Ошибка в DatetimeIndex конструктор где NaT и dateutil.tz.tzlocal вызовет OutOfBoundsDatetime ошибка (GH 23807)

  • Ошибка в DatetimeIndex.tz_localize() и Timestamp.tz_localize() с dateutil.tz.tzlocal около перехода на летнее время, которое возвращало некорректно локализованную дату и время (GH 23807)

  • Ошибка в Timestamp конструкторе, где dateutil.tz.tzutc часовой пояс передан с datetime.datetime аргумент будет преобразован в pytz.UTC timezone (GH 23807)

  • Ошибка в to_datetime() где utc=True не учитывалось при указании unit и errors='ignore' (GH 23758)

  • Ошибка в to_datetime() где utc=True не соблюдался при передаче Timestamp (GH 24415)

  • Ошибка в DataFrame.any() возвращает неверное значение, когда axis=1 и данные имеют тип, похожий на дату и время (GH 23070)

  • Ошибка в DatetimeIndex.to_period() где индекс с учётом часового пояса сначала был преобразован в UTC перед созданием PeriodIndex (GH 22905)

  • Ошибка в DataFrame.tz_localize(), DataFrame.tz_convert(), Series.tz_localize(), и Series.tz_convert() где copy=False изменял бы исходный аргумент на месте (GH 6326)

  • Ошибка в DataFrame.max() и DataFrame.min() с axis=1 где Series с NaN будет возвращён, когда все столбцы содержали одинаковый часовой пояс (GH 10390)

Смещения#

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

  • Ошибка в DateOffset аргументы ключевых слов where week и milliseconds принимались и игнорировались. Передача этих параметров теперь вызовет ValueError (GH 19398)

  • Ошибка при добавлении DateOffset с DataFrame или PeriodIndex некорректное возбуждение TypeError (GH 23215)

  • Ошибка при сравнении DateOffset объектов с объектами, не являющимися DateOffset, особенно строками, вызывая ValueError вместо возврата False для проверок равенства и True для проверок на неравенство (GH 23524)

Числовой#

  • Ошибка в Series __rmatmul__ не поддерживает умножение матрицы на вектор (GH 21530)

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

  • Исправлена ошибка в unique() обрабатывал знаковые нули непоследовательно: для некоторых входных данных 0.0 и -0.0 считались равными, а для некоторых - разными. Теперь они считаются равными для всех входных данных (GH 21866)

  • Ошибка в DataFrame.agg(), DataFrame.transform() и DataFrame.apply() где, при передаче списка функций и axis=1 (например, df.apply(['sum', 'mean'], axis=1)), а TypeError был ошибочно поднят. Для всех трёх методов такие вычисления теперь выполняются корректно. (GH 16679).

  • Ошибка в Series сравнение со скалярами и массивами, похожими на дату и время (GH 22074)

  • Ошибка в DataFrame умножение между boolean dtype и integer возвращает object тип данных вместо целочисленного типа данных (GH 22047, GH 22163)

  • Ошибка в DataFrame.apply() where, при передаче строкового аргумента и дополнительных позиционных или ключевых аргументов (например, df.apply('sum', min_count=1)), a TypeError было ошибочно вызвано (GH 22376)

  • Ошибка в DataFrame.astype() к типу данных расширения может вызвать AttributeError (GH 22578)

  • Ошибка в DataFrame с timedelta64[ns] арифметические операции с типами данных ndarray с целочисленным типом данных некорректно обрабатывающим narray как timedelta64[ns] тип данных (GH 23114)

  • Ошибка в Series.rpow() с dtype object NaN для 1 ** NA вместо 1 (GH 22922).

  • Series.agg() теперь может обрабатывать numpy методы, учитывающие NaN, такие как numpy.nansum() (GH 19629)

  • Ошибка в Series.rank() и DataFrame.rank() когда pct=True и более 224 наличие строк приводило к процентам больше 1.0 (GH 18271)

  • Вызовы, такие как DataFrame.round() с неуникальным CategoricalIndex() теперь возвращают ожидаемые данные. Ранее данные могли неправильно дублироваться (GH 21809).

  • Добавлен log10, floor и ceil в список поддерживаемых функций в DataFrame.eval() (GH 24139, GH 24353)

  • Логические операции &, |, ^ между Series и Index больше не будет вызывать ValueError (GH 22092)

  • Проверка чисел PEP 3141 в is_scalar() функция возвращает True (GH 22903)

  • Методы редукции, такие как Series.sum() теперь принимают значение по умолчанию keepdims=False при вызове из NumPy ufunc, вместо вызова TypeError. Полная поддержка keepdims не был реализован (GH 24356).

Преобразование#

  • Ошибка в DataFrame.combine_first() в котором типы столбцов неожиданно преобразовались в float (GH 20699)

  • Ошибка в DataFrame.clip() в котором типы столбцов не сохраняются и приводятся к float (GH 24162)

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

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

Строки#

  • Ошибка в Index.str.partition() не был безопасным к NaN (GH 23558).

  • Ошибка в Index.str.split() не был безопасным к NaN (GH 23677).

  • Ошибка Series.str.contains() не учитывая na аргумент для Categorical dtype Series (GH 22158)

  • Ошибка в Index.str.cat() когда результат содержал только NaN (GH 24044)

Interval#

  • Ошибка в IntervalIndex конструктор, где closed параметр не всегда переопределял выведенный closed (GH 19370)

  • Ошибка в IntervalIndex представление, где отсутствовала завершающая запятая после списка интервалов (GH 20611)

  • Ошибка в Interval где скалярные арифметические операции не сохраняли closed значение (GH 22313)

  • Ошибка в IntervalIndex где индексирование с datetime-подобными значениями вызывало KeyError (GH 20636)

  • Ошибка в IntervalTree где данные, содержащие NaN вызывало предупреждение и приводило к некорректным запросам индексации с IntervalIndex (GH 23352)

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

  • Ошибка в DataFrame.ne() завершается ошибкой, если столбцы содержат имя столбца "dtype" (GH 22383)

  • Трассировка из KeyError при запросе .loc для одного отсутствующего метки теперь короче и понятнее (GH 21557)

  • PeriodIndex теперь выдаёт KeyError когда ищется некорректная строка, что согласуется с поведением DatetimeIndex (GH 22803)

  • Когда .ix запрашивается отсутствующая целочисленная метка в MultiIndex с первым уровнем целочисленного типа, теперь вызывает KeyError, последовательно со случаем плоского Int64Index, вместо возврата к позиционному индексированию (GH 21593)

  • Ошибка в Index.reindex() при переиндексации tz-наивного и tz-осведомленного DatetimeIndex (GH 8306)

  • Ошибка в Series.reindex() при переиндексации пустой серии с datetime64[ns, tz] тип данных (GH 20869)

  • Ошибка в DataFrame при установке значений с помощью .loc и с учетом часового пояса DatetimeIndex (GH 11365)

  • DataFrame.__getitem__ теперь принимает словари и ключи словарей как списко-подобные метки, согласованно с Series.__getitem__ (GH 21294)

  • Исправлено DataFrame[np.nan] когда столбцы не уникальны (GH 21428)

  • Ошибка при индексации DatetimeIndex с датами и часовыми поясами с наносекундным разрешением (GH 11679)

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

  • Ошибка, при которой смешанные индексы не позволяли использовать целые числа для .at (GH 19860)

  • Float64Index.get_loc теперь вызывает KeyError при передаче булевого ключа. (GH 19087)

  • Ошибка в DataFrame.loc() при индексации с IntervalIndex (GH 19977)

  • Index больше не искажает None, NaN и NaT, т.е. они рассматриваются как три разных ключа. Однако, для числового Index все три всё равно приводятся к NaN (GH 22332)

  • Ошибка в scalar in Index если скаляр является float, в то время как Index имеет целочисленный тип данных (GH 22085)

  • Ошибка в MultiIndex.set_levels() когда значение уровней не является индексируемым (GH 23273)

  • Ошибка, при которой установка столбца timedelta путем Index приводит к приведению к типу double и, следовательно, потере точности (GH 23511)

  • Ошибка в Index.union() и Index.intersection() где имя Index результата не вычислялся правильно для некоторых случаев (GH 9943, GH 9862)

  • Ошибка в Index срез с булевым значением Index может вызывать TypeError (GH 22533)

  • Ошибка в PeriodArray.__setitem__ при принятии среза и значения, похожего на список (GH 23978)

  • Ошибка в DatetimeIndex, TimedeltaIndex где индексирование с Ellipsis потеряли бы свои freq атрибут (GH 21282)

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

Отсутствует#

  • Ошибка в DataFrame.fillna() где ValueError вызывало ошибку, когда один столбец содержал datetime64[ns, tz] тип данных (GH 15522)

  • Ошибка в Series.hasnans() который может быть некорректно кэширован и возвращать неверные ответы, если нулевые элементы вводятся после первоначального вызова (GH 19700)

  • Series.isin() теперь рассматривает все NaN-числа с плавающей точкой как равные также для np.object_-dtype. Это поведение согласуется с поведением для float64 (GH 22119)

  • unique() больше не искажает NaN-значения с плавающей точкой и NaT-object для np.object_-dtype, т.е. NaT больше не приводится к значению NaN и рассматривается как отдельная сущность. (GH 22295)

  • DataFrame и Series теперь корректно обрабатывает маскированные массивы numpy с жёсткими масками. Ранее создание DataFrame или Series из маскированного массива с жёсткой маской создавало объект pandas, содержащий базовое значение, а не ожидаемый NaN. (GH 24574)

  • Ошибка в DataFrame конструктор где dtype аргумент не учитывался при обработке маскированных записей numpy. (GH 24874)

MultiIndex#

  • Ошибка в io.formats.style.Styler.applymap() где subset= с MultiIndex срез сократится до Series (GH 19861)

  • Удалена совместимость для MultiIndex pickles до версии 0.8.0; совместимость с MultiIndex пиклы из версии 0.13 и далее поддерживаются (GH 21654)

  • MultiIndex.get_loc_level() (и как следствие, .loc на Series или DataFrame с MultiIndex index) теперь будет вызывать KeyError, а не возвращает пустой slice, если запрошена метка, которая присутствует в levels но не используется (GH 22221)

  • MultiIndex получил MultiIndex.from_frame(), он позволяет построить MultiIndex объект из DataFrame (GH 22420)

  • Исправление TypeError в Python 3 при создании MultiIndex в которых некоторые уровни имеют смешанные типы, например, когда некоторые метки являются кортежами (GH 15457)

Ввод-вывод#

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

  • Ошибка в read_csv() в котором имена столбцов в Unicode не распознавались должным образом в Python 2.x (GH 13253)

  • Ошибка в DataFrame.to_sql() при записи данных с учетом часового пояса (datetime64[ns, tz] dtype) вызывал бы TypeError (GH 9086)

  • Ошибка в DataFrame.to_sql() где наивный DatetimeIndex будет записано как TIMESTAMP WITH TIMEZONE тип в поддерживаемых базах данных, например PostgreSQL (GH 23510)

  • Ошибка в read_excel() когда parse_cols указан с пустым набором данных (GH 9208)

  • read_html() больше не игнорирует полностью пробельные внутри при рассмотрении skiprows и header аргументы. Ранее пользователям приходилось уменьшать свои header и skiprows значения на таких таблицах, чтобы обойти проблему. (GH 21641)

  • read_excel() будет корректно показывать предупреждение об устаревании для ранее устаревших sheetname (GH 17994)

  • read_csv() и read_table() будет вызывать исключение UnicodeError и не вызывать аварийное завершение при некорректно закодированных строках (GH 22748)

  • read_csv() будет корректно разбирать даты с учетом часового пояса (GH 22256)

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

  • Ошибка в read_csv() в безымянных столбцах неправильно идентифицировались при извлечении мультииндекса (GH 23687)

  • read_sas() будет корректно разбирать числа в файлах sas7bdat, имеющих ширину менее 8 байт. (GH 21616)

  • read_sas() будет корректно парсить файлы sas7bdat со многими столбцами (GH 22628)

  • read_sas() будет правильно парсить файлы sas7bdat с типами страниц данных, у которых также установлен бит 7 (так что тип страницы 128 + 256 = 384) (GH 16615)

  • Ошибка в read_sas() в котором некорректно вызывалась ошибка при неверном формате файла. (GH 24548)

  • Ошибка в detect_client_encoding() где потенциальные IOError не обрабатывается при импорте в процессе mod_wsgi из-за ограниченного доступа к stdout. (GH 21552)

  • Ошибка в DataFrame.to_html() с index=False пропускает индикаторы усечения (…) на усеченном DataFrame (GH 15019, GH 22783)

  • Ошибка в DataFrame.to_html() с index=False когда и столбцы, и индекс строк являются MultiIndex (GH 22579)

  • Ошибка в DataFrame.to_html() с index_names=False отображение имени индекса (GH 22747)

  • Ошибка в DataFrame.to_html() с header=False не отображение имён строк индекса (GH 23788)

  • Ошибка в DataFrame.to_html() с sparsify=False что приводило к вызову исключения TypeError (GH 22887)

  • Ошибка в DataFrame.to_string() который нарушал выравнивание столбцов, когда index=False и ширина значений первого столбца больше ширины заголовка первого столбца (GH 16839, GH 13032)

  • Ошибка в DataFrame.to_string() который вызывал представления DataFrame чтобы не занимать всё окно (GH 22984)

  • Ошибка в DataFrame.to_csv() где одиночный уровень MultiIndex некорректно записывал кортеж. Теперь записывается только значение индекса (GH 19589).

  • HDFStore вызовет исключение ValueError когда format kwarg передается в конструктор (GH 13291)

  • Ошибка в HDFStore.append() при добавлении DataFrame с пустым строковым столбцом и min_itemsize < 8 (GH 12242)

  • Ошибка в read_csv() в котором возникали утечки памяти в C-движке при разборе NaN Ошибка при установке новой метки наGH 21353)

  • Ошибка в read_csv() в котором некорректные сообщения об ошибках выдавались, когда skipfooter был передан вместе с nrows, iterator, или chunksize (GH 23711)

  • Ошибка в read_csv() в котором MultiIndex имена индексов неправильно обрабатывались в случаях, когда они не были предоставлены (GH 23484)

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

  • Ошибка в read_html() в которой сообщение об ошибке не отображало допустимые варианты при предоставлении недопустимого (GH 23549)

  • Ошибка в read_excel() в котором извлекались лишние имена заголовков, хотя они не были указаны (GH 11733)

  • Ошибка в read_excel() в котором имена столбцов иногда не преобразовывались в строку должным образом в Python 2.x (GH 23874)

  • Ошибка в read_excel() в котором index_col=None не соблюдалось и всё равно парсились столбцы индекса (GH 18792, GH 20480)

  • Ошибка в read_excel() в котором usecols не проходил проверку на корректность имён столбцов при передаче в виде строки (GH 20480)

  • Ошибка в DataFrame.to_dict() когда результирующий словарь содержит не-Python скаляры в случае числовых данных (GH 23753)

  • DataFrame.to_string(), DataFrame.to_html(), DataFrame.to_latex() будет правильно форматировать вывод при передаче строки в качестве float_format аргумент (GH 21625, GH 22270)

  • Ошибка в read_csv() что приводило к вызову исключения OverflowError при попытке использовать 'inf' как na_value с целочисленным индексным столбцом (GH 17128)

  • Ошибка в read_csv() что приводило к неправильному чтению CSV-файлов с акцентированными или специальными символами в C-движке на Python 3.6+ в Windows (GH 15086)

  • Ошибка в read_fwf() в котором тип сжатия файла не определялся корректно (GH 22199)

  • Ошибка в pandas.io.json.json_normalize() что приводило к вызову исключения TypeError когда два последовательных элемента record_path являются словарями (GH 22706)

  • Ошибка в DataFrame.to_stata(), pandas.io.stata.StataWriter и pandas.io.stata.StataWriter117 где исключение оставило бы частично записанный и недействительный dta-файл (GH 23573)

  • Ошибка в DataFrame.to_stata() и pandas.io.stata.StataWriter117 которые создавали недопустимые файлы при использовании strLs с не-ASCII символами (GH 23573)

  • Ошибка в HDFStore что приводило к вызову исключения ValueError при чтении DataFrame в Python 3 из фиксированного формата, записанного в Python 2 (GH 24510)

  • Ошибка в DataFrame.to_string() и в более общем случае в плавающей repr форматтер. Нули не обрезались, если inf присутствовал в столбцах, в то время как это было с NA значениями. Нули теперь обрезаются, как в присутствии NA (GH 24861).

  • Ошибка в repr при усечении количества столбцов и наличии широкого последнего столбца (GH 24849).

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

  • Ошибка в DataFrame.plot.scatter() и DataFrame.plot.hexbin() вызывал исчезновение метки оси x и подписей делений, когда цветовая шкала была включена во встроенном бэкенде IPython (GH 10611, GH 10678, и GH 20455)

  • Ошибка при построении графика Series с датами и временем с использованием matplotlib.axes.Axes.scatter() (GH 22039)

  • Ошибка в DataFrame.plot.bar() приводило к использованию несколькими цветами вместо одного (GH 20585)

  • Ошибка в проверке параметра color приводила к добавлению лишнего цвета в заданный массив цветов. Это происходило в нескольких функциях построения графиков с использованием matplotlib. (GH 20726)

GroupBy/resample/rolling#

  • Ошибка в Rolling.min() и Rolling.max() с closed='left', дата-времяподобный индекс и только одна запись в серии, приводящая к segfault (GH 24718)

  • Ошибка в GroupBy.first() и GroupBy.last() с as_index=False приводя к потере информации о часовом поясе (GH 15884)

  • Ошибка в DateFrame.resample() при понижающей дискретизации через границу перехода на летнее время (GH 8531)

  • Ошибка в привязке даты для DateFrame.resample() со смещением Day когда n > 1 (GH 24127)

  • Ошибка, где ValueError ошибочно возникает при вызове SeriesGroupBy.count() метод SeriesGroupBy когда переменная группировки содержит только NaN и версия numpy < 1.13 (GH 21956).

  • Несколько ошибок в Rolling.min() с closed='left' и datetime-подобный индекс, приводящий к некорректным результатам и сегфолту. (GH 21704)

  • Ошибка в Resampler.apply() при передаче позиционных аргументов в применяемую функцию (GH 14615).

  • Ошибка в Series.resample() при передаче numpy.timedelta64 to loffset kwarg (GH 7687).

  • Ошибка в Resampler.asfreq() когда частота TimedeltaIndex является подпериодом новой частоты (GH 13022).

  • Ошибка в SeriesGroupBy.mean() когда значения были целочисленными, но не могли поместиться в int64, вызывая переполнение. (GH 22487)

  • RollingGroupby.agg() и ExpandingGroupby.agg() теперь поддерживают несколько агрегационных функций в качестве параметров (GH 15072)

  • Ошибка в DataFrame.resample() и Series.resample() Ошибка в срезе MultiIndex в различных крайних случаях ('W') через переход на летнее/зимнее время (GH 9119, GH 21459)

  • Ошибка в DataFrame.expanding() в котором axis аргумент не учитывался во время агрегаций (GH 23372)

  • Ошибка в GroupBy.transform() что вызывало пропущенные значения, когда входная функция может принимать DataFrame но переименовывает его (GH 23455).

  • Ошибка в GroupBy.nth() где порядок столбцов не всегда сохранялся (GH 20760)

  • Ошибка в GroupBy.rank() с method='dense' и pct=True когда группа имеет только одного участника, вызывало бы ZeroDivisionError (GH 23666).

  • Вызов GroupBy.rank() с пустыми группами и pct=True вызывал ZeroDivisionError (GH 22519)

  • Ошибка в DataFrame.resample() при передискретизации NaT в TimeDeltaIndex (GH 13223).

  • Ошибка в DataFrame.groupby() не учитывал observed аргумент при выборе столбца и вместо этого всегда используется observed=False (GH 23970)

  • Ошибка в SeriesGroupBy.pct_change() или DataFrameGroupBy.pct_change() ранее работало между группами при вычислении процентного изменения, теперь корректно работает внутри каждой группы (GH 21200, GH 21235).

  • Ошибка, препятствующая созданию хэш-таблицы с очень большим числом (2^32) строк (GH 22805)

  • Ошибка в groupby при группировке по категориальным данным вызывает ValueError и некорректная группировка, если observed=True и nan присутствует в категориальной колонке (GH 24740, GH 21151).

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

  • Ошибка в pandas.concat() при объединении ресемплированных DataFrame с индексом, учитывающим часовой пояс (GH 13783)

  • Ошибка в pandas.concat() при соединении только Series the names аргумент concat больше не игнорируется (GH 23490)

  • Ошибка в Series.combine_first() с datetime64[ns, tz] тип данных, который вернет результат без часового пояса (GH 21469)

  • Ошибка в Series.where() и DataFrame.where() с datetime64[ns, tz] тип данных (GH 21546)

  • Ошибка в DataFrame.where() с пустым DataFrame и пустым cond имеющий небулевый тип данных (GH 21947)

  • Ошибка в Series.mask() и DataFrame.mask() с list условные выражения (GH 21891)

  • Ошибка в DataFrame.replace() вызывает RecursionError при преобразовании OutOfBounds datetime64[ns, tz] (GH 20380)

  • GroupBy.rank() теперь вызывает ValueError когда передано недопустимое значение для аргумента na_option (GH 22124)

  • Ошибка в get_dummies() с атрибутами Unicode в Python 2 (GH 22084)

  • Ошибка в DataFrame.replace() вызывает RecursionError при замене пустых списков (GH 22083)

  • Ошибка в Series.replace() и DataFrame.replace() когда dict используется как to_replace значение и один ключ в словаре является значением другого ключа, результаты были несоответствующими между использованием целочисленного ключа и строкового ключа (GH 20656)

  • Ошибка в DataFrame.drop_duplicates() для пустых DataFrame который некорректно вызывает ошибку (GH 20516)

  • Ошибка в pandas.wide_to_long() когда строка передается в аргумент stubnames, а имя столбца является подстрокой этого stubname (GH 22468)

  • Ошибка в merge() при слиянии datetime64[ns, tz] данные, содержащие переход на летнее время (GH 18885)

  • Ошибка в merge_asof() при слиянии по значениям с плавающей точкой в пределах определённой погрешности (GH 22981)

  • Ошибка в pandas.concat() при объединении многоколоночного DataFrame с данными, учитывающими часовой пояс, с DataFrame с другим количеством столбцов (GH 22796)

  • Ошибка в merge_asof() где возникало запутанное сообщение об ошибке при попытке объединения с пропущенными значениями (GH 23189)

  • Ошибка в DataFrame.nsmallest() и DataFrame.nlargest() для датафреймов, которые имеют MultiIndex для столбцов (GH 23033).

  • Ошибка в pandas.melt() при передаче имён столбцов, которые отсутствуют в DataFrame (GH 23575)

  • Ошибка в DataFrame.append() с Series с часовым поясом dateutil вызывал бы TypeError (GH 23682)

  • Ошибка в Series конструкция при передаче без данных и dtype=str (GH 22477)

  • Ошибка в cut() с bins как перекрывающийся IntervalIndex где возвращалось несколько бинов на элемент вместо вызова ValueError (GH 23980)

  • Ошибка в pandas.concat() при объединении Series datetimetz с Series категория теряла часовой пояс (GH 23816)

  • Ошибка в DataFrame.join() при объединении по частичному MultiIndex удалял имена (GH 20452).

  • DataFrame.nlargest() и DataFrame.nsmallest() теперь возвращает правильные значения n, когда keep != 'all', также при связях по первым столбцам (GH 22752)

  • Создание DataFrame с аргументом индекса, который не был уже экземпляром Index был сломан (GH 22227).

  • Ошибка в DataFrame предотвращал использование подклассов списка для построения (GH 21226)

  • Ошибка в DataFrame.unstack() и DataFrame.pivot_table() возвращалось вводящее в заблуждение сообщение об ошибке, когда результирующий DataFrame содержит больше элементов, чем может обработать int32. Теперь сообщение об ошибке улучшено, указывая на фактическую проблему (GH 20601)

  • Ошибка в DataFrame.unstack() где ValueError возникала при разворачивании значений с учетом часового пояса (GH 18338)

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

  • Ошибка в merge_asof() где TypeError возникала, когда by_col были значения с учетом часового пояса (GH 21184)

  • Ошибка, показывающая некорректную форму при возникновении ошибки во время DataFrame конструкции. (GH 20742)

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

  • Обновление булевой, даты или временной колонки до Sparse теперь работает (GH 22367)

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

  • Предоставление sparse_index В конструктор SparseArray больше не устанавливает значение по умолчанию для na-value в np.nan для всех типов данных. Правильное значение na_value для data.dtype MarsGuy +

  • Ошибка в SparseArray.nbytes занижает использование памяти, не включая размер своего разреженного индекса.

  • Улучшена производительность Series.shift() для не-NA fill_value, поскольку значения больше не преобразуются в плотный массив.

  • Ошибка в DataFrame.groupby не включая fill_value в группах для не-NA fill_value при группировке по разреженному столбцу (GH 5078)

  • Ошибка в унарном операторе инверсии (~) на SparseSeries с логическими значениями. Производительность этого также улучшена (GH 22835)

  • Ошибка в SparseArary.unique() не возвращает уникальные значения (GH 19595)

  • Ошибка в SparseArray.nonzero() и SparseDataFrame.dropna() возвращая сдвинутые/некорректные результаты (GH 21172)

  • Ошибка в DataFrame.apply() где типы данных теряли разреженность (GH 23744)

  • Ошибка в concat() при объединении списка Series со всеми разреженными значениями, изменяющими fill_value и преобразование в плотный Series (GH 24371)

Стиль#

  • background_gradient() теперь принимает text_color_threshold параметр для автоматического осветления цвета текста на основе яркости цвета фона. Это улучшает читаемость при тёмных цветах фона без необходимости ограничивать диапазон цветовой карты фона. (GH 21258)

  • background_gradient() теперь также поддерживает применение по таблице (в дополнение к построчному и постолбцовому) с axis=None (GH 15204)

  • bar() теперь также поддерживает применение по таблице (в дополнение к построчному и постолбцовому) с axis=None и установка диапазона обрезки с помощью vmin и vmax (GH 21548 и GH 21526). NaN значения также обрабатываются правильно.

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

Другие#

  • Ошибка, при которой переменные C объявлялись с внешней линковкой, вызывая ошибки импорта, если определенные другие библиотеки C импортировались до pandas. (GH 24113)

Участники#

Всего 337 человек внесли исправления в этот выпуск. Люди со знаком '+' рядом с именами внесли исправление впервые.

  • AJ Dyka +

  • AJ Pryor, Ph.D +

  • Aaron Critchley

  • Adam Hooper

  • Adam J. Stewart

  • Adam Kim

  • Адам Климонт +

  • Addison Lynch +

  • Алан Хог +

  • Alex Radu +

  • Alex Rychyk

  • Alex Strick van Linschoten +

  • Alex Volkov +

  • Alexander Buchkovsky

  • Alexander Hess +

  • Alexander Ponomaroff +

  • Allison Browne +

  • Aly Sivji

  • Andrew

  • Andrew Gross +

  • Andrew Spott +

  • Andy +

  • Аникет Уттам +

  • Anjali2019 +

  • Anjana S +

  • Antti Kaihola +

  • Anudeep Tubati +

  • Arjun Sharma +

  • Armin Varshokar

  • Artem Bogachev

  • ArtinSarraf +

  • Barry Fitzgerald +

  • Bart Aelterman +

  • Ben James +

  • Бен Нельсон +

  • Benjamin Grove +

  • Benjamin Rowell +

  • Benoit Paquet +

  • Борис Лау +

  • Brett Naul

  • Brian Choi +

  • C.A.M. Gerlach +

  • Carl Johan +

  • Чалмер Лоу

  • Chang She

  • Charles David +

  • Cheuk Ting Ho

  • Chris

  • Chris Roberts +

  • Кристофер Уилан

  • Chu Qing Hao +

  • Da Cheezy Mobsta +

  • Дамини Сатья

  • Daniel Himmelstein

  • Daniel Saxton +

  • Darcy Meyer +

  • DataOmbudsman

  • Давид Аркос

  • David Krych

  • Dean Langsam +

  • Diego Argueta +

  • Diego Torres +

  • Dobatymo +

  • Даг Латорнелл +

  • Dr. Irv

  • Дилан Дмитрий Грей +

  • Eric Boxer +

  • Эрик Чеа

  • Erik +

  • Erik Nilsson +

  • Fabian Haase +

  • Fabian Retkowski

  • Fabien Aulaire +

  • Fakabbir Amin +

  • Fei Phoon +

  • Fernando Margueirat +

  • Florian Müller +

  • Fábio Rosado +

  • Гейб Фернандо

  • Габриэль Рид +

  • Giftlin Rajaiah

  • Gioia Ballin +

  • Gjelt

  • Gosuke Shibahara +

  • Graham Inggs

  • Guillaume Gay

  • Guillaume Lemaitre +

  • Hannah Ferchland

  • Haochen Wu

  • Hubert +

  • HubertKl +

  • HyunTruth +

  • Иэн Барр

  • Ignacio Vergara Kausel +

  • Irv Lustig +

  • IsvenC +

  • Джакопо Рота

  • Jakob Jarmar +

  • James Bourbeau +

  • James Myatt +

  • James Winegar +

  • Ян Рудольф

  • Jared Groves +

  • Jason Kiley +

  • Javad Noorbakhsh +

  • Jay Offerdahl +

  • Jeff Reback

  • Чонмин Ю +

  • Jeremy Schendel

  • Jerod Estapa +

  • Jesper Dramsch +

  • Jim Jeon +

  • Joe Jevnik

  • Joel Nothman

  • Joel Ostblom +

  • Жорди Контести

  • Jorge López Fueyo +

  • Joris Van den Bossche

  • Jose Quinones +

  • Jose Rivera-Rubio +

  • Josh

  • Jun +

  • Justin Zheng +

  • Kaiqi Dong +

  • Kalyan Gokhale

  • Kang Yoosam +

  • Карл Данкле Вернер +

  • Karmanya Aggarwal +

  • Кевин Маркхэм +

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

  • Kimi Li +

  • Koustav Samaddar +

  • Krishna +

  • Kristian Holsheimer +

  • Ksenia Gueletina +

  • Kyle Prestel +

  • LJ +

  • LeakedMemory +

  • Li Jin +

  • Licht Takeuchi

  • Luca Donini +

  • Лучано Виола +

  • Mak Sze Chun +

  • Марк Гарсия

  • Мариус Потгитер +

  • Марк Сикора +

  • Маркус Майер +

  • Marlene Silva Marchena +

  • Martin Babka +

  • MatanCohe +

  • Mateusz Woś +

  • Mathew Topper +

  • Matt Boggess +

  • Matt Cooper +

  • Matt Williams +

  • Мэттью Гилберт

  • Мэтью Рёшке

  • Max Kanter

  • Michael Odintsov

  • Michael Silverstein +

  • Michael-J-Ward +

  • Микаэль Шоэнтген +

  • Miguel Sánchez de León Peque +

  • Ming Li

  • Mitar

  • Mitch Negus

  • Monson Shao +

  • Moonsoo Kim +

  • Mortada Mehyar

  • Myles Braithwaite

  • Nehil Jain +

  • Nicholas Musolino +

  • Nicolas Dickreuter +

  • Nikhil Kumar Mengani +

  • Nikoleta Glynatsi +

  • Ondrej Kokes

  • Pablo Ambrosio +

  • Pamela Wu +

  • Parfait G +

  • Patrick Park +

  • Paul

  • Paul Ganssle

  • Пол Риди

  • Paul van Mulbregt +

  • Филлип Клауд

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

  • Piyush Aggarwal +

  • Prabakaran Kumaresshan +

  • Pulkit Maloo

  • Pyry Kovanen

  • Rajib Mitra +

  • Redonnet Louis +

  • Rhys Parry +

  • Rick +

  • Robin

  • Roei.r +

  • RomainSa +

  • Роман Иманкулов +

  • Roman Yurchak +

  • Ruijing Li +

  • Ryan +

  • Ryan Nazareth +

  • Rüdiger Busche +

  • SEUNG HOON, SHIN +

  • Sandrine Pataut +

  • Sangwoong Yoon

  • Santosh Kumar +

  • Saurav Chakravorty +

  • Скотт МакАллистер +

  • Sean Chan +

  • Шади Акики +

  • Shengpu Tang +

  • Шириш Кадам +

  • Simon Hawkins +

  • Simon Riddell +

  • Simone Basso

  • Sinhrks

  • Soyoun(Rose) Kim +

  • Шринивас Редди Татипарти (శ్రీనివాస్ రెడ్డి తాటిపర్తి) +

  • Stefaan Lippens +

  • Стефано Чианчиулли

  • Stefano Miccoli +

  • Stephen Childs

  • Stephen Pascoe

  • Стив Бейкер +

  • Steve Cook +

  • Steve Dower +

  • Stéphan Taljaard +

  • Sumin Byeon +

  • Sören +

  • Tamas Nagy +

  • Таня Джайн +

  • Tarbo Fukazawa

  • Thein Oo +

  • Thiago Cordeiro da Fonseca +

  • Thierry Moisan

  • Thiviyan Thanapalasingam +

  • Thomas Lentali +

  • Tim D. Smith +

  • Tim Swast

  • Tom Augspurger

  • Tomasz Kluczkowski +

  • Tony Tao +

  • Triple0 +

  • Troels Nielsen +

  • Tuhin Mahmud +

  • Тайлер Редди +

  • Uddeshya Singh

  • Uwe L. Korn +

  • Vadym Barda +

  • Varad Gunjal +

  • Victor Maryama +

  • Victor Villas

  • Vincent La

  • Vitória Helena +

  • Vu Le

  • Вьом Джайн +

  • Weiwen Gu +

  • Wenhuan

  • Wes Turner

  • Wil Tan +

  • William Ayd

  • Yeojin Kim +

  • Yitzhak Andrade +

  • Yuecheng Wu +

  • Yuliya Dovzhenko +

  • Юрий Байда +

  • Zac Hatfield-Dodds +

  • aberres +

  • aeltanawy +

  • ailchau +

  • alimcmaster1

  • alphaCTzo7G +

  • amphy +

  • araraonline +

  • azure-pipelines[bot] +

  • benarthur91 +

  • bk521234 +

  • cgangwar11 +

  • chris-b1

  • cxl923cc +

  • dahlbaek +

  • dannyhyunkim +

  • darke-spirits +

  • david-liu-brattle-1

  • davidmvalente +

  • deflatSOCO

  • doosik_bae +

  • dylanchase +

  • eduardo naufel schettino +

  • euri10 +

  • evangelineliu +

  • fengyqf +

  • fjdiod

  • fl4p +

  • fleimgruber +

  • gfyoung

  • h-vetinari

  • harisbal +

  • henriqueribeiro +

  • himanshu awasthi

  • hongshaoyang +

  • igorfassen +

  • jalazbe +

  • jbrockmendel

  • jh-wu +

  • justinchan23 +

  • louispotok

  • marcosrullan +

  • miker985

  • nicolab100 +

  • nprad

  • нсуреш +

  • ottiP

  • pajachiet +

  • raguiar2 +

  • ratijas +

  • realead +

  • robbuckley +

  • saurav2608 +

  • sideeye +

  • ssikdar1

  • svenharris +

  • syutbai +

  • testvinder +

  • thatneat

  • tmnhat2001

  • tomascassidy +

  • tomneep

  • topper-123

  • vkk800 +

  • winlu +

  • ym-pett +

  • yrhooke +

  • ywpark1 +

  • zertrin

  • zhezherun +