Примечания к выпуску NumPy 1.24#

Выпуск NumPy 1.24.0 продолжает текущую работу по улучшению обработки и продвижения типов данных, увеличению скорости выполнения и уточнению документации. Также есть большое количество новых и устаревших устареваний из-за изменений в продвижении и очистках. Это можно назвать выпуском устареваний. Основные моменты:

  • Много новых устареваний, проверьте их.

  • Многие устаревшие уведомления,

  • Новые функции и исправления F2PY.

  • Новые ключевые слова "dtype" и "casting" для функций объединения.

Подробности см. ниже,

Эта версия поддерживает Python версий 3.8-3.11.

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

Устаревание fastCopyAndTranspose и PyArray_CopyAndTranspose#

The numpy.fastCopyAndTranspose функция устарела. Используйте соответствующие методы copy и transpose напрямую:

arr.T.copy()

Базовая C-функция PyArray_CopyAndTranspose также устарел в C-API NumPy.

(gh-22313)

Преобразование целых чисел Python вне диапазона#

Попытка преобразования целого числа Python в значение NumPy теперь всегда проверяет, может ли результат быть представлен NumPy. Это означает, что следующие примеры в будущем будут завершаться неудачей и выдавать DeprecationWarning теперь:

np.uint8(-1)
np.array([3000], dtype=np.int8)

Многие из них ранее успешно работали. Такой код в основном был полезен для беззнаковых целых чисел с отрицательными значениями, такими как np.uint8(-1) давая np.iinfo(np.uint8).max.

Обратите внимание, что преобразование между целыми числами NumPy не затрагивается, так что np.array(-1).astype(np.uint8) продолжает работать и использовать логику переполнения целых чисел C. Для отрицательных значений это также будет работать для просмотра массива: np.array(-1, dtype=np.int8).view(np.uint8). В некоторых случаях использование np.iinfo(np.uint8).max или val % 2**8 также может хорошо работать.

В редких случаях входные данные могут смешивать как отрицательные значения, так и очень большие беззнаковые значения (т.е. -1 и 2**63). Там, к сожалению, необходимо использовать % на основе значения Python или использовать преобразование со знаком или без знака в зависимости от того, ожидаются ли отрицательные значения.

(gh-22385)

Устарело msort#

The numpy.msort функция устарела. Используйте np.sort(a, axis=0) вместо этого.

(gh-22456)

np.str0 и аналогичные теперь устарели#

Псевдонимы скалярных типов, оканчивающиеся на 0-битный размер: np.object0, np.str0, np.bytes0, np.void0, np.int0, np.uint0 а также np.bool8 теперь устарели и в конечном итоге будут удалены.

(gh-22607)

Устаревшие устаревания#

  • The normed аргумент ключевого слова был удален из np.histogram, np.histogram2d, и np.histogramdd. Используйте density вместо. Если normed был передан по позиции, density MarsGuy +

    (gh-21645)

  • Создание рваного массива теперь всегда вызывает ValueError если только dtype=object передаётся. Это включает очень глубоко вложенные последовательности.

    (gh-22004)

  • Поддержка Visual Studio 2015 и более ранних версий удалена.

  • Поддержка POSIX-слоя взаимодействия Windows Interix удалена.

    (gh-22139)

  • Поддержка Cygwin < 3.3 была удалена.

    (gh-22159)

  • Метод mini() из np.ma.MaskedArray был удалён. Используйте либо np.ma.MaskedArray.min() или np.ma.minimum.reduce().

  • Форма с одним аргументом функции np.ma.minimum и np.ma.maximum был удален. Используйте np.ma.minimum.reduce() или np.ma.maximum.reduce() вместо этого.

    (gh-22228)

  • Передача экземпляров dtype, отличных от канонических (в основном с нативным порядком байтов), в dtype= или signature= в ufunc теперь будет вызывать TypeError. Мы рекомендуем передавать строки "int8" или скалярные типы np.int8 поскольку порядок байтов, единица даты/времени и т.д. никогда не применяются. (Изначально устарело в NumPy 1.21.)

    (gh-22540)

  • The dtype= Аргумент для функций сравнения ufuncs теперь применяется корректно. Это означает, что только bool и object являются допустимыми значениями и dtype=object применяется.

    (gh-22541)

  • Устаревание для псевдонимов np.object, np.bool, np.float, np.complex, np.str, и np.int истек (вводит NumPy 1.20). Некоторые из них теперь будут выдавать FutureWarning в дополнение к вызову ошибки, поскольку в будущем они будут отображаться на скаляры NumPy.

    (gh-22607)

Примечания по совместимости#

array.fill(scalar) может вести себя немного иначе#

numpy.ndarray.fill в некоторых случаях может вести себя немного иначе теперь из-за того, что логика согласована с присваиванием элементов:

arr = np.array([1])  # with any dtype/value
arr.fill(scalar)
# is now identical to:
arr[0] = scalar

Ранее приведение типов могло давать немного разные результаты при использовании значений, которые не могли быть представлены в целевом dtype или когда цель имела object тип данных.

(gh-20924)

Приведение подмассива к объекту теперь копирует#

Приведение dtype, включающего подмассив, к объекту теперь гарантирует копию подмассива. Ранее возвращалось небезопасное представление:

arr = np.ones(3, dtype=[("f", "i", 3)])
subarray_fields = arr.astype(object)[0]
subarray = subarray_fields[0]  # "f" field

np.may_share_memory(subarray, arr)

Теперь всегда false. Ранее это было true для конкретного приведения.

(gh-21925)

Возвращаемые массивы учитывают уникальность объектов kwarg dtype#

Когда dtype ключевой аргумент используется с array или asarray, dtype возвращаемого массива теперь всегда точно соответствует dtype, предоставленному вызывающей стороной.

В некоторых случаях это изменение означает, что представление вместо входного массива возвращается. Следующий пример демонстрирует это на 64-битном Linux, где long и longlong имеют одинаковую точность, но различаются dtypes:

>>> arr = np.array([1, 2, 3], dtype="long")
>>> new_dtype = np.dtype("longlong")
>>> new = np.asarray(arr, dtype=new_dtype)
>>> new.dtype is new_dtype
True
>>> new is arr
False

До изменения, dtype не совпало, потому что new is arr был True.

(gh-21995)

Экспорт DLPack вызывает BufferError#

Когда буфер массива не может быть экспортирован через DLPack, возникает BufferError теперь всегда вызывается там, где ранее TypeError или RuntimeError было вызвано. Это позволяет вернуться к протоколу буфера или __array_interface__ когда DLPack был попробован первым.

(gh-22542)

Сборки NumPy больше не тестируются на GCC-6#

Ubuntu 18.04 устарел для GitHub Actions, и GCC-6 недоступен на Ubuntu 20.04, поэтому сборки с этим компилятором больше не тестируются. Мы все еще тестируем сборки с использованием GCC-7 и GCC-8.

(gh-22598)

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

Новый атрибут symbol добавлено в полиномиальные классы#

Классы полиномов в numpy.polynomial пакет имеет новый symbol атрибут, который используется для представления неизвестной переменной полинома. Это можно использовать для изменения значения переменной при выводе:

>>> P_y = np.polynomial.Polynomial([1, 0, -1], symbol="y")
>>> print(P_y)
1.0 + 0.0·y¹ - 1.0·y²

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

>>> P = np.polynomial.Polynomial([1, -1])  # default symbol is "x"
>>> P_z = np.polynomial.Polynomial([1, 1], symbol="z")
>>> P * P_z
Traceback (most recent call last)
   ...
ValueError: Polynomial symbols differ

Символом может быть любой допустимый идентификатор Python. По умолчанию это symbol=x, согласованно с существующим поведением.

(gh-16154)

Поддержка F2PY для Fortran character строки#

F2PY теперь поддерживает обёртывание функций Fortran с:

  • символ (например, character x)

  • символьный массив (например, character, dimension(n) :: x)

  • символьная строка (например, character(len=10) x)

  • и массив строк символов (например, character(len=10), dimension(n, m) :: x)

аргументы, включая передачу строк Python Unicode в качестве аргументов строк Fortran.

(gh-19388)

Новая функция np.show_runtime#

Новая функция numpy.show_runtime был добавлен для отображения информации о времени выполнения машины в дополнение к numpy.show_config который отображает информацию, связанную со сборкой.

(gh-21468)

strict опция для testing.assert_array_equal#

The strict опция теперь доступна для testing.assert_array_equal. Установка strict=True отключит поведение вещания для скаляров и обеспечит, чтобы входные массивы имели одинаковый тип данных.

(gh-21595)

Новый параметр equal_nan добавлен в np.unique#

np.unique был изменен в 1.21 для обработки всех NaN значения как равные и возвращает единственное NaN. Установка equal_nan=False восстановит поведение до версии 1.21 для обработки NaNs как уникальные. По умолчанию True.

(gh-21623)

casting и dtype именованные аргументы для numpy.stack#

The casting и dtype аргументы ключевых слов теперь доступны для numpy.stack. Чтобы использовать их, напишите np.stack(..., dtype=None, casting='same_kind').

casting и dtype именованные аргументы для numpy.vstack#

The casting и dtype аргументы ключевых слов теперь доступны для numpy.vstack. Чтобы использовать их, напишите np.vstack(..., dtype=None, casting='same_kind').

casting и dtype именованные аргументы для numpy.hstack#

The casting и dtype аргументы ключевых слов теперь доступны для numpy.hstack. Чтобы использовать их, напишите np.hstack(..., dtype=None, casting='same_kind').

(gh-21627)

Базовый генератор битов, лежащий в основе синглтона RandomState, может быть изменён#

Синглтон RandomState экземпляр, представленный в numpy.random модуль инициализируется при запуске с MT19937 генератор битов. Новая функция set_bit_generator позволяет заменить генератор битов по умолчанию на предоставленный пользователем генератор битов. Эта функция была введена для предоставления метода, позволяющего бесшовно интегрировать высококачественный современный генератор битов в новый код с существующим кодом, который использует функции генерации случайных величин, предоставляемые синглтоном. Сопутствующая функция get_bit_generator возвращает текущий генератор битов, используемый синглтоном RandomState. Это предоставлено для упрощения восстановления исходного источника случайности, если требуется.

Предпочтительный метод для генерации воспроизводимых случайных чисел — использовать современный генератор битов в экземпляре Generator. Функция default_rng упрощает создание экземпляра:

>>> rg = np.random.default_rng(3728973198)
>>> rg.random()

Тот же генератор случайных чисел может затем быть общим с экземпляром-одиночкой, так что вызов функций в random модуль будет использовать тот же генератор случайных чисел:

>>> orig_bit_gen = np.random.get_bit_generator()
>>> np.random.set_bit_generator(rg.bit_generator)
>>> np.random.normal()

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

>>> np.random.set_bit_generator(orig_bit_gen)

(gh-21976)

np.void теперь имеет dtype аргумент#

NumPy теперь позволяет создавать структурированные void скаляры напрямую, передавая dtype аргумент для np.void.

(gh-22316)

Улучшения#

Улучшения F2PY#

  • Сгенерированные модули расширений больше не используют устаревший NumPy-C API

  • Улучшено f2py сгенерированные сообщения об исключениях

  • Многочисленные исправления ошибок и flake8 исправления предупреждений

  • различные макросы CPP, которые можно использовать в C-выражениях файлов сигнатур, имеют префикс f2py_. Например, следует использовать f2py_len(x) вместо len(x)

  • Новая конструкция character(f2py_len=...) введён для поддержки возврата строк символов предполагаемой длины (например, character(len=*)) из функций-обёрток

Хук для поддержки перезаписи f2py внутренние структуры данных после чтения всех входных файлов. Это требуется, например, для обратной совместимости поддержки SciPy, где символьные аргументы обрабатываются как строковые аргументы в C выражения.

(gh-19388)

IBM zSystems Vector Extension Facility (SIMD)#

Добавлена поддержка SIMD-расширений zSystem (z13, z14, z15) через интерфейс универсальных внутренних функций. Эта поддержка приводит к повышению производительности для всех SIMD-ядер, реализованных с использованием универсальных внутренних функций, включая следующие операции: rint, floor, trunc, ceil, sqrt, absolute, square, reciprocal, tanh, sin, cos, equal, not_equal, greater, greater_equal, less, less_equal, maximum, minimum, fmax, fmin, argmax, argmin, add, subtract, multiply, divide.

(gh-20913)

NumPy теперь выдает ошибки с плавающей запятой при приведениях типов#

В большинстве случаев NumPy ранее не выдавал предупреждений или ошибок с плавающей точкой, когда это происходило при приведениях. Например, приведения типа:

np.array([2e300]).astype(np.float32)  # overflow for float32
np.array([np.inf]).astype(np.int64)

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

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

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

arr = np.full(100, fill_value=1000, dtype=np.float64)
arr.astype(np.int8)

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

arr.astype(np.int64).astype(np.int8)

Может возвращать неопределённый результат с установленным предупреждением:

RuntimeWarning: invalid value encountered in cast

Точное поведение зависит от стандарта C99 и его реализации как в программном обеспечении, так и в аппаратном обеспечении.

(gh-21437)

F2PY поддерживает атрибут value#

Стандарт Fortran требует, чтобы переменные, объявленные с value атрибут должен передаваться по значению, а не по ссылке. F2PY теперь правильно поддерживает этот шаблон использования. Так что integer, intent(in), value :: x в кодах Fortran будут сгенерированы правильные обертки.

(gh-21807)

Добавлена поддержка pickle для сторонних генераторов битов#

Формат pickle для битовых генераторов был расширен, чтобы позволить каждому битовому генератору предоставлять собственный конструктор при упаковке. Предыдущие версии NumPy поддерживали только распаковку Generator экземпляры, созданные с одним из основных наборов генераторов битов, поставляемых с NumPy. Попытка распаковать Generator которые использовали сторонние генераторы битов, завершались неудачей, поскольку конструктор, используемый при распаковке, знал только о генераторах битов, включенных в NumPy.

(gh-22014)

arange() теперь явно завершается ошибкой с dtype=str#

Ранее np.arange(n, dtype=str) функция работала для n=1 и n=2, но будет вызывать неспецифическое сообщение об исключении для других значений n. Теперь он вызывает TypeError информируя, что arange не поддерживает строковые типы данных:

>>> np.arange(2, dtype=str)
Traceback (most recent call last)
   ...
TypeError: arange() not supported for inputs with DType .

(gh-22055)

numpy.typing протоколы теперь проверяются во время выполнения#

Протоколы, используемые в numpy.typing.ArrayLike и numpy.typing.DTypeLike теперь правильно помечены как проверяемые во время выполнения, что упрощает их использование для проверки типов во время выполнения.

(gh-22357)

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

Более быстрая версия np.isin и np.in1d для целочисленных массивов#

np.in1d (используется np.isin) теперь может переключаться на более быстрый алгоритм (до >10x быстрее), когда ему передаются два целочисленных массива. Это часто используется автоматически, но вы можете использовать kind="sort" или kind="table" чтобы принудительно использовать старый или новый метод соответственно.

(gh-12065)

Более быстрые операторы сравнения#

Функции сравнения (numpy.equal, numpy.not_equal, numpy.less, numpy.less_equal, numpy.greater и numpy.greater_equal) теперь гораздо быстрее, так как они векторизованы с помощью универсальных внутренних функций. Для процессора с расширением SIMD AVX512BW прирост производительности составляет до 2.57x, 1.65x и 19.15x для целочисленных, вещественных и булевых типов данных соответственно (при N=50000).

(gh-21483)

Изменения#

Улучшенное сообщение о переполнении целочисленного деления#

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

>>> np.array([np.iinfo(np.int32).min]*10, dtype=np.int32) // np.int32(-1)
:1: RuntimeWarning: divide by zero encountered in floor_divide
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int32)

Переполнение целочисленного деления теперь возвращает минимальное значение входного dtype и вызывает следующее RuntimeWarning:

>>> np.array([np.iinfo(np.int32).min]*10, dtype=np.int32) // np.int32(-1)
:1: RuntimeWarning: overflow encountered in floor_divide
array([-2147483648, -2147483648, -2147483648, -2147483648, -2147483648,
       -2147483648, -2147483648, -2147483648, -2147483648, -2147483648],
      dtype=int32)

(gh-21506)

masked_invalid теперь изменяет маску на месте#

При использовании с copy=False, numpy.ma.masked_invalid теперь изменяет входной маскированный массив на месте. Это заставляет его вести себя идентично masked_where и лучше соответствует документации.

(gh-22046)

nditer/NpyIter позволяет выделить все операнды#

Итератор NumPy, доступный через np.nditer в Python и как NpyIter в C теперь поддерживает выделение всех массивов. Форма итератора по умолчанию равна () в этом случае. Тип данных операнда должен быть предоставлен, поскольку «общий тип данных» не может быть выведен из других входных данных.

(gh-22457)