Разное
Специальные значения чисел с плавающей точкой IEEE 754
Специальные значения, определённые в numpy: nan, inf,
NaN можно использовать как маску (если неважно, каким было исходное значение)
Примечание: нельзя использовать равенство для проверки NaN. Например:
>>> myarr = np.array([1., 0., np.nan, 3.]) >>> np.nonzero(myarr == np.nan) (array([], dtype=int64),) >>> np.nan == np.nan # is always False! Use special numpy functions instead. False >>> myarr[myarr == np.nan] = 0. # doesn't work >>> myarr array([ 1., 0., NaN, 3.]) >>> myarr[np.isnan(myarr)] = 0. # use this instead find >>> myarr array([ 1., 0., 0., 3.])
Другие связанные функции специальных значений:
isinf(): True if value is inf isfinite(): True if not nan or inf nan_to_num(): Map nan to 0, inf to max float, -inf to min float
Следующие функции соответствуют обычным функциям, за исключением того, что значения nan исключаются из результатов:
nansum() nanmax() nanmin() nanargmax() nanargmin() >>> x = np.arange(10.) >>> x[3] = np.nan >>> x.sum() nan >>> np.nansum(x) 42.0
Как numpy обрабатывает числовые исключения
По умолчанию 'warn' для invalid, divide, и overflow и 'ignore' для underflow. Но это можно изменить, и это можно установить индивидуально для разных типов исключений. Разные варианты поведения:
- ‘ignore’ : Не предпринимать никаких действий при возникновении исключения.
- ‘warn’ : Вывести
RuntimeWarning(через модуль Pythonwarnings). - ‘raise’ : Вызвать
FloatingPointError. - ‘call’ : Вызвать функцию, заданную с помощью функции
seterrcall. - ‘print’ : Вывести предупреждение напрямую в
stdout. - ‘log’ : Записать ошибку в объект журнала, заданный
seterrcall.
Эти варианты поведения могут быть заданы для всех типов ошибок или для конкретных:
- all : применяется ко всем числовым исключениям
- invalid : при генерации NaN
- divide : деление на ноль (для целых чисел тоже!)
- overflow : переполнение чисел с плавающей точкой
- underflow : подпотоки чисел с плавающей точкой
Обратите внимание, что деление на ноль целых чисел обрабатывается той же механикой. Эти варианты поведения устанавливаются на основе потока.
Примеры
>>> oldsettings = np.seterr(all='warn')
>>> np.zeros(5,dtype=np.float32)/0.
invalid value encountered in divide
>>> j = np.seterr(under='ignore')
>>> np.array([1.e-100])**10
>>> j = np.seterr(invalid='raise')
>>> np.sqrt(np.array([-1.]))
FloatingPointError: invalid value encountered in sqrt
>>> def errorhandler(errstr, errflag):
... print("saw stupid error!")
>>> np.seterrcall(errorhandler)
<function err_handler at 0x...>
>>> j = np.seterr(all='call')
>>> np.zeros(5, dtype=np.int32)/0
FloatingPointError: invalid value encountered in divide
saw stupid error!
>>> j = np.seterr(**oldsettings) # restore previous
... # error-handling settings
Взаимодействие с C
Только обзор вариантов. Мало подробностей о том, как каждый работает.
- Непосредственный код, вручную оберните собственный код C.
-
Плюсы:
- Эффективность
- Нет зависимостей от других инструментов
-
Минусы:
-
Много накладных расходов обучения:
- нужно изучить основы API Python C
- нужно изучить основы API numpy C
- нужно изучить, как обрабатывать счётчик ссылок и любить его.
-
Счётчик ссылок часто сложно реализовать правильно.
- ошибки в реализации приводят к утечкам памяти и, что ещё хуже, к ошибкам сегментации
- API изменится для Python 3.0!
-
- Cython
-
Плюсы:
- избегайте изучения API C
- не нужно заниматься подсчётом ссылок
- можно писать код в псевдо-Python и генерировать код C
- также можно взаимодействовать с существующим кодом C
- должно защитить вас от изменений в API Python C
- стал фактическим стандартом в научном сообществе Python
- быстрая поддержка индексирования массивов
-
Минусы:
- Можно писать код в нестандартном формате, который может устареть
- Не так гибко, как ручная обёртка
- ctypes
-
Плюсы:
- часть стандартной библиотеки Python
- хорошо подходит для взаимодействия с существующими разделяемыми библиотеками, особенно с DLL Windows
- избегает проблем с API/счётчиком ссылок
-
хорошая поддержка numpy: у массивов есть всё это в их атрибуте ctypes:
a.ctypes.data a.ctypes.get_strides a.ctypes.data_as a.ctypes.shape a.ctypes.get_as_parameter a.ctypes.shape_as a.ctypes.get_data a.ctypes.strides a.ctypes.get_shape a.ctypes.strides_as
-
Минусы:
- нельзя использовать для написания кода, который будет преобразован в C-расширения, только инструмент обертки.
- SWIG (автоматический генератор обёрток)
-
Плюсы:
- существует давно
- поддержка нескольких языков сценариев
- поддержка C++
- Хорош для обертывания больших (множество функций) существующих библиотек C
-
Минусы:
- генерирует много кода между Python и кодом C
- может вызывать проблемы с производительностью, которые практически невозможно оптимизировать
- файлы интерфейса могут быть трудно написать
- не обязательно избегает проблем со счётчиком ссылок или необходимости знать API
- scipy.weave
-
Плюсы:
- может преобразовать многие выражения numpy в код C
- динамическая компиляция и загрузка сгенерированного кода C
- можно встраивать чистый код C в модуль Python, и weave будет извлекать, генерировать интерфейсы и компилировать и т.д.
-
Минусы:
- Будущее очень неопределённо: это единственная часть Scipy, не портированная в Python 3, и фактически устарела в пользу Cython.
- Psyco
-
Плюсы:
- Преобразует чистый Python в эффективный машинный код с помощью оптимизаций типа jit
- очень быстро, когда оптимизируется хорошо
-
Минусы:
- Только на intel (windows?)
- Не делает много для numpy?
Взаимодействие с Fortran:
Явным выбором для обертки кода Fortran является f2py.
Pyfort — более старая альтернатива, но больше не поддерживается. Fwrap — более новый проект, который выглядел многообещающим, но больше не развивается.
Взаимодействие с C++:
- Cython
- CXX
- Boost.python
- SWIG
- SIP (используется в основном в PyQT)
© 2005–2020 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/1.19/user/misc.html