Примечания к выпуску NumPy 1.15.0#
NumPy 1.15.0 — это выпуск с необычно большим количеством улучшений, множеством устареваний старых функций и улучшениями многих существующих функций. Пожалуйста, прочитайте подробные описания ниже, чтобы узнать, затронуты ли вы.
Для тестирования мы перешли на pytest в качестве замены более не поддерживаемого фреймворка nose. Старый интерфейс на основе nose остаётся для проектов, которые всё ещё могут его использовать.
Версии Python, поддерживаемые этим выпуском: 2.7, 3.4-3.7. Колёса связаны с OpenBLAS v0.3.0, что должно исправить некоторые проблемы linalg, сообщённые для NumPy 1.14.
Основные моменты#
NumPy перешёл на pytest для тестирования.
Новый
numpy.printoptionsменеджер контекста.Много улучшений в функциях гистограммы.
Поддержка имен полей в юникоде в python 2.7.
Улучшенная поддержка PyPy.
Исправления и улучшения для
numpy.einsum.
Новые функции#
numpy.gcdиnumpy.lcm, для вычисления наибольшего общего делителя и наименьшего общего кратного.numpy.ma.stack,numpy.stackФункция объединения массивов обобщена для маскированных массивов.numpy.quantileфункция, интерфейс кpercentileбез множителей 100numpy.nanquantileфункция, интерфейс кnanpercentileбез множителей 100numpy.printoptions, контекстный менеджер, который временно устанавливает параметры печати для области действияwithблок:>>> with np.printoptions(precision=2): ... print(np.array([2.0]) / 3) [0.67]
numpy.histogram_bin_edges, функция для получения границ бинов, используемых гистограммой, без необходимости вычислять гистограмму.Функции C npy_get_floatstatus_barrier и npy_clear_floatstatus_barrier были добавлены для обработки изменения порядка операций оптимизацией компилятора. Подробности см. ниже.
Устаревшие функции#
Псевдонимы встроенных
pickleфункции устарели в пользу их непсевдонимныхpickle.имена:numpy.loads
numpy.core.numeric.load
numpy.core.numeric.loads
numpy.ma.loads, numpy.ma.dumps
numpy.ma.load, numpy.ma.dump — эти функции уже не работали в Python 3 при вызове со строкой.
Многомерное индексирование с чем-либо, кроме кортежа, устарело. Это означает, что список индексов в
ind = [slice(None), 0]; arr[ind]должно быть изменено на кортеж, например,ind = [slice(None), 0]; arr[tuple(ind)]илиarr[(slice(None), 0)]. Это изменение необходимо для избежания неоднозначности в выражениях типаarr[[[0, 1], [0, 1]]], в настоящее время интерпретируется какarr[array([0, 1]), array([0, 1])], который будет интерпретирован какarr[array([[0, 1], [0, 1]])]в будущем.Импорты из следующих подмодулей устарели, они будут удалены в будущем.
numpy.testing.utils
numpy.testing.decorators
numpy.testing.nosetester
numpy.testing.noseclasses
numpy.core.umath_tests
Передача генератора в
numpy.sumтеперь устарело. Это было недокументированное поведение, но работало. Ранее оно вычисляло сумму выражения генератора. В будущем оно может возвращать другой результат. Используйтеnp.sum(np.from_iter(generator))или встроенный Pythonsumвместо этого.Пользователи C-API должны вызывать
PyArrayResolveWriteBackIfCopyилиPyArray_DiscardWritebackIfCopyна любом массиве с помощьюWRITEBACKIFCOPYфлаг установлен, перед освобождением массива. Будет выдано предупреждение об устаревании, если эти вызовы не используются, когда это необходимо.Пользователи
nditerдолжен использовать объект nditer в качестве контекстного менеджера всякий раз, когда один из операндов итератора доступен для записи, чтобы numpy мог управлять семантикой обратной записи, или должен вызватьit.close(). A RuntimeWarning может быть выведено в противном случае в этих случаях.The
normedаргументnp.histogram, устаревшее давно в версии 1.6.0, теперь выдаетDeprecationWarning.
Будущие изменения#
NumPy 1.16 прекратит поддержку Python 3.4.
NumPy 1.17 прекратит поддержку Python 2.7.
Примечания по совместимости#
Скомпилированные тестовые модули переименованы и сделаны приватными#
Следующие скомпилированные модули были переименованы и сделаны приватными:
umath_tests->_umath_teststest_rational->_rational_testsmultiarray_tests->_multiarray_testsstruct_ufunc_test->_struct_ufunc_testsoperand_flag_tests->_operand_flag_tests
The umath_tests модуль всё ещё доступен для обратной совместимости, но
будет удалён в будущем.
The NpzFile возвращаемый np.savez теперь является collections.abc.Mapping#
Это означает, что он ведёт себя как словарь только для чтения и имеет новый .values()
метод и len() реализация.
Для Python 3 это означает, что .iteritems(), .iterkeys() были устаревшими, и .keys() и .items() теперь возвращают представления, а не списки. Это согласуется с тем, как встроенный dict тип изменился между python 2 и python 3.
При определенных условиях, nditer должен использоваться в контекстном менеджере#
При использовании numpy.nditer с "writeonly" или "readwrite" флаги, есть некоторые обстоятельства, когда nditer фактически не предоставляет представление записываемого массива. Вместо этого он предоставляет копию, и если вы вносите изменения в копию, nditer позже записывает эти изменения обратно в ваш фактический массив. В настоящее время эта обратная запись происходит, когда объекты массива собираются сборщиком мусора, что делает этот API подверженным ошибкам в CPython и полностью неработоспособным в PyPy. Поэтому
nditer теперь должен использоваться как контекстный менеджер при работе с записываемыми массивами, например, with np.nditer(...) as it: .... Вы также можете
явно вызвать it.close() для случаев, когда контекстный менеджер неприменим, например, в выражениях-генераторах.
Numpy перешёл на использование pytest вместо nose для тестирования#
Последний релиз nose был 1.3.7 в июне 2015 года, и разработка этого инструмента завершена, поэтому NumPy теперь перешел на использование pytest. Старые декораторы и инструменты nose, которые ранее использовались некоторыми зависимыми проектами, остаются доступными, но не будут поддерживаться. Стандартные утилиты тестирования,
assert_almost_equal и подобные, не будут затронуты этим изменением, за исключением функций, специфичных для nose import_nose и raises. Эти функции
не используются в numpy, но сохраняются для совместимости с нижестоящими проектами.
NumPy больше не модифицирует (monkey-patches) ctypes с __array_interface__#
Ранее numpy добавлял __array_interface__ атрибуты для всех целочисленных типов из ctypes.
np.ma.notmasked_contiguous и np.ma.flatnotmasked_contiguous всегда возвращают списки#
) будет вести себя иначе при приведении массива в будущем.
Все последующие пользователи, кажется, проверяют None результат из
flatnotmasked_contiguous и заменить его на []. Эти вызывающие объекты
продолжат работать как раньше.
np.squeeze восстанавливает старое поведение объектов, которые не могут обработать axis аргумент#
До версии 1.7.0, numpy.squeeze не имел axis аргумент и все пустые оси удалялись по умолчанию. Включение axis
аргумент позволял выборочно сжимать одну или несколько пустых осей,
но старое ожидание API не соблюдалось, потому что оси все еще могли быть
выборочно удалены (тихий успех) из объекта, ожидающего удаления всех пустых осей.
Это тихое, выборочное удаление пустых осей для объектов, ожидающих
старого поведения, было исправлено, и старое поведение восстановлено.
неструктурированного void массива .item метод теперь возвращает объект bytes#
.item теперь возвращает bytes объект вместо буфера или массива байтов.
Это может повлиять на код, который предполагал, что возвращаемое значение изменяемо, что больше
не так.
copy.copy и copy.deepcopy больше не превращает masked в массив#
Поскольку np.ma.masked является скаляром только для чтения, копирование должно быть пустой операцией. Эти
функции теперь ведут себя согласованно с np.copy().
Многополевая индексация структурированных массивов по-прежнему возвращает копию#
Изменение, при котором индексирование по нескольким полям структурированных массивов возвращает представление
вместо копии, отложено до версии 1.16. Новый метод
numpy.lib.recfunctions.repack_fields был введен, чтобы помочь смягчить
последствия этого изменения, который можно использовать для написания кода, совместимого с
numpy 1.15 и 1.16. Для получения дополнительной информации о том, как обновить код с учетом
этого будущего изменения, см. раздел «доступ к нескольким полям» в
руководство пользователя.
Изменения в C API#
Новые функции npy_get_floatstatus_barrier и npy_clear_floatstatus_barrier#
Функции npy_get_floatstatus_barrier и npy_clear_floatstatus_barrier
были добавлены и должны использоваться вместо npy_get_floatstatus и
npy_clear_status функций. Оптимизирующие компиляторы, такие как GCC 8.1 и Clang,
переставляли порядок операций, когда предыдущие функции использовались
в SIMD-функциях ufunc, что приводило к проверке флагов floatstatus
до выполнения операции, статус которой мы хотели проверить. См. #10339.
Изменения в PyArray_GetDTypeTransferFunction#
PyArray_GetDTypeTransferFunction теперь по умолчанию использует пользовательские
copyswapn / copyswap для пользовательских типов данных. Если это вызывает
значительное снижение производительности, рассмотрите реализацию copyswapn чтобы отразить
реализацию PyArray_GetStridedCopyFn. См. #10898.
Новые возможности#
np.gcd и np.lcm ufuncs добавлены для целочисленных типов и типов объектов#
Они вычисляют наибольший общий делитель и наименьшее общее кратное соответственно. Работают со всеми целочисленными типами numpy, а также со встроенными типами произвольной точности Decimal и long типы.
Поддержка кроссплатформенных сборок для iOS#
Система сборки была изменена для добавления поддержки
_PYTHON_HOST_PLATFORM переменная окружения, используемая distutils при компиляции на одной платформе для другой платформы. Это позволяет компилировать NumPy для целей iOS.
Это позволяет компилировать NumPy только для одной конкретной платформы за раз. Создание полного пакета NumPy, совместимого с iOS, требует сборки для 5 архитектур, поддерживаемых iOS (i386, x86_64, armv7, armv7s и arm64), и объединения этих 5 скомпилированных сборок в один «толстый» бинарный файл.
return_indices ключевое слово добавлено для np.intersect1d#
Новое ключевое слово return_indices возвращает индексы двух входных массивов, соответствующие общим элементам.
np.quantile и np.nanquantile#
Как np.percentile и np.nanpercentile, но принимает квантили в [0, 1]
вместо процентилей в [0, 100]. np.percentile теперь является тонкой оберткой вокруг np.quantile с дополнительным шагом деления на 100.
Система сборки#
Добавлена экспериментальная поддержка 64-битной архитектуры RISC-V.
Улучшения#
np.einsum обновления#
Синхронизация технологии оптимизации пути einsum между numpy и opt_einsum. В частности, жадный путь получил множество улучшений от @jcmgray. Полный список исправленных проблем:
Произвольная память может быть передана в жадный путь. Исправляет gh-11210.
Жадный путь был обновлен, чтобы включить больше идей динамического программирования, предотвращая большое количество дублирующих (и дорогостоящих) вызовов, которые определяют фактическое сокращение пар, которое происходит. Теперь занимает несколько секунд на нескольких сотнях входных тензоров. Полезно для теорий матричного произведения состояний.
Перерабатывает обработку ошибок broadcast dot, найденную в gh-11218 gh-10352, чтобы она происходила немного раньше в процессе.
Улучшает can_dot функциональность, которая ранее пропускала крайний случай (часть gh-11308).
np.flip может работать по нескольким осям#
np.flip теперь принимает None или кортежи целых чисел в своих axis аргумент. Если ось равна None, она перевернёт все оси.
histogram и histogramdd функции перемещены в np.lib.histograms#
Изначально они были найдены в np.lib.function_base. Они по-прежнему доступны под своими неограниченными np.histogram(dd) имена, и для поддержания совместимости, псевдонимы в np.lib.function_base.histogram(dd).
Код, который делает from np.lib.function_base import * потребуется обновить с новым местоположением и следует рассмотреть возможность неиспользования import * в будущем.
histogram будет принимать значения NaN при явном задании бинов#
Ранее это завершалось ошибкой при попытке вычислить конечный диапазон для данных. Поскольку диапазон в любом случае игнорируется, когда корзины заданы явно, эта ошибка была излишней.
Обратите внимание, что вызов histogram на значениях NaN продолжает вызывать
RuntimeWarning типично для работы с значениями nan, которые можно заглушить как обычно с помощью errstate.
histogram работает с типами даты и времени, когда заданы явные границы бинов#
Даты, время и временные интервалы теперь можно гистограммировать. Границы бинов должны передаваться явно и пока не вычисляются автоматически.
histogram оценщик "auto" лучше справляется с ограниченной дисперсией#
Больше IQR, равный 0, не приводит к n_bins=1, скорее, количество выбранных бинов
связано с размером данных в этой ситуации.
Края, возвращаемые histogram и histogramdd теперь соответствуют типу данных float#
При передаче np.float16, np.float32, или np.longdouble данных,
возвращаемые границы теперь имеют тот же тип данных. Ранее, histogram будет возвращать тот же тип только если заданы явные бины, и histogram произведёт float64 корзины независимо от входных данных.
histogramdd позволяет явно задавать диапазоны в подмножестве осей#
The range аргумент numpy.histogramdd теперь может содержать None значения, чтобы указать, что диапазон для соответствующей оси должен быть вычислен из данных. Ранее это нельзя было указать для каждой оси отдельно.
Аргументы normed у histogramdd и histogram2d были переименованы#
Эти аргументы теперь называются density, что согласуется с
histogram. Старый аргумент продолжает работать, но новое имя следует предпочесть.
np.r_ работает с 0d массивами, и np.ma.mr_ работает с np.ma.masked#
0D массивы, переданные в r_ и mr_ Вспомогательные функции конкатенации теперь обрабатываются как массивы длины 1. Ранее их передача вызывала ошибку. В результате, numpy.ma.mr_ теперь работает корректно на masked random.chisquare() (в модуле numpy)
np.ptp принимает keepdims аргумент и расширенные кортежи осей#
np.ptp (размах) теперь может работать по нескольким осям, так же как np.max
и np.min.
MaskedArray.astype теперь идентичен ndarray.astype#
Это означает, что он принимает все те же аргументы, позволяя большему количеству кода, написанного для ndarray, работать и с маскированным массивом.
Включить AVX2/AVX512 во время компиляции#
Изменение в simd.inc.src для разрешения использования AVX2 или AVX512 во время компиляции. Ранее компиляция для avx2 (или 512) с -march=native всё равно использовала SSE код для simd-функций, даже когда остальной код получал AVX2.
nan_to_num всегда возвращает скаляры при получении скалярных или 0d входных данных#
Ранее для целочисленных скалярных входов возвращался массив, что не согласуется с поведением для входов с плавающей точкой и поведением ufunc в целом. Для всех типов скалярного или 0d входа результат теперь является скаляром.
np.flatnonzero работает с типами, конвертируемыми в numpy#
np.flatnonzero теперь использует np.ravel(a) вместо a.ravel(), поэтому работает для списков, кортежей и т.д.
np.interp возвращает скаляры numpy вместо встроенных скаляров#
Ранее np.interp(0.5, [0, 1], [10, 20]) вернет float, но теперь возвращает np.float64 объект, который более точно соответствует поведению других функций.
Кроме того, особый случай np.interp(object_array_0d, ...) больше не поддерживается, так как np.interp(object_array_nd) все равно никогда не поддерживалось.
В результате этого изменения, period Аргумент теперь можно использовать на массивах 0d.
Разрешить использование имен полей типа данных в виде юникода в Python 2#
Ранее np.dtype([(u'name', float)]) вызовет TypeError в
Python 2, так как только байтовые строки были разрешены в именах полей. Теперь любые юникодные
строковые имена полей будут закодированы с помощью ascii кодек, вызывая
UnicodeEncodeError при неудаче.
Это изменение упрощает написание совместимого кода для Python 2/3 с использованием
from __future__ import unicode_literals, что ранее вызывало TypeError для строковых литералов имён полей в Python 2.
Сравнительные ufuncs принимают dtype=object, переопределяя значение по умолчанию bool#
Это позволяет создавать объектные массивы символьных типов, которые переопределяют == и другие операторы для возврата выражений, которые будут сравниваться поэлементно с
np.equal(a, b, dtype=object).
sort функции принимают kind='stable'#
До сих пор для выполнения стабильной сортировки данных пользователь должен был:
>>> np.sort([5, 2, 6, 2, 1], kind='mergesort')
[1, 2, 2, 5, 6]
поскольку сортировка слиянием — единственный стабильный алгоритм сортировки, доступный в NumPy. Однако наличие kind='mergesort' не делает явным, что пользователь хочет выполнить стабильную сортировку, что ухудшает читаемость.
Это изменение позволяет пользователю указать kind='stable', тем самым проясняя намерение.
Не создавайте временные копии для накопления на месте#
Когда ufunc выполняют накопление, они больше не создают временные копии из-за перекрытия между входом и выходом, то есть следующий накапливаемый элемент добавляется до того, как накопленный результат сохраняется на своем месте, поэтому перекрытие безопасно. Избегание копирования приводит к более быстрому выполнению.
linalg.matrix_power теперь может обрабатывать стеки матриц#
Как и другие функции в linalg, matrix_power теперь может работать с массивами
размерности больше 2, которые обрабатываются как стеки матриц. В рамках
этого изменения, для дальнейшего улучшения согласованности, имя первого аргумента
было изменено на a (из M), и исключения для неквадратных
матриц были изменены на LinAlgError (из ValueError).
Увеличение производительности в random.permutation для многомерных массивов#
permutation использует быстрый путь в random.shuffle для всех размерностей входного массива. Ранее быстрый путь использовался только для одномерных массивов.
Обобщённые ufuncs теперь принимают axes, axis и keepdims аргументы#
Можно управлять, по каким осям действует обобщенный ufunc, передавая
axes аргумент, список кортежей с индексами определённых осей. Например, для сигнатуры (i,j),(j,k)->(i,k) подходящий для матричного
умножения, базовые элементы — это двумерные матрицы, и они
считаются хранящимися в двух последних осях каждого аргумента. Соответствующий
ключевое слово осей будет [(-2, -1), (-2, -1), (-2, -1)]. Если кто-то хотел использовать ведущие размерности вместо этого, нужно передать [(0, 1), (0, 1), (0, 1)].
Для простоты, для обобщенных ufuncs, работающих с 1-мерными массивами
(векторами), принимается одно целое число вместо кортежа из одного элемента, и
для обобщенных ufuncs, у которых все выходы являются скалярами, (пустые) выходные
кортежи могут быть опущены. Следовательно, для сигнатуры (i),(i)->() подходящий
для скалярного произведения, можно передать axes=[0, 0] чтобы указать, что векторы хранятся в первых измерениях двух входных аргументов.
В качестве сокращения для обобщенных ufunc, которые похожи на редукции, т.е. действуют на одно общее ядро измерения, как в примере с внутренним произведением выше, можно передать axis аргумент. Это эквивалентно передаче
axes с одинаковыми записями для всех аргументов с этим основным измерением
(например, для приведённого выше примера, axes=[(axis,), (axis,)]).
Кроме того, как и для редукций, для обобщенных универсальных функций, у которых входы
имеют одинаковое количество основных измерений, а выходы не имеют основных измерений,
можно передать keepdims оставить измерение размером 1 в выводах, что позволяет корректное вещание относительно исходных входных данных. Расположение дополнительного измерения можно контролировать с помощью axesНапример, для примера с внутренним произведением, keepdims=True, axes=[-2, -2, -2] будет действовать на
пример скалярного произведения, keepdims=True, axis=-2 будет действовать на предпоследнее измерение входных аргументов и оставит размер 1 в этом месте на выходе.
значения float128 теперь выводятся корректно на системах ppc#
Ранее вывод значений float128 был ошибочным на ppc, поскольку специальный формат чисел с плавающей запятой двойной двойной точности на этих системах не учитывался. Теперь float128 выводятся с правильным округлением и уникальностью.
Предупреждение пользователям ppc: вам следует обновить glibc, если его версия <=2.23, особенно при использовании float128. На ppc malloc в glibc в этих версиях часто неправильно выравнивает выделенную память, что может привести к сбою numpy при использовании значений float128.
Новый np.take_along_axis и np.put_along_axis функции#
При использовании с многомерными массивами, argsort, argmin, argmax, и
argpartition возвращают массивы, которые сложно использовать в качестве индексов.
take_along_axis предоставляет простой способ использовать эти индексы для поиска значений в массиве, так что:
np.take_along_axis(a, np.argsort(a, axis=axis), axis=axis)
то же самое, что:
np.sort(a, axis=axis)
np.put_along_axis действует как двойная операция для записи по этим индексам в массиве.