Создание массива 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. Я знаю, как сделать это для доступа к позициям в массиве, хотя не при создании последовательности.
Любая помощь будет оценена,
спасибо!
Ответы
Ответ 1
Well NumPy реализует функцию создания массива MATLAB, вектор, используя две функции вместо одного - каждый неявно указывает конкретную ось, по которой должно происходить конкатенация. Эти функции:
Итак, для вашего примера эквивалент 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]
Обозначение среза работает как ожидалось [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])
Ответ 2
Вы можете попробовать что-то вроде:
a = np.hstack(([0.2],np.linspace(1,60,60),[60.8]))
Ответ 3
np.concatenate([[.2], linspace(1,60,60), [60.8]])
Ответ 4
Выполняет ли arange(0.2,60.8,0.2)
то, что вы хотите?
http://docs.scipy.org/doc/numpy/reference/generated/numpy.arange.html
Ответ 5
Мне как-то нравится идея построения этих сегментированных диапазонов, о которых вы говорили. Если вы используете их много, возможно, небольшая функция, например
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.
Ответ 6
если я правильно понимаю 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
ожидает итерабельность, которая является последовательностью или последовательностью последовательностей, которые имеют одинаковую длину.
Ответ 7
Посмотрите np.r_
. Это в основном эквивалентно тому, что предложили все остальные, но если вы пришли из Matlab, это немного интуитивно (и если вы исходите из любого другого языка, это немного противоречит интуиции).
В качестве примера vector=[0.2,1:60,60.8];
переводится на:
vector = np.r_[0.2, 1:61, 60.8]
Ответ 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]
Я знаю, что это не технически новый ответ, но использование двоеточия для построения массива при индексировании в матрицу кажется настолько естественным в Matlab, я уверен, что многие люди, которые приходят на эту страницу, захотят это узнать. (Я пришел сюда вместо того, чтобы задавать новый вопрос.)
Ответ 9
Самый простой способ с помощью numpy.repeat() ||| numpy.tile()
a = np.array([1,2,3,4,5])
np.r_[np.repeat(a,3),np.tile(a,3)]