<p>A implementação de numpy.vectorize é essencialmente um loop for?</p>

Criado em 6 jul. 2020  ·  5Comentários  ·  Fonte: numpy/numpy

https://numpy.org/doc/1.18/reference/generated/numpy.vectorize.html
Este tutorial menciona que a implementação de vetorizar é essencialmente um loop for. Mas, até onde eu sei, uma função vetorizada usará
SIMD, então é correto dizer que a implementação de numpy.vectorize é essencialmente um loop for? Se verdadeiro, então é mais rápido do que funções não vetorizadas apenas porque é um loop implementado em linguagem C?

Muito obrigado antecipadamente.

33 - Question

Comentários muito úteis

Sim. No contexto de linguagens de programação de matriz numérica interpretada como Python (com numpy) e MATLAB ™, costumamos usar "vetorização" para nos referirmos à substituição de loops explícitos na linguagem de programação interpretada por uma função (ou operador) que cuida de todos os loop lógico internamente. Em numpy, os ufunc s implementam essa lógica. Isso não está relacionado ao uso de "vetorização" para se referir ao uso de instruções de CPU SIMD que computam sobre várias entradas simultaneamente, exceto que ambos usam uma metáfora semelhante: eles são como suas contrapartes "escalares", mas realizam o cálculo sobre vários valores de entrada com uma única invocação.

Com numpy.vectorize() , geralmente não há muitos benefícios de velocidade sobre o loop Python for explícito. O objetivo principal disso é transformar a função Python em ufunc , que implementa toda a semântica de transmissão e, portanto, lida com entradas de qualquer tamanho. A função Python que está sendo "vetorizada" ainda ocupa a maior parte do tempo, além de converter o valor bruto de cada elemento em um objeto Python para passar para a função. Você não esperaria que np.vectorize(lambda x, y: x + y) fosse tão rápido quanto o ufunc np.add , que é C tanto no loop quanto no conteúdo do loop.

Todos 5 comentários

Sim. No contexto de linguagens de programação de matriz numérica interpretada como Python (com numpy) e MATLAB ™, costumamos usar "vetorização" para nos referirmos à substituição de loops explícitos na linguagem de programação interpretada por uma função (ou operador) que cuida de todos os loop lógico internamente. Em numpy, os ufunc s implementam essa lógica. Isso não está relacionado ao uso de "vetorização" para se referir ao uso de instruções de CPU SIMD que computam sobre várias entradas simultaneamente, exceto que ambos usam uma metáfora semelhante: eles são como suas contrapartes "escalares", mas realizam o cálculo sobre vários valores de entrada com uma única invocação.

Com numpy.vectorize() , geralmente não há muitos benefícios de velocidade sobre o loop Python for explícito. O objetivo principal disso é transformar a função Python em ufunc , que implementa toda a semântica de transmissão e, portanto, lida com entradas de qualquer tamanho. A função Python que está sendo "vetorizada" ainda ocupa a maior parte do tempo, além de converter o valor bruto de cada elemento em um objeto Python para passar para a função. Você não esperaria que np.vectorize(lambda x, y: x + y) fosse tão rápido quanto o ufunc np.add , que é C tanto no loop quanto no conteúdo do loop.

Obrigado por sua explicação detalhada. Mas para ser claro, deixe-me dar um exemplo.

import pandas as pd
import numpy as np
df = pd.DataFrame({'a': range(100000), 'b': range(1, 1000001)})
# method1
df.loc[:, 'c'] = df.apply(lambda x: x['a'] + x['b'], axis=1)
# method2 
df.loc[:, 'c'] = np.vectorize(lambda x, y: x + y)(df['a'], df['b'])
# method3
df.loc[:, 'c'] = np.add(df['a'], df['b'])

então com sua explicação, eu acho

método | loop em C | conteúdo do loop em C | usar SIMD
- | - | - | -
1 | × | × | ×
2 | √ | × | ×
3 | √ | √ | √

Direito?

np.add é mais rápido do que np.vectorize(lambda x, y: x + y) porque evita a conversão de C doubles em objetos Python e a sobrecarga de chamada de função Python. É possível que também use instruções SIMD, dependendo se você tem ou não

np.add é mais rápido do que np.vectorize(lambda x, y: x + y) porque evita a conversão de C doubles em objetos Python e a sobrecarga de chamada de função Python. É possível que _também_ use instruções SIMD, dependendo se você tem ou não

Deixa comigo. Obrigado.

Você pode usar vectorize de numba para produzir ufuncs que operam em paralelo sem sobrecargas do Python:

https://numba.pydata.org/numba-doc/latest/user/vectorize.html

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

inducer picture inducer  ·  3Comentários

MorBilly picture MorBilly  ·  4Comentários

marcocaccin picture marcocaccin  ·  4Comentários

keithbriggs picture keithbriggs  ·  3Comentários

toddrjen picture toddrjen  ·  4Comentários