Eu preciso criar uma matriz NumPy de comprimento n
, cada elemento do qual év
.
Existe algo melhor do que:
a = empty(n)
for i in range(n):
a[i] = v
Eu sei zeros
e ones
funcionaria para v = 0, 1. Eu poderia usar v * ones(n)
, mas não funcionará quando seria muito mais lento.v
for None
e também
a = np.zeros(n)
no loop é mais rápido quea.fill(0)
. Isso é contrário ao que eu esperava, pois penseia=np.zeros(n)
que precisaria alocar e inicializar nova memória. Se alguém puder explicar isso, eu agradeceria.v * ones(n)
ainda é horrível, pois usa a multiplicação cara. Substitua*
por+
, porém, ev + zeros(n)
se mostra surpreendentemente bom em alguns casos ( stackoverflow.com/questions/5891410/… ).var = np.empty(n)
e preenchê-la com 'var [:] = v'. (aliás,np.full()
é tão rápido como este)Respostas:
Introduzido o NumPy 1.8
np.full()
, que é um método mais direto do que oempty()
seguidofill()
para criar uma matriz preenchida com um determinado valor:Essa é, sem dúvida, a maneira de criar uma matriz preenchida com certos valores, porque descreve explicitamente o que está sendo alcançado (e, em princípio, pode ser muito eficiente, pois executa uma tarefa muito específica).
fonte
help(numpy.full)
em um shell Python. Também estou surpreso que não esteja na documentação da web.np.fill()
não existe e deveria existirarr.fill()
), com uma diferença de cerca de 10%. Se a diferença fosse maior, eu levantaria um problema no rastreador de erros do NumPy. :) Prefiro um código mais explícito e claro, por uma diferença tão pequena no tempo de execução, por isso continuonp.full()
o tempo todo.Atualizado para o Numpy 1.7.0: (dica de chapéu para @Rolf Bartstra.)
a=np.empty(n); a.fill(5)
é o mais rápidoEm ordem decrescente de velocidade:
fonte
np.full()
seria útil. Na minha máquina, com o NumPy 1.8.1, é cerca de 15% mais lento que afill()
versão menos direta (o que é inesperado, poisfull()
tem o potencial de ser um pouco mais rápido).fill()
é a solução mais rápida. A solução de multiplicação é muito mais lenta.10000
vez de1e4
faz uma diferença notável, por algum motivo (full()
é quase 50% mais lento com1e4
).full()
, ele é executado consideravelmente mais lento quando o tipo de dados não é explicitamente um float. Caso contrário, é comparável (mas um pouco mais lento) com os melhores métodos aqui.full(100000, 5)
,full(100000, 5, dtype=float)
,full(100000, 5, dtype=int)
ea =np.empty(100000); a.fill(5)
todos têm aproximadamente o mesmo tempo na minha máquina (sem cache:%timeit -r1 -n1 …
) (NumPy 1.11.2).Eu acredito que
fill
é a maneira mais rápida de fazer isso.Você também deve sempre evitar iterar como está fazendo no seu exemplo. Um simples
a[:] = v
realizará o que sua iteração faz usando difusão numpy .fonte
fill
, vi querepeat
atende às minhas necessidades ainda melhor.a[:]=v
é realmente mais rápida do que afill
?fill
.Aparentemente, não apenas as velocidades absolutas, mas também a ordem de velocidade (conforme relatado pelo usuário 1579844) dependem da máquina; aqui está o que eu encontrei:
a=np.empty(1e4); a.fill(5)
é mais rápido;Em ordem decrescente de velocidade:
Portanto, tente descobrir e use o que é mais rápido em sua plataforma.
fonte
eu tinha
em mente, mas aparentemente isso é mais lento que todas as outras sugestões de tamanho suficiente
n
.Aqui está uma comparação completa com o perfplot (um projeto meu para animais de estimação).
As duas
empty
alternativas ainda são as mais rápidas (com o NumPy 1.12.1).full
alcança grandes matrizes.Código para gerar o gráfico:
fonte
Você pode usar
numpy.tile
, por exemplo:Embora
tile
se pretenda 'agrupar' uma matriz (em vez de uma escalar, como neste caso), ela fará o trabalho, criando matrizes pré-preenchidas de qualquer tamanho e dimensão.fonte
sem entorpecente
fonte
[v] * n
seria mais diretamente relevante para a questão do OP.