0
votes

Opérations vectorielles optimisées Numpy / Pandas

Supposons que j'aie un dataframe df:

  Vx    Vy    Vmagnitude
0 1.00  1.00  1.41421
1 2.00  3.00  3.60555
2 1.50  1.75  2.30489

Le but est de créer une nouvelle colonne df ['Vmagnitude'] définie comme la magnitude de la somme vectorielle entre Vx et Vy, comme dans cette image :

  Vx    Vy
0 1.00  1.00
1 2.00  3.00
2 1.50  1.75 

Quelle serait la manière la plus rapide et / ou la plus pythonique d'implémenter cela en utilisant numpy / pandas?


1 commentaires

np.sqrt (df.Vx.pow (2) + df.Vy.pow (2)) ou np.sqrt (df.pow (2) .sum (1)) < / code> s'il s'agit du cadre entier


4 Réponses :



0
votes

Vous pouvez définir une nouvelle magnitude de colonne comme étant la somme des racines carrées des vecteurs comme indiqué ci-dessous

    Vx    Vy  Magnitude
0  1.0  1.00   1.414214
1  2.0  3.00   3.605551
2  1.5  1.75   2.304886

Output:

import pandas as pd
import numpy as np 


d = {'Vx':[1,2,1.5], 'Vy':[1,3,1.75]}
df = pd.DataFrame(data=d)
df['Magnitude'] = np.sqrt(df['Vx'].pow(2) + df['Vy'].pow(2))
print(df)


0 commentaires

1
votes

Un moyen rapide (performances dans les jeux 3D par exemple) serait de ne pas utiliser le sqrt et de stocker uniquement le x² + y² = x * x + y * y dans une colonne VMagnitudeSquare ou comme vous le souhaitez . Dans la plupart des cas, pour d'autres calculs, vous pouvez simplement l'utiliser.

Tout cela revient au fait que la fonction sqrt est "lente". Mais cela dépend de votre utilisation.


0 commentaires

3
votes

Lorsque le problème s'aggrave, vous pouvez essayer d'utiliser pandas eval. Assurez-vous d'installer numexpr pour les gains ( pip install numexpr ), voir le lisez-moi numexpr ici pour voir comment cela fonctionne. S'il est installé, Pandas intègre simplement cette fonctionnalité dans la méthode .eval .

In [24]: %timeit np.linalg.norm( df[["vx", "vy"]], axis=1)
1 loop, best of 3: 266 ms per loop

In [25]: %timeit df.eval("sqrt(vx**2 + vy**2)", engine='python')
10 loops, best of 3: 144 ms per loop

In [26]: %timeit df.eval("sqrt(vx**2 + vy**2)", engine='numexpr')
10 loops, best of 3: 42 ms per loop

Je pense que c'est votre meilleur pari, numexpr utilise le multi-threading

import pandas

df = pandas.DataFrame( random.random((5000000,2)), columns=('vx', 'vy'))

df.eval("vmag = sqrt(vx**2 + vy**2)", engine='numexpr', inplace=True)

Voir également ce document pour améliorer les performances.


0 commentaires