Разделение по элементам Numpy работает не так, как ожидалось

#python #numpy

#python #numpy

Вопрос:

Из документов, вот как обычно работает разделение элементов

 a1 = np.array([8,12,14])
b1 = np.array([4,6,7])
a1/b1
array([2, 2, 2])
  

Которое работает. Я пытаюсь сделать то же самое, я думаю, на разных массивах, и это не так. Для двух трехмерных векторов он возвращает матрицу 3×3. Я даже убедился, что их «форма одинакова», но никакой разницы.

 >> t
array([[  3.17021277e 00],
       [  4.45795858e-15],
       [  7.52842809e-01]])
>> s
array([  1.00000000e 00,   7.86202619e 02,   7.52842809e-01])
>> t/s
array([[  3.17021277e 00,   4.03231011e-03,   4.21098897e 00],
       [  4.45795858e-15,   5.67024132e-18,   5.92149984e-15],
       [  7.52842809e-01,   9.57568432e-04,   1.00000000e 00]])
t/s.T
array([[  3.17021277e 00,   4.03231011e-03,   4.21098897e 00],
       [  4.45795858e-15,   5.67024132e-18,   5.92149984e-15],
       [  7.52842809e-01,   9.57568432e-04,   1.00000000e 00]])
  

Комментарии:

1. Для одномерного массива s == s.T .

2. @undefinedisnotafunction хорошо, но зачем возвращать матрицу 3×3 при разделении по элементам?

3. Я думаю, что s должно быть array ([[ 1.00000000e 00, 7.86202619e 02, 7.52842809e-01 ]])

4. @yayu Из-за трансляции .

5. @undefinedisnotafunction эта ссылка возвращает 404

Ответ №1:

Это потому, что формы ваших двух массивов являются t.shape = (3,1) и s.shape = (3,). Итак, применяются правила трансляции: они гласят, что если два измерения равны, то делайте это поэлементно, если они не совпадают, произойдет сбой, если одно из них не равно единице, и вот тут становится интересно: в этом случае массив с размером в единицу повторит операцию по всем элементам другого измерения.

Я думаю, то, что вы хотите сделать, было бы

 t[:,0] / s
  

или

 np.squeeze(t) / s
  

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

 a = np.arange(3)
b = np.arange(3)
  

поэлементно вы можете сделать сейчас:

 a*b = [0,1,4]
  

Если вы хотите, чтобы эта операция выполнялась между всеми элементами, вы можете вставить эти измерения размера one следующим образом:

 a[np.newaxis,:] * b[:,np.newaxis]
  

Попробуйте! Это действительно удобная концепция, хотя я вижу, как это поначалу сбивает с толку.