2013-05-13 1 views
2

Я относительно новичок в python, но я пытаюсь понять что-то, что кажется основным.Почему x [:, 0] = x [0] для однострочного вектора?

Создать вектор:

x = np.linspace(0,2,3) 
Out[38]: array([ 0., 1., 2.]) 

теперь, почему не х [:, 0] значение аргумента?

IndexError: invalid index 

Это должно быть x [0]. У меня есть функция, которую я звоню, которая вычисляет:

np.sqrt(x[:,0]**2 + x[:,1]**2 + x[:,2]**2) 

Почему я не могу сказать, что я прав, независимо от ввода? Это много других языков, оно не зависит от наличия других строк в массиве. Возможно, я неправильно понимаю что-то фундаментальное - извините, если так. Я бы хотел избежать:

if len(x) == 1: 
    norm = np.sqrt(x[0]**2 + x[1]**2 + x[2]**2) 
else: 
    norm = np.sqrt(x[:,0]**2 + x[:,1]**2 + x[:,2]**2) 

всюду. Конечно, есть способ обойти это ... спасибо.

Edit: пример его работы на другом языке Matlab:

>> b = [1,2,3] 
b = 
    1  2  3 
>> b(:,1) 
ans = 
    1 
>> b(1) 
ans = 

    1 
+3

Это неправда, потому что вы указали индекс для измерения 1 и индекс для измерения 2, когда ваш массив имеет только одно измерение. Python является явным, а не подразумеваемым. Приведите пример на другом языке, и мы поможем вам написать интерпретацию массива, который делает те же неявные предположения. – Paul

+0

См. Править, пожалуйста. – Griff

+1

Вы можете написать 'x.ndim' вместо' len (x) '. Это не изменит, но это четкое и понятное имя. – jorgeca

ответ

3

я, как правило, решить эту проблему, написав

x = np.atleast_2d(x) 
norm = np.sqrt(x[:,0]**2 + x[:,1]**2 + x[:,2]**2) 

Matlab не имеет 1D массивов, поэтому b=[1 2 3] еще 2D массив и индексирование с двумя измерениями имеет смысл. Это может быть новая концепция для вас, но они весьма полезны на самом деле (вы можете перестать беспокоиться о том, нужно ли умножать транспонирование, вставить строку или столбец в другой массив ...)

Кстати, вы могли бы написать любитель, более общую норму, как это:

x = np.atleast_2d(x) 
norm = np.sqrt((x**2).sum(axis=1)) 
1

проблема заключается в том, что х [:, 0] в Python не то же самое, как и в Matlab. Если вы хотите извлечь первый элемент в одном векторе строки вы должны идти с

x[:1] 

Это называется «срез». В этом примере это означает, что вы берете все в массиве от первого элемента к элементу с индексом 1 (не включается).

Помните, что Python имеет нулевую нумерацию.

Другим примером может быть:

x[0:2] 

, который будет возвращать первый и второй элемент массива.

7

Похоже, что эллипс, описанный @JanneKarila, ответил на ваш вопрос, но я хотел бы указать, как вы можете сделать свой код немного более «numpythonic». Кажется, вы хотите обработать n-мерный массив с формой (d_1, d_2, ..., d_ {n-1}, 3) и вычислить величины этого набора трехмерных векторов, в результате чего (n-1) -мерный массив с формой (d_1, d_2, ..., d_ {n-1}). Один простой способ сделать это состоит в том, чтобы скомпоновать все элементы, а затем суммировать вдоль последней оси, а затем взять квадратный корень. Если x является массивом, этот расчет можно записать np.sqrt(np.sum(x**2, axis=-1)). Ниже приведено несколько примеров.

х представляет 1-D, с формой (3):

In [31]: x = np.array([1.0, 2.0, 3.0]) 

In [32]: np.sqrt(np.sum(x**2, axis=-1)) 
Out[32]: 3.7416573867739413 

х 2-D с формой (2, 3):

In [33]: x = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) 

In [34]: x 
Out[34]: 
array([[ 1., 2., 3.], 
     [ 4., 5., 6.]]) 

In [35]: np.sqrt(np.sum(x**2, axis=-1)) 
Out[35]: array([ 3.74165739, 8.77496439]) 

х 3-D , с формой (2, 2, 3):

In [36]: x = np.arange(1.0, 13.0).reshape(2,2,3) 

In [37]: x 
Out[37]: 
array([[[ 1., 2., 3.], 
     [ 4., 5., 6.]], 

     [[ 7., 8., 9.], 
     [ 10., 11., 12.]]]) 

In [38]: np.sqrt(np.sum(x**2, axis=-1)) 
Out[38]: 
array([[ 3.74165739, 8.77496439], 
     [ 13.92838828, 19.10497317]]) 
+0

А, это гораздо приятнее, чем вызов 'np.atleast_2d' и суммирование вдоль первой оси, как в моем ответе. – jorgeca