Усечение 2D-массива для заданного допуска [Python] - PullRequest
0 голосов
/ 11 апреля 2020

Старый вопрос о разложении по сингулярным значениям побудил меня задать этот вопрос: как я могу усечь двумерный массив до количества столбцов, определяемых определенным допуском?

В частности, рассмотрите следующее фрагмент кода, который определяет принятый допуск 1e-4 и применяет декомпозицию сингулярного значения к матрице 'A'.

#Python
tol=1e-4
U,Sa,V=np.linalg.svd(A)
S=np.diag(Sa)

Полученная диагональная матрица сингулярного значения S содержит неотрицательные сингулярные значения в убывающем порядок величины.

То, что я хочу получить, - это усеченная матрица 'S', таким образом, что столбцы матрицы, содержащие особые значения ниже 1e-4, будут удалены. Затем примените это усечение к матрице «U».

Есть ли простой способ сделать это? Я искал вокруг и нашел некоторые решения проблемы для Matlab, но не нашел ничего подобного для Python. Для Matlab код будет выглядеть примерно так:

%Matlab
tol=1e-4
mask=any(Sigma>=tol,2);
sigRB=Sigma(:,mask);
mask2=any(U>=tol,2);
B=U(:,mask);

Заранее спасибо. Надеюсь, мой пост был не слишком запутанным, чтобы понять.

1 Ответ

1 голос
/ 11 апреля 2020

Я не уверен, правильно ли я вас понимаю. Если мое решение не соответствует вашим запросам, рассмотрите возможность добавления примера к вашему вопросу.

Следующий код удаляет все столбцы из массива s, которые состоят только из значений, меньших tol.

s = np.array([
    [1, 0, 0, 0, 0, 0],
    [0, .9, 0, 0, 0, 0],
    [0, 0, .5, 0, 0, 0],
    [0, 0, 0, .4, 0, 0],
    [0, 0, 0, 0, .3, 0],
    [0, 0, 0, 0, 0, .2]
])

print(s)

tol = .4
ind = np.argwhere(s.max(axis=1) < tol)

s = np.delete(s, ind, 1)

print(s)

Вывод:

[[1.  0.  0.  0.  0.  0. ]
 [0.  0.9 0.  0.  0.  0. ]
 [0.  0.  0.5 0.  0.  0. ]
 [0.  0.  0.  0.4 0.  0. ]
 [0.  0.  0.  0.  0.3 0. ]
 [0.  0.  0.  0.  0.  0.2]]


[[1.  0.  0.  0. ]
 [0.  0.9 0.  0. ]
 [0.  0.  0.5 0. ]
 [0.  0.  0.  0.4]
 [0.  0.  0.  0. ]
 [0.  0.  0.  0. ]]

Я применяю max к оси 1, а затем использую np.argwhere, чтобы получить индексы столбцов, где максимальное значение равно меньше чем tol.

Редактировать: чтобы обрезать столбцы матрицы 'U', чтобы она по размеру совпадала с уменьшенной матрицей 'S', работает следующий код:

k = len(S[0])
Ured = U[:,0:k]
Uredsize = np.shape(Ured) # To check it has worked
print(Uredsize)
...