создание массива numpy с помощью последовательности
Я нахожусь в своем переходном путешествии от MATLAB к scipy (+numpy)+matplotlib. У меня постоянно возникают проблемы при реализации некоторых вещей. Я хочу создать простой векторный массив из трех различных частей. В MATLAB я бы сделал что-то вроде:
vector=[0.2,1:60,60.8];
Это приводит к одномерному массиву из 62 позиций. Я пытаюсь реализовать это с помощью scipy. Ближе всего я сейчас к этому:
a=[[0.2],linspace(1,60,60),[60.8]]
Однако это создает список, а не массив, и поэтому я не могу преобразовать его в векторный массив. Но затем, когда я делаю это, я получаю ошибку
a=array([[0.2],linspace(1,60,60),[60.8]])
ValueError: setting an array element with a sequence.
Я считаю, что мое главное препятствие заключается в том, что я не могу понять, как перевести эту простую операцию в MATLAB:
a=[1:2:20];
К numpy. Я знаю, как это сделать, чтобы получить доступ к позициям в массиве,хотя и не при создании последовательности. Любая помощь будет оценена по достоинству, Спасибо!
8 ответов:
Хорошо NumPy реализует функцию создания массива MATLAB, вектор , используядве функции вместо одной-каждая неявно определяет определенную ось, вдоль которойдолжна происходить конкатенация . Эти функции являются следующими:
R_ (последовательная конкатенация) и
C_ (по столбцам)
Итак, для вашего примера эквивалент NumPy:
>>> import numpy as NP >>> v = NP.r_[.2, 1:10, 60.8] >>> print(v) [ 0.2 1. 2. 3. 4. 5. 6. 7. 8. 9. 60.8]
По столбцам аналогом является:
>>> NP.c_[.2, 1:10, 60.8]
нотация slice работает как ожидалось [start: stop: step]:
>>> v = NP.r_[.2, 1:25:7, 60.8] >>> v array([ 0.2, 1. , 8. , 15. , 22. , 60.8])
Хотя если в качестве третьего аргумента используетсямнимое число , то срезающая нотация ведет себя так: linspace:
>>> v = NP.r_[.2, 1:25:7j, 60.8] >>> v array([ 0.2, 1. , 5. , 9. , 13. , 17. , 21. , 25. , 60.8])
В противном случае он ведет себя как arange:>>> v = NP.r_[.2, 1:25:7, 60.8] >>> v array([ 0.2, 1. , 8. , 15. , 22. , 60.8])
Делает ли
arange(0.2,60.8,0.2)
то, что вы хотите?Http://docs.scipy.org/doc/numpy/reference/generated/numpy.arange.html
Мне почему-то нравится идея построения этих сегментированных диапазонов, о которых вы упомянули. Если вы используете их много, возможно, небольшая функция, такая как
import numpy as np def segrange(*args): result = [] for arg in args: if hasattr(arg,'__iter__'): result.append(range(*arg)) else: result.append([arg]) return np.concatenate(result)
Это дает вам
>>> segrange(1., (2,5), (5,10,2)) [ 1. 2. 3. 4. 5. 7. 9.]
Было бы неплохо иметь. Хотя, я бы, вероятно, пошел за ответом, используя concatenate/hstack.
Если я правильно понимаю matlab, вы можете выполнить что-то вроде этого, используя:
Но, возможно, есть и лучший способ...a=np.array([0.2]+list(range(1,61))+[60.8])
list(range(1,61))
может быть простоrange(1,61)
, Если вы используете python 2.X.Это работает, создавая 3 списка и затем объединяя их с помощью оператора
+
.Причина, по которой ваша первоначальная попытка не сработала, заключается в том, что
a=[ [0.2], np.linspace(1,60,60), [60.8] ]
создает список списков -- другими словами:a[0] == [0.2] #another list (length 1) a[1] == np.linspace(1,60,60) #an array (length 60) a[2] == [60.8] #another list (length 1)
Функция
array
ожидает итерацию, которая является последовательность или последовательность последовательностей одинаковой длины.
Взгляните на
np.r_
. Это в основном эквивалентно тому, что предлагали все остальные, но если вы исходите из matlab, это немного более интуитивно (и если вы исходите из любого другого языка, это немного противоречит интуиции).В качестве примера,
vector=[0.2,1:60,60.8];
переводится в:vector = np.r_[0.2, 1:61, 60.8]
Просто хочу отметить для всех других людей, переходящих из MATLAB в Numpy, что вы можете построить np.массив r_ с двоеточиями и затем использовать его для индексации
Например, если у вас есть в matlab
arr_ones = ones(10,10)
Или в Numpy
arr_ones = np.ones([10,10])
В Matlab вы можете взять только столбцы с 1 по 5, а также 7, как это:
arr_ones(:,[1:5 7])
Делать то же самое в Numpy не является (по крайней мере, для меня) интуитивным. Это даст вам ошибку "недопустимый синтаксис":
arr_ones[:,[1:5,7]]
Однако это работает:
inds = np.r[1:5,] arr_ones[:,inds]
I знаю, что технически это не новый ответ, но использование двоеточия для построения массива при индексации в матрицу кажется настолько естественным в Matlab, что я готов поспорить, что многие люди, которые приходят на эту страницу, захотят узнать это. (Я пришел сюда вместо того, чтобы задать новый вопрос.)