Примечания к выпуску 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был передан по позиции,densityMarsGuy +(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)