создание массива 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 15

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])

Вы можете попробовать что-то вроде:

a = np.hstack(([0.2],np.linspace(1,60,60),[60.8]))
np.concatenate([[.2], linspace(1,60,60), [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, что я готов поспорить, что многие люди, которые приходят на эту страницу, захотят узнать это. (Я пришел сюда вместо того, чтобы задать новый вопрос.)