Joh*_*hnE 2 python numpy pandas numba
编辑补充:我不认为 numba 基准是公平的,下面的注释
我正在尝试对以下用例的数值处理数据的不同方法进行基准测试:
换句话说,不需要系列和数据框的完全通用性,尽管它们被包含在 b/c 中,但它们仍然是封装数据的便捷方式,并且经常有预处理或后处理确实需要熊猫的通用性numpy 数组。
问题:基于此用例,以下基准是否合适,如果不合适,我该如何改进它们?
# importing pandas, numpy, Series, DataFrame in standard way
from numba import jit
nobs = 10000
nlines = 100
def proc_df():
df = DataFrame({ 'x': np.random.randn(nobs),
'y': np.random.randn(nobs) })
for i in range(nlines):
df['z'] = df.x + df.y
return df.z
def proc_ser():
x = Series(np.random.randn(nobs))
y = Series(np.random.randn(nobs))
for i in range(nlines):
z = x + y
return z
def proc_arr():
x = np.random.randn(nobs)
y = np.random.randn(nobs)
for i in range(nlines):
z = x + y
return z
@jit
def proc_numba():
xx = np.random.randn(nobs)
yy = np.random.randn(nobs)
zz = np.zeros(nobs)
for j in range(nobs):
x, y = xx[j], yy[j]
for i in range(nlines):
z = x + y
zz[j] = z
return zz
Run Code Online (Sandbox Code Playgroud)
结果(Win 7,3 年前的 Xeon 工作站(四核)。标准和最近的 anaconda 发行版或非常接近。)
In [1251]: %timeit proc_df()
10 loops, best of 3: 46.6 ms per loop
In [1252]: %timeit proc_ser()
100 loops, best of 3: 15.8 ms per loop
In [1253]: %timeit proc_arr()
100 loops, best of 3: 2.02 ms per loop
In [1254]: %timeit proc_numba()
1000 loops, best of 3: 1.04 ms per loop # may not be valid result (see note below)
Run Code Online (Sandbox Code Playgroud)
编辑以添加(对 jeff 的响应)将 df/series/array 传递给函数而不是在函数内部创建它们的替代结果(即将包含“randn”的代码行从函数内部移动到外部函数):
10 loops, best of 3: 45.1 ms per loop
100 loops, best of 3: 15.1 ms per loop
1000 loops, best of 3: 1.07 ms per loop
100000 loops, best of 3: 17.9 µs per loop # may not be valid result (see note below)
Run Code Online (Sandbox Code Playgroud)
关于 numba 结果的注意事项:我认为 numba 编译器必须在 for 循环上进行优化并将 for 循环减少到单个迭代。我不知道,但这是我能想到的唯一解释,因为它不可能比 numpy 快 50 倍,对吧?这里的后续问题:为什么这里 numba 比 numpy 快?
好吧,您实际上并没有为相同的事情计时(或者更确切地说,您正在为不同的方面计时)。
例如
In [6]: x = Series(np.random.randn(nobs))
In [7]: y = Series(np.random.randn(nobs))
In [8]: %timeit x + y
10000 loops, best of 3: 131 µs per loop
In [9]: %timeit Series(np.random.randn(nobs)) + Series(np.random.randn(nobs))
1000 loops, best of 3: 1.33 ms per loop
Run Code Online (Sandbox Code Playgroud)
所以 [8] 次实际操作,而 [9] 包括系列创建(和随机数生成)的开销加上实际操作
另一个例子是proc_servs proc_df。这proc_df包括分配 DataFrame 中特定列的开销(对于初始创建和随后的重新分配实际上是不同的)。
所以创建结构(你也可以计时,但这是一个单独的问题)。执行完全相同的操作并计时。
此外你说你不需要对齐。Pandas 默认为您提供此功能(并没有真正简单的方法将其关闭,尽管它只是一个简单的检查它们是否已经对齐)。在 numba 中,您需要“手动”对齐它们。
| 归档时间: |
|
| 查看次数: |
2869 次 |
| 最近记录: |