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

Этот выпуск NumPy является последним, поддерживающим Python 2.7, и будет поддерживаться как долгосрочный релиз с исправлениями ошибок до 2020 года. Поддержка Python 3.4 прекращена, поддерживаемые версии Python - 2.7 и 3.5-3.7. Колеса на PyPI связаны с OpenBLAS v0.3.4+, что должно исправить известные проблемы с потоками, обнаруженные в предыдущих версиях OpenBLAS.

Разработчикам, собирающим этот релиз, следует использовать Cython >= 0.29 и, если используется OpenBLAS, OpenBLAS > v0.3.4.

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

Основные моменты#

  • Экспериментальная (только по выбору) поддержка переопределения функций numpy, см. __array_function__ ниже.

  • The matmul функция теперь является ufunc. Это обеспечивает лучшую производительность и позволяет переопределять с помощью __array_ufunc__.

  • Улучшена поддержка архитектур ARM и POWER.

  • Улучшенная поддержка AIX и PyPy.

  • Улучшенная совместимость с ctypes.

  • Улучшенная поддержка PEP 3118.

Новые функции#

  • Новые функции, добавленные в numpy.lib.recfuntions модуль для упрощения структурированных изменений присваивания:

    • assign_fields_by_name

    • structured_to_unstructured

    • unstructured_to_structured

    • apply_along_fields

    • require_fields

    См. руководство пользователя по адресу <https://docs.scipy.org/doc/numpy/user/basics.rec.html> для получения дополнительной информации.

Новые устаревания#

  • Словари типов numpy.core.typeNA и numpy.core.sctypeNA устарели. Они содержали ошибки, не были задокументированы и будут удалены в выпуске 1.18. Используйте numpy.sctypeDict вместо этого.

  • The numpy.asscalar функция устарела. Это псевдоним для более мощной numpy.ndarray.item, не тестировалось и не работает для скаляров.

  • The numpy.set_array_ops и numpy.get_array_ops функции устарели. В рамках NEP 15, они были устаревшими вместе с функциями C-API PyArray_SetNumericOps и PyArray_GetNumericOps. Пользователи, которые хотят переопределить внутренние функции циклов во встроенных ufunc, должны использовать PyUFunc_ReplaceLoopBySignature.

  • The numpy.unravel_index аргумент ключевого слова dims устарел, используйте shape вместо этого.

  • The numpy.histogram normed аргумент устарел. Он был устаревшим ранее, но предупреждение не выдавалось.

  • The positive оператор (+) примененный к нечисловым массивам устарел. Подробности см. ниже.

  • Передача итератора в функции стека устарела

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

  • Сравнения NaT теперь возвращают False без предупреждения, завершая цикл устаревания, начатый в NumPy 1.11.

  • np.lib.function_base.unique был удалён, завершая цикл устаревания, начатый в NumPy 1.4. Используйте numpy.unique вместо этого.

  • многополевая индексация теперь возвращает представления вместо копий, завершая цикл устаревания, начатый в NumPy 1.7. Это изменение ранее пытались внедрить в NumPy 1.14, но откатили до настоящего момента.

  • np.PackageLoader и np.pkgload были удалены. Они были устаревшими в 1.10, не имели тестов и, похоже, больше не работают в 1.15.

Будущие изменения#

  • NumPy 1.17 прекратит поддержку Python 2.7.

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

скрипт f2py в Windows#

В Windows установленный скрипт для запуска f2py теперь является .exe файл вместо *.py файл и должен запускаться из командной строки как f2py всякий раз, когда Scripts каталог находится в пути. Запуск f2py как модуль python -m numpy.f2py [...] будет работать без изменения пути в любой версии NumPy.

Сравнения NaT#

В соответствии с поведением NaN, все сравнения, кроме проверок на неравенство с значениями datetime64 или timedelta64 NaT («не-время»), теперь всегда возвращают False, и проверки неравенства с NaT теперь всегда возвращают True. Это включает сравнения между значениями NaT. Для совместимости со старым поведением используйте np.isnat для явной проверки на NaT или преобразования массивов datetime64/timedelta64 с .astype(np.int64) перед выполнением сравнений.

выравнивание complex64/128 изменилось#

Выравнивание памяти для комплексных типов теперь такое же, как у C-структуры, состоящей из двух значений с плавающей точкой, тогда как раньше оно было равно размеру типа. Для многих пользователей (например, на x64/unix/gcc) это означает, что complex64 теперь выравнивается по 4 байта вместо 8 байт. Важное следствие - что выровненные структурированные типы данных теперь могут иметь другой размер. Например, np.dtype('c8,u1', align=True) раньше имел размер элемента 16 (на x64/gcc), но теперь он равен 12.

Более подробно, тип complex64 теперь имеет то же выравнивание, что и структура C struct {float r, i;}, в зависимости от компилятора, используемого для компиляции numpy, и аналогично для типов complex128 и complex256.

удаление nd_grid __len__#

len(np.mgrid) и len(np.ogrid) теперь считаются бессмысленными и вызывают TypeError.

np.unravel_index теперь принимает shape аргумент ключевого слова#

Ранее только dims ключевой аргумент принимался для спецификации формы массива, который должен быть использован для развёртывания. dims остаётся поддерживаемым, но теперь устарел.

многопольные представления возвращают представление вместо копии#

Индексирование структурированного массива с несколькими полями, например, arr[['f1', 'f3']], возвращает представление в исходном массиве вместо копии. Возвращённое представление часто будет иметь дополнительные байты заполнения, соответствующие промежуточным полям в исходном массиве, в отличие от предыдущего, что повлияет на код, такой как arr[['f1', 'f3']].view('float64'). Это изменение планировалось с numpy 1.7. Операции, затрагивающие этот путь, выдавали FutureWarnings с тех пор. Дополнительные FutureWarnings об этом изменении были добавлены в версии 1.12.

Чтобы помочь пользователям обновить свой код с учётом этих изменений, в numpy.lib.recfunctions модуль, который безопасно позволяет такие операции. Например, приведённый выше код можно заменить на structured_to_unstructured(arr[['f1', 'f3']], dtype='float64'). См. раздел "доступ к нескольким полям" в руководство пользователя.

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

The NPY_FEATURE_VERSION был увеличен до 0x0000D из-за добавления:

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

Оценщик интегрированной квадратичной ошибки (ISE) добавлен в histogram#

Этот метод (bins='stone') для оптимизации количества бинов является обобщением правила Скотта. Правило Скотта предполагает, что распределение приблизительно нормальное, в то время как ISE является непараметрическим методом, основанным на кросс-валидации.

max_rows ключевое слово добавлено для np.loadtxt#

Новое ключевое слово max_rows в numpy.loadtxt устанавливает максимальное количество строк содержимого для чтения после skiprows, как в numpy.genfromtxt.

добавлена поддержка оператора модуля для np.timedelta64 операнды#

Оператор модуля (остатка) теперь поддерживается для двух операндов типа np.timedelta64. Операнды могут иметь разные единицы измерения, и возвращаемое значение будет соответствовать типу операндов.

Улучшения#

pickling массивов numpy без копирования#

До протокола 4, сериализация массивов numpy создавала 2 ложные копии данных. С протоколом pickle 5 и PickleBuffer API, большое разнообразие массивов NumPy теперь может быть сериализовано без копирования с использованием буферов вне полосы и с одним копированием меньше при использовании буферов в полосе. Это приводит, для больших массивов, к снижению пикового использования памяти до 66%.

обеспечить независимость от оболочки#

Сборки NumPy больше не должны напрямую взаимодействовать с оболочкой хоста. exec_command был заменён на subprocess.check_output где это уместно.

np.polynomial.Polynomial классы отображаются в LaTeX в Jupyter notebooks#

При использовании во внешнем интерфейсе, который поддерживает это, Polynomial экземпляры теперь отображаются через LaTeX. Текущий формат является экспериментальным и может быть изменен.

randint и choice теперь работают с пустыми распределениями#

Даже когда не нужно было извлекать элементы, np.random.randint и np.random.choice вызывал ошибку, когда аргументы описывали пустое распределение. Это исправлено, так что, например, np.random.choice([], 0) == np.array([], dtype=float64).

linalg.lstsq, linalg.qr, и linalg.svd теперь работают с пустыми массивами#

Ранее, LinAlgError будет вызвано, когда пустая матрица/пустые матрицы (с нулевыми строками и/или столбцами) передаются. Теперь возвращаются выходные данные соответствующих форм.

Цепочка исключений для предоставления лучших сообщений об ошибках для неверных строк формата PEP3118#

Это должно помочь отследить проблемы.

Обновления пути оптимизации Einsum и улучшения эффективности#

Einsum был синхронизирован с текущей работой upstream.

numpy.angle и numpy.expand_dims теперь работают с ndarray подклассы#

В частности, они теперь работают для маскированных массивов.

NPY_NO_DEPRECATED_API подавление предупреждений компилятора#

Установка NPY_NO_DEPRECATED_API установка значения 0 подавит текущие предупреждения компилятора при использовании устаревшего API numpy.

np.diff Добавлены ключевые аргументы prepend и append#

Новые kwargs prepend и append, позволяют вставлять значения на любом конце разностей. Подобно опциям для ediff1d. Теперь обратная величина cumsum можно легко получить через prepend=0.

Поддержка ARM обновлена#

Поддержка процессоров ARM обновлена для работы с 32- и 64-битными целями, а также с порядком байтов big и little endian. Проблемы выравнивания памяти AARCH32 были решены. CI-тестирование расширено для включения целей AARCH64 через сервисы shippable.com.

Добавление флагов сборки#

numpy.distutils всегда перезаписывал, а не добавлял к LDFLAGS и другие аналогичные переменные окружения для компиляции расширений Fortran. Теперь, если NPY_DISTUTILS_APPEND_FLAGS переменная окружения установлена в 1, поведение будет добавлением. Это применяется к: LDFLAGS, F77FLAGS, F90FLAGS, FREEFLAGS, FOPT, FDEBUG, и FFLAGS. См. gh-11525 для более подробной информации.

Обобщенные сигнатуры универсальных функций теперь допускают фиксированные размерности#

Используя числовое значение в сигнатуре обобщённой ufunc, можно указать, что данная функция требует, чтобы входные или выходные данные имели размерности с заданным размером. Например, сигнатура функции, которая преобразует полярный угол в двумерный декартов единичный вектор, будет ()->(2); что для функции, преобразующей два сферических угла в трехмерный единичный вектор, будет (),()->(3); и что для векторного произведения двух трёхмерных векторов будет (3),(3)->(3).

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

Обобщённые сигнатуры ufunc теперь позволяют гибкие размерности#

Некоторые функции, в частности реализация @ как matmulочень похожи на обобщённые универсальные функции в том, что они работают с основными измерениями, но их нельзя представить как таковые, потому что они могли обрабатывать входные данные, в которых измерение отсутствует. Для поддержки этого теперь разрешено добавлять знак вопроса после имени измерения, чтобы указать, что измерение не обязательно должно присутствовать.

С этим дополнением сигнатура для matmul может быть выражен как (m?,n),(n,p?)->(m?,p?). Это означает, что если, например, второй операнд имеет только одно измерение, для целей элементарной функции он будет рассматриваться так, как если бы этот вход имел основную форму (n, 1), и вывод имеет соответствующую основную форму (m, 1). Однако фактический выходной массив имеет гибкое измерение удаленным, т.е. он будет иметь форму (..., m). Аналогично, если оба аргумента имеют только одно измерение, входные данные будут представлены как имеющие формы (1, n) и (n, 1) к элементарной функции, а вывод как (1, 1), в то время как фактический возвращаемый массив будет иметь форму (). Таким образом, сигнатура позволяет использовать одну элементарную функцию для четырёх связанных, но различных сигнатур, (m,n),(n,p)->(m,p), (n),(n,p)->(p), (m,n),(n)->(m) и (n),(n)->().

np.clip и clip метод проверки перекрытия памяти#

The out аргумент для этих функций теперь всегда проверяется на перекрытие памяти, чтобы избежать повреждённых результатов при перекрытии памяти.

Новое значение unscaled для опции cov в np.polyfit#

Добавлено возможное дополнительное значение в cov параметр np.polyfit функция. С cov='unscaled' масштабирование ковариационной матрицы полностью отключено (аналогично установке absolute_sigma=True в scipy.optimize.curve_fit). Это может быть полезно в случаях, когда веса заданы как 1/sigma, где sigma — (известные) стандартные ошибки (гауссово распределённых) точек данных, в этом случае немасштабированная матрица уже является корректной оценкой ковариационной матрицы.

Подробные строки документации для скалярных числовых типов#

The help функция, при применении к числовым типам, таким как numpy.intc, numpy.int_, и numpy.longlong, теперь перечисляет все псевдонимы для этого типа, различая платформозависимые и независимые псевдонимы.

__module__ атрибут теперь указывает на публичные модули#

The __module__ атрибут в большинстве функций NumPy был обновлён для ссылки на предпочтительный публичный модуль, из которого можно получить доступ к функции, а не на модуль, в котором функция определена. Это обеспечивает более информативное отображение функций в таких инструментах, как IPython, например, вместо 'numpy.core.fromnumeric.sum'> теперь вы видите 'numpy.sum'>.

Большие выделения памяти, помеченные как подходящие для прозрачных огромных страниц#

В системах, поддерживающих прозрачные огромные страницы через системный вызов madvise, numpy теперь отмечает, что большие выделения памяти могут поддерживаться огромными страницами, что снижает накладные расходы на обработку страничных сбоев и в некоторых случаях с высокой частотой сбоев может значительно улучшить производительность. В Linux настройка для использования огромных страниц, /sys/kernel/mm/transparent_hugepage/enabled, должно быть не менее madvise. Системы, в которых уже установлено значение всегда не увидят большой разницы, так как ядро будет автоматически использовать огромные страницы там, где это уместно.

Пользователи очень старых ядер Linux (~3.x и старше) должны убедиться, что /sys/kernel/mm/transparent_hugepage/defrag не установлен в всегда чтобы избежать проблем с производительностью из-за проблем параллелизма в дефрагментации памяти.

Alpine Linux (и другие дистрибутивы с библиотекой musl c) поддерживают#

Теперь по умолчанию используется fenv.h для отчёта об ошибках состояния чисел с плавающей запятой. Ранее у нас была некорректная настройка по умолчанию, которая иногда не сообщала о потере значимости, переполнении и недопустимых операциях с плавающей запятой. Теперь мы можем поддерживать дистрибутивы без glibc, такие как Alpine Linux, при условии, что они поставляются с fenv.h.

Ускорение np.block для больших массивов#

Большие массивы (больше 512 * 512) теперь используют блочный алгоритм, основанный на копировании данных непосредственно в соответствующий срез результирующего массива. Это приводит к значительному ускорению для этих больших массивов, особенно для массивов, блокируемых по более чем 2 измерениям.

arr.ctypes.data_as(...) хранит ссылку на arr#

Ранее вызывающая сторона была ответственна за поддержание массива в течение времени жизни указателя.

Ускорение np.take для массивов только для чтения#

Реализация np.take больше не создаёт ненужную копию исходного массива, когда его writeable флаг установлен в False.

Поддержка объектов, подобных путям, для большего количества функций#

The np.core.records.fromfile функция теперь поддерживает pathlib.Path и другие объекты, подобные пути, в дополнение к файловому объекту. Кроме того, np.load функция теперь также поддерживает объекты, подобные пути, при использовании отображения в память (mmap_mode именованный аргумент).

Улучшенное поведение идентичностей ufunc при редукциях#

Универсальные функции имеют .identity который используется, когда .reduce вызывается на пустой оси.

Начиная с этого релиза, логические бинарные универсальные функции, logical_and, logical_or, и логическое_исключающее_или, теперь имеют identity типа bool, где ранее они были типа int. Это восстанавливает поведение версии 1.14, при котором получается bool s при редукции пустых объектных массивов с этими ufuncs, сохраняя при этом поведение версии 1.15 получения int s при сокращении пустых объектных массивов с арифметическими универсальными функциями, такими как add и multiply.

Дополнительно, logaddexp теперь имеет идентичность -inf, что позволяет вызывать её на пустых последовательностях, где ранее это было невозможно.

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

Улучшено преобразование из объектов ctypes#

NumPy всегда поддерживал взятие значения или типа из ctypes и преобразование его в массив или dtype, но корректно работало только для более простых типов. Начиная с этого релиза, это ограничение снято - теперь:

  • The _pack_ атрибут ctypes.Structure, используется для эмуляции C-функции __attribute__((packed)), соблюдается.

  • Порядок байтов всех объектов ctypes сохраняется

  • ctypes.Union поддерживается

  • Непредставимые конструкции вызывают исключения, а не производят опасно некорректные результаты:

    • Битовые поля больше не интерпретируются как подмассивы

    • Указатели больше не заменяются типом, на который они указывают

Новый ndpointer.contents член#

Это соответствует .contents член обычных массивов ctypes и может использоваться для создания np.array вокруг содержимого указателей. Это заменяет np.array(some_nd_pointer), который перестал работать в версии 1.15. Как побочный эффект этого изменения, ndpointer теперь поддерживает dtypes с перекрывающимися полями и заполнением.

matmul теперь является ufunc#

numpy.matmul теперь является ufunc, что означает, что и функция, и __matmul__ оператор теперь может быть переопределён с помощью __array_ufunc__. Его реализация также изменилась. Он использует те же подпрограммы BLAS, что и numpy.dot, обеспечивая аналогичную производительность для больших матриц.

Массивы начала и конца для linspace, logspace и geomspace#

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

CI расширен дополнительными сервисами#

Теперь мы используем дополнительные бесплатные CI-сервисы, благодаря компаниям, которые их предоставляют:

  • Тестирование покрытия кода через codecov.io

  • Тестирование Arm через shippable.com

  • Дополнительные тестовые запуски на azure pipelines

Это в дополнение к нашему постоянному использованию travis, appveyor (для колес) и LGTM

Изменения#

Функции сравнения ufunc теперь будут вызывать ошибку вместо возврата NotImplemented#

Ранее, унарные функции сравнения, такие как np.equal вернёт NotImplemented если их аргументы имели структурированные типы данных, чтобы помочь операторам сравнения, таким как __eq__ обрабатывать их. Это больше не нужно, так как соответствующая логика перемещена в сами операторы сравнения (которые, таким образом, продолжают возвращать NotImplemented по мере необходимости). Следовательно, как и все другие ufuncs, ufuncs сравнения теперь будут выдавать ошибку на структурированных типах данных.

Positive теперь будет выдавать предупреждение об устаревании для нечисловых массивов#

Ранее, +array безусловно возвращал копию. Теперь он будет вызывать DeprecationWarning если массив не числовой (т.е., если np.positive(array) вызывает TypeError. Для ndarray подклассы, которые переопределяют значение по умолчанию __array_ufunc__ реализация, TypeError передается дальше.

NDArrayOperatorsMixin теперь реализует матричное умножение#

Ранее, np.lib.mixins.NDArrayOperatorsMixin не реализовал специальные методы для оператора матричного умножения Python (@). Это изменилось, поскольку теперь matmul является ufunc и может быть переопределён с использованием __array_ufunc__.

Масштабирование ковариационной матрицы в np.polyfit отличается#

До сих пор np.polyfit использовал нестандартный множитель в масштабировании ковариационной матрицы. А именно, вместо использования стандартного chisq/(M-N), масштабировал его с chisq/(M-N-2) где M - количество точек данных, а N - количество параметров. Это масштабирование не согласуется с другими программами подгонки, такими как, например, scipy.optimize.curve_fit и был изменен на chisq/(M-N).

maximum и minimum больше не выдавать предупреждения#

Как часть кода, введённого в 1.10, float32 и float64 устанавливать недопустимое состояние float при обнаружении Nan в numpy.maximum и numpy.minimum, при использовании семантики SSE2. Это вызвало RuntimeWarning иногда выдаваться. В версии 1.15 мы исправили несоответствия, из-за которых предупреждения стали более заметными. Теперь предупреждения не будут выдаваться.

Модули расширения Umath и multiarray объединены в один модуль#

Два модуля были объединены, согласно NEP 15. Ранее np.core.umath и np.core.multiarray были отдельными модулями c-расширения. Теперь они являются обёртками Python для единого np.core/_multiarray_math c-расширении модуля.

getfield расширены проверки корректности#

numpy.ndarray.getfield теперь проверяет аргументы dtype и offset, чтобы предотвратить доступ к недопустимым областям памяти.

Функции NumPy теперь поддерживают переопределения с __array_function__#

NumPy имеет новый экспериментальный механизм для переопределения реализации почти всех функций NumPy на не-NumPy массивах путем определения __array_function__ метод, как описано в NEP 18.

Эта функция ещё не включена по умолчанию, но была выпущена для облегчения экспериментов потенциальными пользователями. Подробности о настройке соответствующей переменной окружения см. в NEP. Ожидается, что в релизе NumPy 1.17 переопределения будут включены по умолчанию, что также будет более производительным благодаря новой реализации на C.

Массивы на основе буферов только для чтения не могут быть установлены writeable#

Теперь мы запрещаем установку writeable флаг True для массивов, созданных из fromstring(readonly-buffer).