Python 数字处理2d阵列的最快方法:数据帧vs系列vs阵列vs numba
编辑添加:我不认为numba基准是公平的,注意如下 我正试图为以下用例测试不同的数值处理数据的方法:Python 数字处理2d阵列的最快方法:数据帧vs系列vs阵列vs numba,python,numpy,pandas,numba,Python,Numpy,Pandas,Numba,编辑添加:我不认为numba基准是公平的,注意如下 我正试图为以下用例测试不同的数值处理数据的方法: 相当大的数据集(100000多条记录) 100多行相当简单的代码(z=x+y) 不需要排序或索引 换句话说,系列和数据帧的完整通用性是不需要的,尽管它们包含在这里b/c它们仍然是封装数据的方便方法,并且通常存在预处理或后处理,这确实需要pandas over numpy阵列的通用性 问题:基于此用例,以下基准是否合适?如果不合适,我如何改进它们 # importing pandas, 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
结果(Win 7,3年前的Xeon工作站(四核)。标准和最近的anaconda分布或非常接近。)
编辑以添加(对jeff的响应)将df/series/array传递到函数中而不是在函数内部创建它们的替代结果(即将包含“randn”的代码行从函数内部移动到函数外部):
关于numba结果的注意事项:我认为numba编译器必须在for循环上进行优化,并将for循环减少到单个迭代。我不知道,但这是我能想到的唯一解释,因为它不可能比numpy快50倍,对吗?接下来的问题是:好吧,你在这里并不是在为同样的事情计时(或者更确切地说,你是在为不同的方面计时) 例如 因此[8]乘以实际操作,而[9]包括序列创建(和随机数生成)的开销加上实际操作 另一个例子是
proc\u ser
vsproc\u df
。proc_df
包括数据帧中特定列的分配开销(对于初始创建和后续重新分配,这实际上是不同的)
因此,创建结构(您也可以计算时间,但这是一个单独的问题)。执行完全相同的操作并计时
进一步说,你不需要对齐。Pandas默认为您提供此功能(并且没有真正简单的方法关闭它,尽管它只是简单地检查它们是否已对齐)。在numba中,您需要“手动”对齐它们。继续@Jeff answer。代码可以进一步优化
nobs = 10000
x = pd.Series(np.random.randn(nobs))
y = pd.Series(np.random.randn(nobs))
%timeit proc_ser()
%timeit x + y
%timeit x.values + y.values
100 loops, best of 3: 11.8 ms per loop
10000 loops, best of 3: 107 µs per loop
100000 loops, best of 3: 12.3 µs per loop
好的,我不认为它改变了什么(数据创建是有意的,只是这里测量的一小部分),但上面添加了替代结果。Re numba manual alignment(手动对齐):虽然我不认为它与numpy在本例中有任何不同(因为我只是在numba中迭代numpy数组),但这个用例非常简单,我不认为这是一个问题。Jeff,如果你错过了,这是以下内容的后续内容:
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)
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
nobs = 10000
x = pd.Series(np.random.randn(nobs))
y = pd.Series(np.random.randn(nobs))
%timeit proc_ser()
%timeit x + y
%timeit x.values + y.values
100 loops, best of 3: 11.8 ms per loop
10000 loops, best of 3: 107 µs per loop
100000 loops, best of 3: 12.3 µs per loop