#python #numpy
#python #numpy
Вопрос:
У меня есть список, из которого я хочу собрать ядро [90,50,10]
Что я хочу сделать, так это получить ядро, которое выглядит как —
[[90,0,0]
[50,0,0]
[10,0,0]
[0,90,0]
[0,50,0]
[0,10,0]
[0,0,90]
[0,0,50]
[0,0,10]]
Я могу реализовать это с помощью цикла, И я попытался сделать что-то в строках этого —
k = np.array([90,50,10])
for i in k:
d = np.zeros((3,3))
np.fill_diagonal(d, i)
print(d)
[[90. 0. 0.]
[ 0. 90. 0.]
[ 0. 0. 90.]]
[[50. 0. 0.]
[ 0. 50. 0.]
[ 0. 0. 50.]]
[[10. 0. 0.]
[ 0. 10. 0.]
[ 0. 0. 10.]]
Проблема в том, что для изменения порядка строк мне понадобится еще одна итерация, а np.fill_diagonal — это метод на месте, поэтому я не могу использовать понимание списка.
Я ищу способ, которым я мог бы решить это векторизованным способом без каких-либо циклов, используя только numpy и в одной строке кода.
Редактировать:
Предпочтительное решение должно позволять создавать ядро размером 25X5, если я использую массив размером 5X1, например [90,50,40,30,10]
Ответ №1:
вы могли бы сделать:
s = np.array([90,50,10])
size = s.size
o = np.zeros((size ** 2, s.size))
o[np.arange(size**2), np.repeat(np.arange(size), size)] = np.tile(s, size)
print(o)
[[90. 0. 0.]
[50. 0. 0.]
[10. 0. 0.]
[ 0. 90. 0.]
[ 0. 50. 0.]
[ 0. 10. 0.]
[ 0. 0. 90.]
[ 0. 0. 50.]
[ 0. 0. 10.]]
Ответ №2:
Вот один из возможных однострочных вариантов, например k = np.array([90, 50, 10])
:
np.concatenate([np.pad(k[:, None], ((0, 0), (i, 2-i))) for i in range(k.size)])
Ответ №3:
IIUC,
#k = np.array([90, 50, 10])
kernel = np.tile(np.identity(k.shape[0])*k, k.shape[0]).reshape(k.shape[0]**2, k.shape[0])
print(kernel)
[[90. 0. 0.]
[90. 0. 0.]
[90. 0. 0.]
[ 0. 50. 0.]
[ 0. 50. 0.]
[ 0. 50. 0.]
[ 0. 0. 10.]
[ 0. 0. 10.]
[ 0. 0. 10.]]
Комментарии:
1. Хотелось бы, чтобы мы могли выбрать 2 ответа как верхние.
2. Разве вывод здесь не отличается от вопроса?