2014-10-07 5 views
1

Думаю, у меня небольшой день, и я не могу это понять. У меня есть массив m x n numpy и вы хотите преобразовать его в вектор, где каждый элемент представляет собой трехмерный вектор, содержащий номер строки, номер столбца и значение всех элементов в массиве.Numpy: вектор индексов и значений

Например, если задан массив numpy, то первый элемент в векторе будет: [1, 1, a [1, 1]], тогда следующий будет [1, 2, a [1, 2 ]] и т.д.

+0

Вы хотите работать с массивами 'm x n' или с массивами' n x 2'? – Bakuriu

+0

@Bakuriu Я хотел бы, чтобы он масштабировался на все размеры, пожалуйста. – user2909415

+0

В Python и индексировании numpy начинается с '0'. Таким образом, первым элементом будет '[0, 0, a [0,0]]'. – hpaulj

ответ

1

Эта последовательность производит (3, Н * м) массива с индексами и значением

In [786]: A = np.arange(12).reshape(3,4) 
In [787]: X=np.vstack([np.indices(A.shape),A[None,...]]).reshape(3,-1) 
In [788]: X.shape 
Out[788]: (3, 12) 
In [789]: X 
Out[789]: 
array([[ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2], 
     [ 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3], 
     [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]]) 

Это может быть перенесено, чтобы каждый «строки» представляет элемент:

In [793]: X.T[0,:] 
Out[793]: array([0, 0, 0]) 
In [794]: X.T[10,:] 
Out[794]: array([ 2, 2, 10]) 

Его также можно отливать в структурированный массив длиной (n*m,) и dtype('i4,i4,i4'). Этот пример немного сумбурно, но это делает работу:

In [796]: dt=np.dtype('i4,i4,i4') 
In [806]: X1=np.zeros(X.shape[1],dtype=dt) 
In [809]: X1['f0']=X[0] 
In [810]: X1['f1']=X[1] 
In [811]: X1['f2']=X[2] 
# or more compactly: for i,n in enumerate(X1.dtype.names): X1[n] = X[i,:] 
In [812]: X1 
Out[812]: 
array([(0, 0, 0), (0, 1, 1), (0, 2, 2), (0, 3, 3), (1, 0, 4), (1, 1, 5), 
     (1, 2, 6), (1, 3, 7), (2, 0, 8), (2, 1, 9), (2, 2, 10), (2, 3, 11)], 
     dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4')]) 
In [813]: X1[10] 
Out[813]: (2, 2, 10) # note, this a tuple 
In [814]: X1['f2'] 
Out[814]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) 

Допустим, исходная матрица является поплавки, и мы хотим сохранить этот тип в новом массиве. Мы могли бы сделать это, пропуская vstack шаг:

In [833]: A = np.arange(12,dtype=float).reshape(3,4) 
In [834]: X = np.indices(A.shape).reshape(2,-1) 
... 
In [848]: dt=np.dtype([('row',int), ('col',int), ('value',float)]) 
In [850]: X1 = np.zeros(X.shape[1], dtype=dt) 
In [851]: X1['row']=X[0,:] 
In [852]: X1['col']=X[1,:] 
In [853]: X1['value']=A.flatten() 
In [854]: X1 
Out[854]: 
array([(0, 0, 0.0), (0, 1, 1.0), (0, 2, 2.0), (0, 3, 3.0), (1, 0, 4.0), 
     (1, 1, 5.0), (1, 2, 6.0), (1, 3, 7.0), (2, 0, 8.0), (2, 1, 9.0), 
     (2, 2, 10.0), (2, 3, 11.0)], 
     dtype=[('row', '<i4'), ('col', '<i4'), ('value', '<f8')]) 
In [855]: X1[10] 
Out[855]: (2, 2, 10.0) 

X1[10] является 0D массив с DTYPE dt, и форма (), которая печатает в виде кортежа.

1

Я думаю, что что-то, как это должно работать:

n = 10 
m = 5 

data = np.random.randn(n, m) 
grid = np.indices(data.shape) 
r = np.array([grid[0], grid[1], data]) 
result = np.array(zip(*r.T)) 

Есть, вероятно, более эффективные способы сделать это, хотя. См: numpy.indices

+0

Мне нужно, чтобы это был вектор тройки, ваш результат все еще является массивом mxn. Думаю, я просто изменил результат? – user2909415

+0

Да, я думаю, вы хотите 'result = r.T.reshape (-1, 3)' –

+0

Вам нужен 2d-массив или 1-й массив с элементами tuple (dtype)? – hpaulj

Смежные вопросы