Numpy / Pandas 优化向量操作
Numpy / Pandas optimized vector operations
假设我有一个数据框 df:
Vx Vy
0 1.00 1.00
1 2.00 3.00
2 1.50 1.75
目标是创建一个新列 df['Vmagnitude']
,定义为 Vx 和 Vy 之间矢量和的大小,如 in this picture:
Vx Vy Vmagnitude
0 1.00 1.00 1.41421
1 2.00 3.00 3.60555
2 1.50 1.75 2.30489
什么是最快的 and/or 使用 numpy/pandas 最 pythonic 的实现方式?
你可以使用 np.linalg.norm:
df["Vmagnitude"] = np.linalg.norm(df[["Vx", "Vy"]], axis=1)
您可以将新的列幅度定义为向量的平方根之和,如下所示
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)
输出:
Vx Vy Magnitude
0 1.0 1.00 1.414214
1 2.0 3.00 3.605551
2 1.5 1.75 2.304886
一种快速的方法(例如 3D 游戏中的性能)是不使用 sqrt 并仅将 x²+y² = x*x + y*y
存储在列 VMagnitudeSquare 中或您喜欢的任何方式。
在大多数情况下,您可以使用它进行进一步计算。
这一切都归结为 sqrt 函数 "slow"。
但这取决于您的使用情况。
当问题变大时,您可以尝试使用 pandas eval。确保安装 numexpr 以获得收益 (pip install numexpr
) ,请参阅 the numexpr readme here 了解其工作原理。如果已安装,Pandas 只是将此功能包装到 .eval
方法中。
import pandas
df = pandas.DataFrame( random.random((5000000,2)), columns=('vx', 'vy'))
df.eval("vmag = sqrt(vx**2 + vy**2)", engine='numexpr', inplace=True)
我认为这是你最好的选择,numexpr 使用多线程
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
另请参阅 this doc 以提高性能。
假设我有一个数据框 df:
Vx Vy
0 1.00 1.00
1 2.00 3.00
2 1.50 1.75
目标是创建一个新列 df['Vmagnitude']
,定义为 Vx 和 Vy 之间矢量和的大小,如 in this picture:
Vx Vy Vmagnitude
0 1.00 1.00 1.41421
1 2.00 3.00 3.60555
2 1.50 1.75 2.30489
什么是最快的 and/or 使用 numpy/pandas 最 pythonic 的实现方式?
你可以使用 np.linalg.norm:
df["Vmagnitude"] = np.linalg.norm(df[["Vx", "Vy"]], axis=1)
您可以将新的列幅度定义为向量的平方根之和,如下所示
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)
输出:
Vx Vy Magnitude
0 1.0 1.00 1.414214
1 2.0 3.00 3.605551
2 1.5 1.75 2.304886
一种快速的方法(例如 3D 游戏中的性能)是不使用 sqrt 并仅将 x²+y² = x*x + y*y
存储在列 VMagnitudeSquare 中或您喜欢的任何方式。
在大多数情况下,您可以使用它进行进一步计算。
这一切都归结为 sqrt 函数 "slow"。 但这取决于您的使用情况。
当问题变大时,您可以尝试使用 pandas eval。确保安装 numexpr 以获得收益 (pip install numexpr
) ,请参阅 the numexpr readme here 了解其工作原理。如果已安装,Pandas 只是将此功能包装到 .eval
方法中。
import pandas
df = pandas.DataFrame( random.random((5000000,2)), columns=('vx', 'vy'))
df.eval("vmag = sqrt(vx**2 + vy**2)", engine='numexpr', inplace=True)
我认为这是你最好的选择,numexpr 使用多线程
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
另请参阅 this doc 以提高性能。