Нарезка и укладка элементов кортежа в матрицу в Python - PullRequest
0 голосов
/ 26 декабря 2018

У меня есть список кортежей (собственное значение, собственный вектор), из которого я должен извлечь первые 60 собственных векторов и сложить их горизонтально в матрицу.Я использую этот код:

matrix_60 = np.hstack((eig_pairs[:60][1]).reshape(samples,1))

Код не работает должным образом (я понимаю, что кортеж не имеет атрибута reshape), но я не могу определить правильный синтаксис.Ожидаемый результат - получить первые 60 собственных векторов и расположить их по столбцам (таким образом, матрица будет иметь N строк по 60 столбцов).

Ответы [ 4 ]

0 голосов
/ 27 декабря 2018

Вы можете использовать np.stack с axis=1 для составления столбцов векторов:

np.stack([vec for val, vec in eig_pairs[:60]], axis=1)

Понимание списка извлечет собственные векторы из первых 60 кортежей.stack создает новую ось для конкатенации в указанном измерении.

Выражение eig_pairs[:60] по-прежнему является списком, поэтому eig_pairs[:60][1] - это только второй кортеж в этом списке, а не второй элементиз каждого кортежа.Вот почему вам нужно понимание, чтобы извлечь векторы.

0 голосов
/ 26 декабря 2018

Если у вас есть массив кортежей python, называемый tuples собственных значений и векторов, вы можете получить массив только из собственных векторов, таких как:

eigenvectors = [tuple[1] for tuple in tuples]

Теперь вы, вероятно, можете просто сделать np.array(eigenvectors).

0 голосов
/ 27 декабря 2018

Как заметил @Tyler Chen, вы не можете нарезать список кортежей Python с помощью Numpy-подобного среза (или, по крайней мере, я не знаю способа).Есть несколько способов решения проблемы:

  1. переберите список с индексом
  2. , используйте map и itemgetter
  3. создайте словарьэлементы: dict()
  4. использование zip в элементах списка

Подробно о каждом в этом ответе SO:
Как извлечь n-й элементиз списка кортежей в python?

Ни один из примеров не показывает, как это работает с массивом как элементом List / Tuple.Итак, я создал простой пример с использованием метода цикла (проще всего понять новому пользователю).Код над комментарием +-+-+-+ создает данные, аналогичные вашим (если я понимаю формулировку проблемы).Код под комментарием показывает, как я это сделаю.Я зациклился на индексе, потому что я использую его в качестве номера строки при добавлении в массив.Вы также можете зациклить элементы списка и добавить для этой цели счетчик строк (см. Альтернативный метод).
В этом примере 10 собственных строк и 20 значений в каждом собственном векторе.Я позволю вам обобщить для N строк и векторов M.
Примечание: размер массива Numpy выделяется заранее.Итак, в общем случае вам нужно будет сканировать ваши кортежи, чтобы определить количество строк и столбцов для размещения массива перед циклом.

import numpy as np
# First, build some simple Eigenvalue and Eigenvector data
# 10 Eigenvalues in eig_vals and Eigenvectors as 20 values in 10 rows (shape [10,20])
eig_vals = np.logspace(0.1,3., num=10)
eig_vec = np.zeros([10,20])
for i in range(len(eig_vals)) :
  eig_vec_r = np.random.random_sample(20)
  eig_vec[i,:]=eig_vec_r
# Create List of tuples for each eig_vals, eig_vec pair: 
eigen_pairs = [(eig_vals[i], eig_vec[i,:]) for i in range(len(eig_vals)) ]
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

# create new nd.array to hold extrated Eigenvector data (shape [10,20])
saved_eig_vec = np.zeros([10,20])

# loop thru List of tuples to extract Eigenvector array and write to saved_eig_vec
# Each Eigenvector will be in 1 row
for i in range(len(eigen_pairs)) :
  saved_eig_vec[i,:] = eigen_pairs[i][1]

#Verify correctness by comparing the following values:
#  1) eig_vec[9,:] initial array created with random_sample function
#  2) eigen_pairs[9][1] -  array saved in list of tuples
#  3) saved eig_vec[9,:] array extrated and saved from list of tuples

print (eig_vec[9,:])
print (eigen_pairs[9][1])
print (saved_eig_vec[9,:])

# Alternate method, looping on list elements with row counter (reset saved_eig_vec array)
saved_eig_vec = np.zeros([10,20])
row = 0
for i in eigen_pairs :
  saved_eig_vec[row,:] = i[1]
  row += 1

print (saved_eig_vec[9,:])
0 голосов
/ 26 декабря 2018

Может как то так?

np.concatenate(list(map(lambda x: x[1], eig_pairs[:60]))).reshape(-1, 60)
...