Spec-Zone.ru › NumPy 1.12

Стандартные подклассы массивов

Класс ndarray в NumPy — это встроенный тип Python нового стиля. Поэтому его можно унаследовать (в Python или C), если это необходимо. Таким образом, он может стать основой для многих полезных классов. Часто выбор между наследованием от объекта массива или использованием ядра массива как внутренней части нового класса является сложным решением, которое может зависеть от предпочтений. NumPy предоставляет инструменты для упрощения взаимодействия вашего нового объекта с другими объектами массивов, и поэтому этот выбор в итоге может не иметь большого значения. Один из способов упростить вопрос заключается в том, можно ли заменить интересующий вас объект одним массивом, или же ему действительно необходимы два или более массивов в основе.

Обратите внимание, что asarray всегда возвращает массив базового класса ndarray. Если вы уверены, что ваш способ использования объекта массива может обрабатывать любой подкласс ndarray, тогда asanyarray можно использовать для более чистого распространения подклассов через вашу подпрограмму. В принципе, подкласс может переопределить любой аспект массива, и поэтому, при строгих правилах, asanyarray будет редко полезным. Однако большинство подклассов объекта массива не переопределяют определённые аспекты объекта массива, такие как интерфейс буфера или атрибуты массива. Однако важным примером того, почему ваша подпрограмма может не справиться с произвольным подклассом массива, является то, что матрицы переопределяют оператор «*» для матричного умножения, а не для поэлементного.

Специальные атрибуты и методы

См. также

Наследование от ndarray

NumPy предоставляет несколько крючков, которые классы могут настроить:

class.__numpy_ufunc__(ufunc, method, i, inputs, **kwargs)

Введено в версии 1.11.

Любой класс (подкласс ndarray или нет) может определить этот метод для переопределения поведения функций NumPy. Это работает очень похоже на Python __mul__ и другие двоичные операции.

  • ufunc — это объект ufunc, который был вызван.
  • method — строка, указывающая, какой метод Ufunc был вызван (один из "__call__", "reduce", "reduceat", "accumulate", "outer", "inner").
  • i — индекс self в inputs.
  • inputs — кортеж аргументов входных данных для ufunc
  • kwargs — словарь, содержащий необязательные входные аргументы ufunc. Аргумент out всегда содержится в kwargs, если задан. Подробности см. в разделе Универсальные функции (ufunc).

Метод должен вернуть либо результат операции, либо NotImplemented, если запрашиваемая операция не реализована.

Если один из аргументов имеет метод __numpy_ufunc__, он выполняется вместо ufunc. Если более одного входного аргумента реализуют __numpy_ufunc__, они вызываются в порядке: подклассы перед суперклассами, иначе слева направо. Первая функция, возвращающая что-то отличное от NotImplemented, определяет результат. Если все операции __numpy_ufunc__ возвращают NotImplemented, генерируется TypeError.

Если подкласс ndarray определяет метод __numpy_ufunc__, это отключает механизм __array_wrap__, __array_prepare__, __array_priority__, описанный ниже.

Примечание

В дополнение к ufunc, __numpy_ufunc__ также переопределяет поведение numpy.dot, хотя это и не Ufunc.

Примечание

Если вы также определите переопределяющие методы бинарных операторов справа (например, __rmul__) или операции сравнения (например, __gt__) в вашем классе, они имеют приоритет над механизмом __numpy_ufunc__ при разрешении результатов бинарных операций (например, ndarray_obj * your_obj).

Технический частный случай: ndarray.__mul__ возвращает NotImplemented, если другой объект не является подклассом ndarray и определяет и __numpy_ufunc__, и __rmul__. Аналогичное исключение применяется для других операций, кроме умножения.

В таком случае, при вычислении бинарной операции, такой как ndarray_obj * your_obj, ваш метод __numpy_ufunc__ не будет вызван. Вместо этого выполнение передаётся вашей правой операции __rmul__, согласно стандартным правилам переопределения операторов Python.

Аналогичный частный случай применим к операциям на месте: если вы определили __rmul__, то ndarray_obj *= your_obj не вызовет вашу реализацию __numpy_ufunc__. Вместо этого произойдёт стандартное поведение Python ndarray_obj = ndarray_obj * your_obj.

Обратите внимание, что вышеизложенное обсуждение относится только к встроенному механизму бинарных операций Python. np.multiply(ndarray_obj, your_obj) всегда вызывает только ваш __numpy_ufunc__, как и ожидалось.

class.__array_finalize__(obj)

Этот метод вызывается всякий раз, когда система внутренне выделяет новый массив из obj, где obj — подкласс (подтип) ndarray. Он может использоваться для изменения атрибутов self после построения (например, для обеспечения 2-мерной матрицы) или для обновления метаданных из «родителя». Подклассы наследуют реализацию по умолчанию этого метода, которая ничего не делает.

class.__array_prepare__(array, context=None)

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

class.__array_wrap__(array, context=None)

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

class.__array_priority__

Значение этого атрибута используется для определения типа объекта, который нужно вернуть в ситуациях, когда существует более одной возможности для типа Python возвращаемого объекта. Подклассы наследуют значение по умолчанию 0.0 для этого атрибута.

class.__array__([dtype])

Если класс (подкласс ndarray или нет) с методом __array__ используется в качестве выходного объекта ufunc, результаты записываются в объект, возвращаемый методом __array__. Аналогичное преобразование выполняется и для входных массивов.

Объекты матриц

matrix объекты наследуют от ndarray и поэтому имеют те же атрибуты и методы, что и ndarray. Однако существуют шесть важных отличий объектов матриц, которые могут привести к неожиданным результатам, когда вы используете матрицы, но ожидаете, что они будут вести себя как массивы:

  1. Объекты матриц могут быть созданы с использованием строковой нотации для разрешения синтаксиса в стиле Matlab, где пробелы отделяют столбцы, а точки с запятой (';') отделяют строки.
  2. Объекты матриц всегда двумерные. Это имеет далеко идущие последствия, так как m.ravel() все еще двумерный (с 1 в первом измерении), а выбор элементов возвращает двумерные объекты, так что поведение последовательности принципиально отличается от массивов.
  3. Объекты матриц переопределяют умножение, чтобы оно было матричным умножением. Убедитесь, что вы понимаете это для функций, которые вы можете захотеть получить матрицы. Особенно с учетом того, что asanyarray(m) возвращает матрицу, когда m — матрица.
  4. Объекты матриц переопределяют возведение в степень, чтобы оно было возведением матрицы в степень. То же предупреждение о использовании возведения в степень внутри функции, которая использует asanyarray(...), чтобы получить объект массива, действует и в этом случае.
  5. Значение по умолчанию __array_priority__ для объектов матриц равно 10.0, и поэтому смешанные операции с ndarrays всегда производят матрицы.
  6. У матриц есть особые атрибуты, которые упрощают вычисления. Это

    matrix.T Возвращает транспонированную матрицу.
    matrix.H Возвращает (комплексно) сопряженную транспонированную матрицу.
    matrix.I Возвращает (мультипликативное) обратное значение обратимой матрицы.
    matrix.A Возвращает матрицу как объект ndarray.

Предупреждение

Объекты матриц переопределяют умножение, ‘*’, и возведение в степень, ‘**’, на матричное умножение и возведение матрицы в степень соответственно. Если ваша подпрограмма может принимать подклассы, и вы не преобразуете их в массивы базового класса, то вы должны использовать ufuncs multiply и power, чтобы убедиться, что вы выполняете правильную операцию для всех входных данных.

Класс матрицы является подклассом ndarray в Python и может быть использован в качестве ссылки для того, как создать свой собственный подкласс ndarray. Матрицы могут быть созданы из других матриц, строк и всего остального, что может быть преобразовано в ndarray. Название «mat» является псевдонимом для «matrix» в NumPy.

matrix Возвращает матрицу из объекта типа массив или из строки данных.
asmatrix(data[, dtype]) Интерпретирует входные данные как матрицу.
bmat(obj[, ldict, gdict]) Создает объект матрицы из строки, вложенной последовательности или массива.

Пример 1: Создание матрицы из строки

>>> a=mat('1 2 3; 4 5 3')
>>> print (a*a.T).I
[[ 0.2924 -0.1345]
 [-0.1345  0.0819]]

Пример 2: Создание матрицы из вложенной последовательности

>>> mat([[1,5,10],[1.0,3,4j]])
matrix([[  1.+0.j,   5.+0.j,  10.+0.j],
        [  1.+0.j,   3.+0.j,   0.+4.j]])

Пример 3: Создание матрицы из массива

>>> mat(random.rand(3,3)).T
matrix([[ 0.7699,  0.7922,  0.3294],
        [ 0.2792,  0.0101,  0.9219],
        [ 0.3398,  0.7571,  0.8197]])

Массивы сопоставления с памятью файла

Массивы сопоставления с памятью файла полезны для чтения и/или изменения небольших фрагментов большого файла с регулярной структурой без чтения всего файла в память. Простой подкласс ndarray использует файл сопоставления с памятью для буфера данных массива. Для небольших файлов издержки чтения всего файла в память обычно незначительны, однако для больших файлов использование сопоставления с памятью может сэкономить значительные ресурсы.

Массивы сопоставления с памятью файла имеют один дополнительный метод (кроме тех, которые они унаследовали от ndarray): .flush(), который должен быть вызван пользователем вручную, чтобы гарантировать, что любые изменения в массиве фактически записываются на диск.

memmap Создает сопоставление с памятью массива, хранящегося в бинарном файле на диске.
memmap.flush() Записывает все изменения в массиве в файл на диске.

Пример:

>>> a = memmap('newfile.dat', dtype=float, mode='w+', shape=1000)
>>> a[10] = 10.0
>>> a[30] = 30.0
>>> del a
>>> b = fromfile('newfile.dat', dtype=float)
>>> print b[10], b[30]
10.0 30.0
>>> a = memmap('newfile.dat', dtype=float)
>>> print a[10], a[30]
10.0 30.0

Символьные массивы (numpy.char)

См. также

Создание символьных массивов (numpy.char)

Примечание

Класс chararray существует для обратной совместимости с Numarray, его не рекомендуется использовать в новых разработках. Начиная с numpy 1.4, если требуется массив строк, рекомендуется использовать массив с типом dtype object_, string_ или unicode_, и использовать свободные функции в модуле numpy.char для быстрых векторизованных строковых операций.

Это улучшенные массивы типа string_ или unicode_. Эти массивы наследуют от ndarray, но специально определяют операции +, *, и % по (векторизованному) элементному принципу. Эти операции недоступны для стандартного ndarray символьного типа. Кроме того, chararray содержит все стандартные методы string (и unicode), выполняемые по элементному принципу. Возможно, самый простой способ создания chararray — использовать self.view(chararray), где self — ndarray с типом данных str или unicode. Однако chararray также можно создать, используя конструктор numpy.chararray, или функцию numpy.char.array:

chararray Предоставляет удобный вид на массивы строковых и unicode-значений.
core.defchararray.array(obj[, itemsize, ...]) Создает chararray.

Еще одно отличие от стандартного ndarray типа данных str заключается в том, что chararray наследует функцию, введенную Numarray, что пробелы в конце любого элемента массива игнорируются при получении элементов и сравнении операций.

Массивы записей (numpy.rec)

См. также

Создание массивов записей (numpy.rec), Процедуры типа данных, Объекты типа данных (dtype).

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

recarray Создает ndarray, который позволяет получать доступ к полям с помощью атрибутов.
record Скаляр типа данных, который позволяет получить доступ к полям как к поиску по атрибутам.

Маскированные массивы (numpy.ma)

См. также

Маскированные массивы

Стандартный класс контейнера

Для обратной совместимости и как стандартный «контейнерный» класс, UserArray из Numeric был перенесен в NumPy и переименован в numpy.lib.user_array.container. Класс контейнера — это класс Python, у которого атрибут self.array является ndarray. Многократное наследование, вероятно, проще с numpy.lib.user_array.container, чем с самим ndarray, поэтому оно включено по умолчанию. Здесь он не документируется, кроме упоминания о его существовании, так как вы должны использовать класс ndarray напрямую, если можете.

numpy.lib.user_array.container(data[, ...]) Стандартный класс-контейнер для простого множественного наследования.

Итераторы массивов

Итераторы — мощная концепция для обработки массивов. По сути, итераторы реализуют обобщенную конструкцию цикла for. Если myiter — это объект итератора, то Python-код:

for val in myiter:
    ...
    some code involving val
    ...

вызывает val = myiter.next() многократно до тех пор, пока StopIteration не будет поднята итератором. Существует несколько способов перебора массива, которые могут быть полезны: стандартный итератор, плоский итератор и N-мерная нумерация.

Стандартный итератор

Стандартный итератор объекта ndarray — это стандартный Python-итератор типа последовательности. Таким образом, когда сам объект массива используется как итератор. Стандартное поведение эквивалентно:

for i in range(arr.shape[0]):
    val = arr[i]

Этот стандартный итератор выбирает подмассив размерности N-1 из массива. Это может быть полезной конструкцией для определения рекурсивных алгоритмов. Для перебора всего массива требуется N цикла for.

>>> a = arange(24).reshape(3,2,4)+10
>>> for val in a:
...     print 'item:', val
item: [[10 11 12 13]
 [14 15 16 17]]
item: [[18 19 20 21]
 [22 23 24 25]]
item: [[26 27 28 29]
 [30 31 32 33]]

Плоский итератор

ndarray.flat Одномерный итератор по массиву.

Как упоминалось ранее, атрибут flat объектов ndarray возвращает итератор, который перебирает весь массив в стиле C — непрерывном порядке.

>>> for i, val in enumerate(a.flat):
...     if i%5 == 0: print i, val
0 10
5 15
10 20
15 25
20 30

Здесь я использовал встроенный итератор enumerate для возврата индекса итератора, а также значения.

N-мерная нумерация

ndenumerate(arr) Многомерный индексный итератор.

Иногда может быть полезно получить N-мерный индекс во время перебора. Итератор ndenumerate может этого достичь.

>>> for i, val in ndenumerate(a):
...     if sum(i)%5 == 0: print i, val
(0, 0, 0) 10
(1, 1, 3) 25
(2, 0, 3) 29
(2, 1, 2) 32

Итератор для широковещательной передачи

broadcast Производит объект, имитирующий широковещательную передачу.

Общая концепция широковещательной передачи также доступна из Python с помощью итератора broadcast. Этот объект принимает N объекты в качестве входных данных и возвращает итератор, возвращающий кортежи, содержащие каждый элемент входных последовательностей в результате широковещательной передачи.

>>> for val in broadcast([[1,0],[2,3]],[0,1]):
...     print val
(1, 0)
(0, 1)
(2, 0)
(3, 1)

© 2008–2017 NumPy Developers
Licensed under the NumPy License.
https://docs.scipy.org/doc/numpy-1.12.0/reference/arrays.classes.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API