Estou tentando dividir uma matriz do Excel em duas dimensões, conforme definido por outra matriz, de preferência sem usar VBA.
Para explicar melhor, o que eu gostaria é de uma fórmula do Excel paraf(A, B)
Onde A é booleano e =
[[1, 0],
[0, 1]
Onde B =
[[1, 2],
[3, 4]
E f(A, B)
os tiles B de acordo com os valores bool em A, neste caso,f(A, B) =
[[1, 2, 0, 0],
[3, 4, 0, 0],
[0, 0, 1, 2],
[0, 0, 3, 4]]
Meus pensamentos iniciais foram, =IF(MUNIT(2), {1, 2;3, 4}, {0, 0;0, 0})
mas a saída não se expande bem.
Este é meu esforço até agora - espero que seja bastante geral:
Você também pode usar Makearray:
(Mesma lógica da versão legada de @Scott Craner)
Abordagem semelhante à do Tom, mas um pouco mais curta:
E só por diversão, isso funcionará em versões mais antigas:
Arraste-o para cima e para baixo o suficiente para o tamanho da matriz.
Para retornar o produto de Kronecker de duas matrizes, tente o seguinte código Python:
Se você nunca usou Python no Excel antes, consulte: Comece a usar Python no Excel
Método alternativo 1:
Para melhor desempenho em matrizes maiores, você também pode tentar usar bissecção:
Onde
BiCOL
eBiROW
são funções lambda personalizadas definidas no Gerenciador de Nomes:Método alternativo 2:
Se você preferir usar uma
REDUCE-VSTACK/HSTACK
abordagem, o desempenho também pode ser melhorado empilhando os resultados em pares, em vez do empilhamento linear:Para uma versão generalizada deste método, consulte
MAPλ
a função de Peter Bartholomew: https://gist.github.com/pbartxlMétodo alternativo 3:
Outra opção relativamente eficiente é usar
TOCOL
withSORTBY
eWRAPROWS
; no entanto, esse método só pode gerar um máximo de 1.048.576 elementos totais, devido às limitações deTOCOL
:Esta seria minha abordagem no Office 365:
=LET(f,LAMBDA(a,b,DROP(REDUCE("",SEQUENCE(COLUMNS(a)),LAMBDA(c,d,HSTACK(c,REDUCE("",SEQUENCE(ROWS(a)),LAMBDA(e,f,VSTACK(e,b*INDEX(a,f,d))))))),1,1)),f(B1:D3,F1#))
Editar: Olhando para a resposta de Tom Sharpe, a minha é meio parecida. Usei o DROP no todo, em vez das funções REDUCE individuais e o envolvi em LAMBDA para chamar
f
como no post de abertura. Mas, fora isso, não é muito diferente, então se você votar, pelo menos vote também no Tom'sNenhuma lógica nova, reduzindo sem
DROP
e usandoINDEX
, esperando por melhor desempenho:Demorou cerca de 6 segundos com esses intervalos no meu Mac.