В чем разница между массивами numpy и матрицами? Какой из них я должен использовать?

Каковы преимущества и недостатки каждого?

Из того, что я видел, любой может работать как замена для другого, если это необходимо, так что я должен беспокоиться об использовании обоих или я должен придерживаться только одного из них?

Будет ли стиль программы влиять на мой выбор? Я занимаюсь некоторым машинным обучением с использованием numpy, поэтому действительно много матриц, но также множество векторов (массивов).

Ответ 1

Матрицы нумерации строго двумерные, а массивы numpy (ndarrays) - N-мерные. Матричные объекты являются подклассом ndarray, поэтому они наследуют все атрибуты и методы ndarrays.

Основным преимуществом матриц numpy является то, что они обеспечивают удобное обозначение для матричного умножения: если a и b являются матрицами, то a * b является их матричным произведением.

import numpy as np

a=np.mat('4 3; 2 1')
b=np.mat('1 2; 3 4')
print(a)
# [[4 3]
#  [2 1]]
print(b)
# [[1 2]
#  [3 4]]
print(a*b)
# [[13 20]
#  [ 5  8]]

С другой стороны, с Python 3.5 NumPy поддерживает умножение матриц префикса с помощью оператора @, поэтому вы можете добиться такого же удобства матричного умножения с ndarrays в Python> = 3.5.

import numpy as np

a=np.array([[4, 3], [2, 1]])
b=np.array([[1, 2], [3, 4]])
print([email protected])
# [[13 20]
#  [ 5  8]]

Оба объекта матрицы и ndarrays имеют .T чтобы возвращать транспонирование, но объекты матрицы также имеют .H для сопряженного транспонирования и .I для обратного.

Напротив, массивы numpy последовательно придерживаются правила, согласно которому операции применяются элементарно (кроме нового оператора @). Таким образом, если a и b являются массивами numpy, тогда a*b - это массив, сформированный путем умножения компонентов по элементу:

c=np.array([[4, 3], [2, 1]])
d=np.array([[1, 2], [3, 4]])
print(c*d)
# [[4 6]
#  [6 4]]

Чтобы получить результат умножения матрицы, вы используете np.dot (или @ в Python> = 3.5, как показано выше):

print(np.dot(c,d))
# [[13 20]
#  [ 5  8]]

Оператор ** также ведет себя по-разному:

print(a**2)
# [[22 15]
#  [10  7]]
print(c**2)
# [[16  9]
#  [ 4  1]]

Так как a - матрица, a**2 возвращает матричное произведение a*a. Поскольку c является ndarray, c**2 возвращает ndarray с каждым компонентом в квадрате по элементу.

Существуют и другие технические различия между объектами матрицы и ndarrays (связанные с np.ravel, выбором элементов и поведением последовательности).

Основным преимуществом массивов numpy является то, что они являются более общими, чем 2-мерные матрицы. Что происходит, когда вам нужен 3-мерный массив? Затем вы должны использовать ndarray, а не объект матрицы. Таким образом, обучение использованию матричных объектов - большая работа - вам нужно изучить операции с матричными объектами и операции ndarray.

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

Напротив, если вы придерживаетесь только ndarrays, то вы можете делать все, что могут делать объекты матрицы, и многое другое, за исключением нескольких разных функций/нотации.

Если вы готовы отказаться от визуальной привлекательности номенклатуры продуктов NumPy (что может быть достигнуто почти так же элегантно с ndarrays в Python> = 3.5), то я думаю, что массивы NumPy - это определенно путь.

PS. Конечно, вам действительно не нужно выбирать один за счет другого, так как np.asmatrix и np.asarray позволяют вам конвертировать один в другой (пока массив 2-мерный).


Существует краткий обзор различий между NumPy arrays против NumPy matrix эс здесь.

Ответ 2

Scipy.org рекомендует использовать массивы:

* 'array' или 'matrix'? Что я должен использовать? - Короткий ответ

Использовать массивы.

  • Они представляют собой стандартный векторный/матричный/тензорный тип numpy. Многие возвращаемые массивы numpy возвращают, а не матрицы.

  • Существует четкое различие между элементарными операциями и операции линейной алгебры.

  • Вы можете иметь стандартные векторы или векторы строк/столбцов, если хотите.

Единственным недостатком использования типа массива является то, что вам придется используйте dot вместо *, чтобы умножить (уменьшить) два тензора (скалярное произведение, матричное векторное умножение и т.д.).

Ответ 3

Просто добавьте один случай в список unutbu.

Одна из самых больших практических различий для меня в numpy ndarrays по сравнению с матрицами numpy или матричными языками, такими как matlab, заключается в том, что измерение не сохраняется в операциях сокращения. Матрицы всегда 2d, а среднее для массива, например, имеет один размер меньше.

Например, введите строки матрицы или массива:

с матрицей

>>> m = np.mat([[1,2],[2,3]])
>>> m
matrix([[1, 2],
        [2, 3]])
>>> mm = m.mean(1)
>>> mm
matrix([[ 1.5],
        [ 2.5]])
>>> mm.shape
(2, 1)
>>> m - mm
matrix([[-0.5,  0.5],
        [-0.5,  0.5]])

с массивом

>>> a = np.array([[1,2],[2,3]])
>>> a
array([[1, 2],
       [2, 3]])
>>> am = a.mean(1)
>>> am.shape
(2,)
>>> am
array([ 1.5,  2.5])
>>> a - am #wrong
array([[-0.5, -0.5],
       [ 0.5,  0.5]])
>>> a - am[:, np.newaxis]  #right
array([[-0.5,  0.5],
       [-0.5,  0.5]])

Я также думаю, что смешивание массивов и матриц приводит к множеству "счастливых" отладочных часов. Тем не менее, scipy.sparse-матрицы всегда являются матрицами в терминах операторов типа умножения.

Ответ 4

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

Однако в Python 3.5 наконец-то есть выделенный инфиксный оператор для умножения матрицы: @.

С недавними версиями NumPy его можно использовать с ndarray s:

A = numpy.ones((1, 3))
B = numpy.ones((3, 3))
A @ B

Итак, теперь, еще больше, когда вы сомневаетесь, вы должны придерживаться ndarray.