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

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

  • Поддержка MUSL, теперь доступны колеса (wheels) для MUSL.

  • Поддержка компилятора Fujitsu C/C++.

  • Массивы объектов теперь поддерживаются в einsum

  • Поддержка умножения матриц на месте (@=).

Мы выпустим NumPy 1.26, когда выйдет Python 3.12. Это необходимо, потому что distutils был удален в Python 3.12, и мы перейдем на использование meson для будущих сборок. Следующий основной выпуск будет NumPy 2.0.0. Мы планируем, что серия 2.0 по-прежнему будет поддерживать проекты, созданные для более ранних версий NumPy.

Поддерживаемые версии Python в этом выпуске: 3.9-3.11.

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

  • np.core.MachAr устарел. Это частный API. В именах, определенных в np.core обычно следует считать приватным.

    (gh-22638)

  • np.finfo(None) устарело.

    (gh-23011)

  • np.round_ устарел. Используйте np.round вместо этого.

    (gh-23302)

  • np.product устарел. Используйте np.prod вместо этого.

    (gh-23314)

  • np.cumproduct устарел. Используйте np.cumprod вместо этого.

    (gh-23314)

  • np.sometrue устарел. Используйте np.any вместо этого.

    (gh-23314)

  • np.alltrue устарел. Используйте np.all вместо этого.

    (gh-23314)

  • Только массивы ndim-0 обрабатываются как скаляры. NumPy раньше обрабатывал все массивы размера 1 (например, np.array([3.14])) как скаляры. В будущем это будет ограничено массивами с ndim 0 (например, np.array(3.14)). Следующие выражения будут выдавать предупреждение об устаревании:

    a = np.array([3.14])
    float(a)  # better: a[0] to get the numpy.float or a.item()
    
    b = np.array([[3.14]])
    c = numpy.random.rand(10)
    c[0] = b  # better: c[0] = b[0, 0]
    

    (gh-10615)

  • np.find_common_type устарело. numpy.find_common_type теперь устарел, и его использование следует заменить либо на numpy.result_type или numpy.promote_types. Большинство пользователей оставляют второй scalar_types аргумент для find_common_type как [] в этом случае np.result_type и np.promote_types являются одновременно быстрее и надежнее. При неиспользовании scalar_types Основное отличие заключается в том, что замена намеренно преобразует порядок байтов, отличный от нативного, в нативный порядок байтов. Кроме того, find_common_type возвращает object dtype, а не неудачное продвижение. Это приводит к различиям, когда входные данные не все числовые. Важно, что это также происходит, например, для timedelta/datetime, для которых правила продвижения NumPy в настоящее время иногда удивительны.

    Когда scalar_types аргумент не [] все сложнее. В большинстве случаев использование np.result_type и передача значений Python 0, 0.0, или 0j дает тот же результат, что и использование int, float, или complex в scalar_types.

    Когда scalar_types создается, np.result_type является правильной заменой и может принимать скалярные значения, такие как np.float32(0.0). Передача значений, отличных от 0, может привести к поведению проверки значений (что np.find_common_type никогда не используется, и NEP 50 может измениться в будущем). Основное возможное изменение поведения в этом случае — когда типы массивов являются знаковыми целыми числами, а типы скаляров — беззнаковыми.

    Если вы не уверены, как заменить использование scalar_types или когда вероятны нечисловые типы данных, пожалуйста, не стесняйтесь открывать проблему в NumPy, чтобы попросить о помощи.

    (gh-22539)

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

  • np.core.machar и np.finfo.machar были удалены.

    (gh-22638)

  • +arr теперь будет вызывать ошибку, когда тип данных не является числовым (и положительное значение не определено).

    (gh-22998)

  • Теперь последовательность должна передаваться в семейство функций объединения (stack, vstack, hstack, dstack и column_stack).

    (gh-23019)

  • np.clip теперь по умолчанию использует приведение того же типа. Возврат к небезопасному приведению был объявлен устаревшим в NumPy 1.17.

    (gh-23403)

  • np.clip теперь будет распространять np.nan значения, передаваемые как min или max. Ранее скаляр NaN обычно игнорировался. Это было устаревшим в NumPy 1.17.

    (gh-23403)

  • The np.dual подмодуль был удален.

    (gh-23480)

  • NumPy теперь всегда игнорирует поведение последовательности для массивоподобных объектов (определяющих один из протоколов массивов). (Устаревание началось в NumPy 1.20)

    (gh-23660)

  • Ниша FutureWarning при приведении к подмассивному типу данных в astype или функции создания массивов, такие как asarray теперь финализирован. Поведение теперь всегда такое же, как если бы подмассив dtype был обёрнут в одно поле (что было обходным решением ранее). (FutureWarning начиная с NumPy 1.20)

    (gh-23666)

  • == и != предупреждения были завершены. Параметр == и != операторы над массивами теперь всегда:

    • вызывать ошибки, возникающие во время сравнений, например, когда массивы имеют несовместимые формы (np.array([1, 2]) == np.array([1, 2, 3])).

    • возвращает массив всех True или все False когда значения принципиально несравнимы (например, имеют разные типы данных). Примером является np.array(["a"]) == np.array([1]).

      Это имитирует поведение Python, возвращающее False и True при сравнении несовместимых типов, таких как "a" == 1 и "a" != 1. В течение долгого времени они давали DeprecationWarning или FutureWarning.

    (gh-22707)

  • Поддержка Nose удалена. NumPy перешёл на использование pytest в 2018 году, а nose не поддерживается много лет. Мы сохраняли поддержку nose в NumPy, чтобы не сломать зависимые проекты, которые могли его использовать и ещё не перешли на pytest или другую тестовую среду. С появлением Python 3.12, непропатченный nose будет вызывать ошибку. Пришло время двигаться дальше.

    Декораторы удалены:

    • вызывает

    • медленно

    • setastest

    • skipif

    • knownfailif

    • устаревший

    • parametrize

    • _needs_refcount

    Их не следует путать с версиями pytest с похожими названиями, например, pytest.mark.slow, pytest.mark.skipif, pytest.mark.parametrize.

    Удалённые функции:

    • Тестер

    • import_nose

    • run_module_suite

    (gh-23041)

  • The numpy.testing.utils прослойка была удалена. Импорт из numpy.testing.utils прослойка была устаревшей с 2019 года, теперь она удалена. Все импорты должны выполняться напрямую из numpy.testing.

    (gh-23060)

  • Переменная окружения для отключения диспетчеризации была удалена. Поддержка для NUMPY_EXPERIMENTAL_ARRAY_FUNCTION переменная окружения была удалена. Эта переменная отключала диспетчеризацию с __array_function__.

    (gh-23376)

  • Поддержка y= как псевдоним для out= был удален. fix, isposinf и isneginf функции позволяли использовать y= как (устаревший) псевдоним для out=. Это больше не поддерживается.

    (gh-23376)

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

  • The busday_count метод теперь корректно обрабатывает случаи, когда begindates позже по времени, чем enddates. Ранее, enddates был включён, хотя документация утверждает, что он всегда исключается.

    (gh-23229)

  • При сравнении дат и временных интервалов с использованием np.equal или np.not_equal numpy ранее разрешал сравнение с casting="unsafe". Эта операция теперь завершается неудачей. Принудительное указание типа выходных данных с помощью dtype kwarg может позволить операции завершиться успешно, но мы не рекомендуем это.

    (gh-22707)

  • При загрузке данных из файлового дескриптора с использованием np.load, если указатель находится в конце файла, что может произойти при чтении нескольких массивов путем вызова np.load повторно, numpy ранее вызывал ValueError if allow_pickle=False, и OSError if allow_pickle=True. Теперь вызывает EOFError вместо этого, в обоих случаях.

    (gh-23105)

np.pad с mode=wrap дополняет строгими кратными исходных данных#

Код на основе более ранней версии pad который использует mode="wrap" будет возвращать разные результаты, когда размер заполнения больше исходного массива.

np.pad с mode=wrap теперь всегда заполняет пространство строгими кратными исходным данным, даже если размер заполнения больше начального массива.

(gh-22575)

Cython long_t и ulong_t удалено#

long_t и ulong_t были псевдонимами для longlong_t и ulonglong_t и запутанным (наследие Python 2). Это изменение может привести к ошибкам:

'long_t' is not a type identifier
'ulong_t' is not a type identifier

Мы рекомендуем использование типов с размером в битах, таких как cnp.int64_t или использование cnp.intp_t который составляет 32 бита на 32-битных системах и 64 бита на 64-битных системах (это наиболее совместимо с индексацией). Если C long если требуется, используйте обычный long или npy_long. cnp.int_t также long (целое число по умолчанию NumPy). Однако, long имеет 32 бита на 64-битных системах Windows, и мы, возможно, захотим скорректировать это даже в NumPy. (Пожалуйста, не стесняйтесь обращаться к разработчикам NumPy, если вам интересно это.)

(gh-22637)

Изменено сообщение об ошибке и тип для некорректного axes аргумент для ufunc#

Сообщение об ошибке и тип, когда неправильный axes значение передается в ufunc(..., axes=[...])` изменилось. Сообщение теперь более точно указывает на проблему, и если значение не совпадает, то AxisError будет вызвано исключение. A TypeError по-прежнему будет вызываться для недопустимых типов входных данных.

(gh-22675)

Объекты, подобные массивам, которые определяют __array_ufunc__ теперь может переопределять ufuncs, если используется как where#

Если where именованный аргумент numpy.ufunc является подклассом numpy.ndarray или является утиным типом, который определяет numpy.class.__array_ufunc__ он может переопределить поведение ufunc используя тот же механизм, что и входные и выходные аргументы. Обратите внимание, что для правильной работы where.__array_ufunc__ реализации придется развернуть where аргумент для передачи в стандартную реализацию ufunc или, для numpy.ndarray подклассы перед использованием super().__array_ufunc__.

(gh-23240)

Компиляция против C API NumPy теперь по умолчанию обратно совместима#

NumPy теперь по умолчанию предоставляет обратно совместимое подмножество C-API. Это делает использование oldest-supported-numpy необязательно. Библиотеки могут переопределить минимальную версию по умолчанию для совместимости с использованием:

#define NPY_TARGET_VERSION NPY_1_22_API_VERSION

перед включением NumPy или передачей эквивалентного -D опция для компилятора. По умолчанию в NumPy 1.25 используется NPY_1_19_API_VERSION. Поскольку C API NumPy 1.19 был идентичен NumPy 1.16, результирующие программы будут совместимы с NumPy 1.16 (с точки зрения C-API). Это значение по умолчанию будет увеличено в будущих неисправленных выпусках. Вы всё ещё можете компилировать против более старой версии NumPy и запускать на более новой.

Для получения дополнительных сведений см. Для авторов нижестоящих пакетов.

(cyan_text)

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

np.einsum теперь принимает массивы с object dtype#

Путь выполнения вызовет операторы Python для массивов с типом object, подобно np.dot и np.matmul.

(gh-18053)

Добавить поддержку умножения матриц на месте#

Теперь возможно выполнить умножение матриц на месте через @= оператор.

>>> import numpy as np

>>> a = np.arange(6).reshape(3, 2)
>>> print(a)
[[0 1]
 [2 3]
 [4 5]]

>>> b = np.ones((2, 2), dtype=int)
>>> a @= b
>>> print(a)
[[1 1]
 [5 5]
 [9 9]]

(gh-21120)

Добавлен NPY_ENABLE_CPU_FEATURES переменная окружения#

Пользователи теперь могут выбрать включение только подмножества встроенных функций ЦП во время выполнения, указав NPY_ENABLE_CPU_FEATURES переменная окружения. Обратите внимание, что указанные функции должны быть вне базовых, поскольку они всегда предполагаются. Будут возникать ошибки при попытке включить функцию, которая либо не поддерживается вашим процессором, либо с которой NumPy не был собран.

(gh-22137)

NumPy теперь имеет np.exceptions пространство имён#

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

(gh-22644)

np.linalg функции возвращают NamedTuples#

np.linalg функции, которые раньше возвращали кортежи, теперь возвращают namedtuples. Эти функции включают eig(), eigh(), qr(), slogdet(), и svd(). Тип возвращаемого значения не изменяется в случаях, когда эти функции возвращают не кортежи с определенными именованными аргументами (как svd(compute_uv=False)).

(gh-22786)

Строковые функции в np.char совместимы с пользовательскими типами данных NEP 42#

Пользовательские типы данных, представляющие строки Unicode или байтовые строки, теперь могут быть переданы в строковые функции в np.char.

(gh-22863)

Экземпляры строкового dtype могут быть созданы из абстрактных классов строкового dtype#

Теперь можно создать экземпляр строкового dtype с размером без использования строкового имени dtype. Например, type(np.dtype('U'))(8) создаст тип данных, эквивалентный np.dtype('U8'). Эта функция наиболее полезна при написании универсального кода, работающего с классами строковых типов данных.

(gh-22963)

Теперь поддерживается компилятор Fujitsu C/C++#

Добавлена поддержка компилятора Fujitsu. Для сборки с компилятором Fujitsu выполните:

python setup.py build -c fujitsu

SSL2 теперь поддерживается#

Добавлена поддержка SSL2. SSL2 — это библиотека, предоставляющая совместимые с OpenBLAS функции GEMM. Для включения SSL2 необходимо отредактировать site.cfg и собрать с компилятором Fujitsu. См. site.cfg.example.

(gh-22982)

Улучшения#

NDArrayOperatorsMixin указывает, что он не имеет __slots__#

The NDArrayOperatorsMixin класс теперь указывает, что он не содержит __slots__, обеспечивая, что подклассы теперь могут использовать эту функцию в Python.

(gh-23113)

Исправление степени комплексного нуля#

np.power теперь возвращает другой результат для 0^{non-zero} для комплексных чисел. Обратите внимание, что значение определено только когда вещественная часть показателя больше нуля. Ранее возвращалось NaN, если мнимая часть не была строго нулевой. Возвращаемое значение — либо 0+0j или 0-0j.

(gh-18535)

Новый DTypePromotionError#

NumPy теперь имеет новый DTypePromotionError который используется, когда два типа данных не могут быть приведены к общему, например:

np.result_type("M8[s]", np.complex128)

вызывает это новое исключение.

(gh-22707)

np.show_config использует информацию из Meson#

Информация о сборке и системе теперь содержит информацию от Meson. np.show_config теперь имеет новый необязательный параметр mode для настройки вывода.

(gh-22769)

Исправление np.ma.diff не сохраняет маску при вызове с аргументами prepend/append.#

Вызов np.ma.diff с аргументами prepend и/или append теперь возвращает MaskedArray с сохранением входной маски.

Ранее, MaskedArray без маски был возвращён.

(gh-22776)

Исправлена обработка ошибок для NumPy C-API в Cython#

Многие функции C NumPy, определённые для использования в Cython, не имели правильного индикатора ошибки, такого как except -1 или except *. Теперь они были добавлены.

(gh-22997)

Возможность напрямую создавать генераторы случайных чисел#

numpy.random.Generator.spawn теперь позволяет напрямую создавать новые независимые дочерние генераторы через numpy.random.SeedSequence.spawn механизм. numpy.random.BitGenerator.spawn делает то же самое для базового генератора битов.

Дополнительно, numpy.random.BitGenerator.seed_seq теперь дает прямой доступ к последовательности начальных значений, используемой для инициализации генератора битов. Это позволяет, например:

seed = 0x2e09b90939db40c400f8f22dae617151
rng = np.random.default_rng(seed)
child_rng1, child_rng2 = rng.spawn(2)

# safely use rng, child_rng1, and child_rng2

Ранее это было сложно сделать без передачи SeedSequence явно. Пожалуйста, смотрите numpy.random.SeedSequence для получения дополнительной информации.

(gh-23195)

numpy.logspace теперь поддерживает нескалярный base аргумент#

The base аргумент numpy.logspace теперь может быть похожим на массив, если он совместим с start и stop аргументы.

(gh-23275)

np.ma.dot() теперь поддерживает не-2D массивы#

Ранее np.ma.dot() работало только если a и b были оба двумерными. Теперь это работает и для не-двумерных массивов, а также для np.dot().

(gh-23322)

Явно показывать ключи файла .npz в repr#

NpzFile показывает ключи загруженного файла .npz при печати.

>>> npzfile = np.load('arr.npz')
>>> npzfile
NpzFile 'arr.npz' with keys arr_0, arr_1, arr_2, arr_3, arr_4...

(gh-23357)

NumPy теперь предоставляет классы DType в np.dtypes#

Новый numpy.dtypes модуль теперь предоставляет классы DType и будет содержать будущую функциональность, связанную с типами данных. Большинству пользователей не требуется напрямую использовать эти классы.

(gh-23358)

Удаление метаданных dtype перед сохранением в файлы .npy или .npz#

В настоящее время, *.npy файл, содержащий таблицу с dtype с метаданными, не может быть прочитан обратно. Теперь np.save и np.savez удалить метаданные перед сохранением.

(gh-23371)

numpy.lib.recfunctions.structured_to_unstructured возвращает представления в большем количестве случаев#

structured_to_unstructured теперь возвращает представление, если шаг между полями постоянен. Ранее отступы между полями или обратное поле приводили к копированию. Это изменение применяется только к ndarray, memmap и recarrayДля всех остальных подклассов массивов поведение остается неизменным.

(gh-23652)

Знаковые и беззнаковые целые числа всегда сравниваются корректно#

Когда uint64 и int64 смешиваются в NumPy, NumPy обычно повышает оба до float64. Это поведение может вызывать споры, но сбивает с толку при сравнениях ==, <=, поскольку возвращаемые результаты могут быть некорректными, но преобразование скрыто, так как результат является булевым. NumPy теперь будет возвращать корректные результаты, избегая приведения к float.

(gh-23713)

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

Быстрее np.argsort на процессорах с поддержкой AVX-512#

32-битный и 64-битный алгоритм быстрой сортировки для np.argsort дает ускорение до 6 раз на процессорах, поддерживающих набор инструкций AVX-512.

Благодаря Корпорация Intel за спонсирование этой работы.

(gh-23707)

Быстрее np.sort на процессорах с поддержкой AVX-512#

Quicksort для 16-битных и 64-битных типов данных дает ускорение до 15x и 9x на процессорах, поддерживающих набор инструкций AVX-512.

Благодаря Корпорация Intel за спонсирование этой работы.

(gh-22315)

__array_function__ механизм теперь работает значительно быстрее#

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

(gh-23020)

ufunc.at может быть намного быстрее#

Общий ufunc.at может быть до 9 раз быстрее. Условия для этого ускорения:

  • операнды выровнены

  • без приведения типов

Если ufuncs с соответствующими индексированными циклами на 1d аргументах с вышеуказанными условиями, ufunc.at может быть до 60 раз быстрее (дополнительное ускорение в 7 раз). Соответствующие индексированные циклы были добавлены в add, subtract, multiply, floor_divide, maximum, minimum, fmax, и fmin.

Внутренняя логика похожа на логику, используемую для обычных ufunc, которые также имеют быстрые пути.

Благодаря D. E. Shaw group за спонсирование этой работы.

(gh-23136)

Более быстрый тест на принадлежность для NpzFile#

Проверка принадлежности NpzFile больше не будет распаковывать архив, если он успешен.

(gh-23661)

Изменения#

np.r_[] и np.c_[] с определенными скалярными значениями#

В редких случаях, используя в основном np.r_ со скалярами может привести к разным результатам. Основные потенциальные изменения выделены следующим:

>>> np.r_[np.arange(5, dtype=np.uint8), -1].dtype
int16  # rather than the default integer (int64 or int32)
>>> np.r_[np.arange(5, dtype=np.int8), 255]
array([  0,   1,   2,   3,   4, 255], dtype=int16)

Где второй пример вернул:

array([ 0,  1,  2,  3,  4, -1], dtype=int8)

Первый связан со скаляром знакового целого числа с массивом беззнаковых целых чисел, а второй — с 255 не помещается в int8 и NumPy в настоящее время проверяет значения, чтобы это работало. (Обратите внимание, что второй пример, как ожидается, изменится в будущем из-за NEP 50; тогда будет вызвана ошибка.)

(gh-22539)

Большинство функций NumPy обёрнуты в вызываемую из C#

Для ускорения __array_function__ диспетчеризации, большинство функций NumPy теперь обёрнуты в C-вызываемые объекты и не являются полноценными функциями Python или C-методами. Они по-прежнему выглядят и ощущаются так же, как раньше (как функция Python), и это должно только улучшить производительность и пользовательский опыт (более чистые трассировки). Однако, пожалуйста, сообщите разработчикам NumPy, если это изменение по какой-то причине сбивает с толку вашу программу.

(gh-23020)

Использование стандартной библиотеки C++#

Сборки NumPy теперь зависят от стандартной библиотеки C++, потому что numpy.core._multiarray_umath расширение связано с компоновщиком C++.

(gh-23601)