Разница между формой numpy.array (R, 1) и (R,)

В numpy некоторые из операций возвращаются в форме (R, 1) но некоторые возвращают (R,) . Это сделает матричное умножение более утомительным, поскольку требуется явная reshape . Например, учитывая матрицу M , если мы хотим сделать numpy.dot(M[:,0], numpy.ones((1, R))) где R – количество строк (конечно, та же проблема также происходит по столбцам). Мы получим matrices are not aligned ошибкой, так как M[:,0] имеет форму (R,) но numpy.ones((1, R)) имеет форму (1, R) .

Поэтому мои вопросы:

  • Выражение степени сложности матрицы дает отрицательное значение
  • Найти индексы значения в матрице 2d
  • Matlab vs Python: Изменить форму
  • используя SciPy для интеграции функции, возвращающей матрицу или массив
  • Список смежности и матрица смежности в Python
  • Существует ли стандартное решение для исключения Гаусса в Python?
    1. В чем разница между формой (R, 1) и (R,) . Я знаю буквально это список номеров и список списков, где весь список содержит только число. Просто интересно, почему бы не дизайн numpy чтобы он предпочитал форму (R, 1) вместо (R,) для упрощения матричного умножения.

    2. Есть ли лучшие способы для вышеупомянутого примера? Без явного изменения формы: numpy.dot(M[:,0].reshape(R, 1), numpy.ones((1, R)))

  • Преобразование двух списков в матрицу
  • Найти индексы значения в матрице 2d
  • Как я могу анализировать матрицу путаницы?
  • numable преобразовать вектор строки в вектор столбца
  • Сделать специальную диагональную матрицу в Numpy
  • Создайте матрицу из текстового файла - python
  • 4 Solutions collect form web for “Разница между формой numpy.array (R, 1) и (R,)”

    1. Значение фигур в NumPy

    Вы пишете: «Я знаю буквально, что это список номеров и список списков, где весь список содержит только число», но это немного бесполезный способ подумать об этом.

    Лучший способ думать о массивах NumPy состоит в том, что они состоят из двух частей: буфера данных, который является всего лишь блоком необработанных элементов, и представления, которое описывает, как интерпретировать буфер данных.

    Например, если мы создадим массив из 12 целых чисел:

     >>> a = numpy.arange(12) >>> a array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) 

    Затем a состоит из буфера данных, устроенного примерно так:

     ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │ └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘ 

    и представление, которое описывает, как интерпретировать данные:

     >>> a.flags C_CONTIGUOUS : True F_CONTIGUOUS : True OWNDATA : True WRITEABLE : True ALIGNED : True UPDATEIFCOPY : False >>> a.dtype dtype('int64') >>> a.itemsize 8 >>> a.shape (12,) 

    Здесь форма (12,) означает, что массив индексируется одним индексом, который работает от 0 до 11. Концептуально, если мы будем называть этот единственный индекс i , массив a выглядит так:

     i= 0 1 2 3 4 5 6 7 8 9 10 11 ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │ └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘ 

    Если мы изменим форму массива, это не изменит буфер данных. Вместо этого он создает новое представление, которое описывает другой способ интерпретации данных. Так после:

     >>> b = a.reshape((3, 4)) 

    массив b имеет тот же буфер данных, что и a , но теперь он индексируется двумя индексами, которые работают от 0 до 2 и от 0 до 3 соответственно. Если мы обозначим два индекса i и j , массив b выглядеть так:

     i= 0 0 0 0 1 1 1 1 2 2 2 2 j= 0 1 2 3 0 1 2 3 0 1 2 3 ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │ └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘ 

    Который означает, что:

     >>> b[2,1] 9 

    Вы можете видеть, что второй индекс изменяется быстро, и первый индекс медленно изменяется. Если вы предпочитаете, чтобы это было наоборот, вы можете указать параметр order :

     >>> c = a.reshape((3, 4), order='F') 

    который приводит к индексированию массива следующим образом:

     i= 0 1 2 0 1 2 0 1 2 0 1 2 j= 0 0 0 1 1 1 2 2 2 3 3 3 ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │ └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘ 

    Который означает, что:

     >>> c[2,1] 5 

    Теперь должно быть ясно, что означает, что массив имеет форму с одним или несколькими размерами размера 1. После:

     >>> d = a.reshape((12, 1)) 

    массив d индексируется двумя индексами, первый из которых выполняется от 0 до 11, а второй индекс всегда равен 0:

     i= 0 1 2 3 4 5 6 7 8 9 10 11 j= 0 0 0 0 0 0 0 0 0 0 0 0 ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │ └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘ 

    и так:

     >>> d[10,0] 10 

    Измерение длины 1 является «бесплатным» (в некотором смысле), так что вам ничего не мешает отправиться в город:

     >>> e = a.reshape((1, 2, 1, 6, 1)) 

    давая массив, индексированный следующим образом:

     i= 0 0 0 0 0 0 0 0 0 0 0 0 j= 0 0 0 0 0 0 1 1 1 1 1 1 k= 0 0 0 0 0 0 0 0 0 0 0 0 l= 0 1 2 3 4 5 0 1 2 3 4 5 m= 0 0 0 0 0 0 0 0 0 0 0 0 ┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐ │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │ └────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘ 

    и так:

     >>> e[0,1,0,0,0] 6 

    Дополнительную информацию о том, как используются массивы, см. В документации по внутренним документам NumPy .

    2. Что делать?

    Поскольку numpy.reshape просто создает новое представление, вы не должны бояться использовать его, когда это необходимо. Это правильный инструмент для использования, когда вы хотите индексировать массив по-другому.

    Однако при длительном вычислении обычно можно организовать сборку массивов с «правильной» формой в первую очередь и таким образом минимизировать количество преобразований и транспонирует. Но, не видя фактического контекста, который привел к необходимости изменения, трудно сказать, что следует изменить.

    Пример в вашем вопросе:

     numpy.dot(M[:,0], numpy.ones((1, R))) 

    но это нереально. Во-первых, это выражение:

     M[:,0].sum() 

    вычисляет результат более просто. Во-вторых, действительно ли что-то особенное в колонке 0? Возможно, вам действительно нужно:

     M.sum(axis=0) 

    Разница между (R,) и (1, R) – это буквально количество указаний, которые вам нужно использовать. ((1, R)) – это 2-мерный массив, который имеет только одну строку. (R) – вектор. Как правило, если для переменной не имеет смысла иметь более одной строки / столбца, вы должны использовать вектор, а не матрицу с одноэлементным размером.

    Для вашего конкретного случая есть несколько вариантов:

    1) Просто сделайте второй аргумент вектором. Следующее работает отлично:

      np.dot(M[:,0], np.ones(R)) 

    2) Если вам нужны операции с матричной матрицей, используйте матрицу класса вместо ndarray. Все матрицы вынуждены быть двумерными массивами, а оператор «*» выполняет умножение матрицы вместо элементарного (так что вам не нужна точка). По моему опыту, это большая проблема, что это стоит, но может быть приятно, если вы привыкли к Matlab.

    Для его базового класса массивов 2d массивы не более особенны, чем 1d или 3d. Есть некоторые операции, которые сохраняют размеры, некоторые из них уменьшают их, другие объединяют или даже расширяют их.

     M=np.arange(9).reshape(3,3) M[:,0].shape # (3,) selects one column, returns a 1d array M[0,:].shape # same, one row, 1d array M[:,[0]].shape # (3,1), index with a list (or array), returns 2d M[:,[0,1]].shape # (3,2) In [20]: np.dot(M[:,0].reshape(3,1),np.ones((1,3))) Out[20]: array([[ 0., 0., 0.], [ 3., 3., 3.], [ 6., 6., 6.]]) In [21]: np.dot(M[:,[0]],np.ones((1,3))) Out[21]: array([[ 0., 0., 0.], [ 3., 3., 3.], [ 6., 6., 6.]]) 

    Другие выражения, которые дают один и тот же массив

     np.dot(M[:,0][:,np.newaxis],np.ones((1,3))) np.dot(np.atleast_2d(M[:,0]).T,np.ones((1,3))) np.einsum('i,j',M[:,0],np.ones((3))) M1=M[:,0]; R=np.ones((3)); np.dot(M1[:,None], R[None,:]) 

    MATLAB начинался с двухмерных массивов. Более новые версии допускают большее количество измерений, но сохраняют нижнюю границу 2. Но вам все равно нужно обратить внимание на разницу между матрицей строк и столбцом один с формой (1,3) v (3,1) . Как часто вы писали [1,2,3].' ? Я собирался написать row vector column vector , но с этим ограничением 2d нет никаких векторов в MATLAB – по крайней мере, не в математическом смысле вектор как 1d.

    Вы посмотрели np.atleast_2d (также версии _1d и _3d)?

    1) Причина не в том, чтобы предпочесть форму (R, 1) над (R,) это то, что она излишне усложняет ситуацию. Кроме того, почему было бы предпочтительнее иметь форму (R, 1) по умолчанию для вектора длины-R вместо (1, R) ? Лучше держать его простым и быть явным, когда вам нужны дополнительные размеры.

    2) Для вашего примера вы вычисляете внешний продукт, чтобы вы могли сделать это без вызова reshape с помощью np.outer :

     np.outer(M[:,0], numpy.ones((1, R))) 
    Python - лучший язык программирования в мире.