我已经写了很多代码,以为我将使用Numpy数组。结果发现我获取的数据是通过Pandas加载的。我现在记得我加载它在Pandas中,因为我在Numpy中加载时遇到了一些问题。我相信数据量太大了。
因此,我想知道,使用Numpy和Pandas有计算性能上的区别吗?
如果Pandas更高效,那我宁愿重写所有代码用Pandas,但如果没有更高效的话,我就只使用一个Numpy数组...
我已经写了很多代码,以为我将使用Numpy数组。结果发现我获取的数据是通过Pandas加载的。我现在记得我加载它在Pandas中,因为我在Numpy中加载时遇到了一些问题。我相信数据量太大了。
因此,我想知道,使用Numpy和Pandas有计算性能上的区别吗?
如果Pandas更高效,那我宁愿重写所有代码用Pandas,但如果没有更高效的话,我就只使用一个Numpy数组...
在多项式运算中,性能差异可能会达到一个数量级,在随机值索引方面则可能达到数个数量级。
实际上我也曾对此产生过疑惑,并发现了这个有趣的比较: http://penandpants.com/2014/09/05/performance-of-pandas-series-vs-numpy-arrays/
我认为更多地是基于性能使用这两者并在它们之间转移数据(从numpy到pandas或反之亦然)。最近的一个例子是,我尝试使用numpy连接4个每个有10k行的小pickle文件 data.shape -> (10,000, 4)
。
代码大致如下:
n_concat = np.empty((0,4))
for file_path in glob.glob('data/0*', recursive=False):
n_data = joblib.load(file_path)
n_concat = np.vstack((co_np, filtered_snp))
joblib.dump(co_np, 'data/save_file.pkl', compress = True)
这导致我的笔记本电脑崩溃了(8 GB,i5),令人惊讶的是,因为卷并不是真正的非常巨大。这4个压缩的pickle文件大约每个都是5 MB。
对于pandas来说,同样的事情效果很好。
for file_path in glob.glob('data/0*', recursive=False):
n_data = joblib.load(sd)
try:
df = pd.concat([df, pd.DataFrame(n_data, columns = [...])])
except NameError:
df = pd.concat([pd.DataFrame(n_data,columns = [...])])
joblib.dump(df, 'data/save_file.pkl', compress = True)
另一方面,当我使用 pandas 数据框架进行梯度下降实现时,速度非常慢,而使用 numpy 则要快得多。
总的来说,我发现 pandas 通常更适合处理中等大小的数据块和常见列操作,而 numpy 最适合在较小的数据集上进行向量化和递归工作(也许是更数学密集型的工作)。
在两者之间移动数据非常方便,因此我想,策略性地使用两者是正确的选择。
在下面的示例中,data
是一个有8M行3列(int32, float32, float32),没有NaN值,第0列(时间)已排序的Pandas frame。 data_np
是通过data.values.astype('float32')
创建的。Python 3.8,Ubuntu上的结果:
A. 列切片和平均值:
# Pandas
%%timeit
x = data.x
for k in range(100): x[100000:100001+k*100].mean()
15.8 ms ± 101 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
# Numpy
%%timeit
for k in range(100): data_np[100000:100001+k*100,1].mean()
874 µs ± 4.34 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Pandas比Numpy慢18倍(15.8毫秒对0.874毫秒)。
B. 在排序列中搜索:
# Pandas
%timeit data.time.searchsorted(1492474643)
20.4 µs ± 920 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
# Numpy
%timeit data_np[0].searchsorted(1492474643)
1.03 µs ± 3.55 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Pandas比Numpy慢20倍(20.4µs vs 1.03µs)。
编辑:我实现了一个名为namedarray的类,它填补了Pandas和Numpy之间的差距,因为它基于Numpy的ndarray类,因此比Pandas性能更好(通常快大约7倍),并且完全兼容Numpy的API和所有运算符;但同时它保持了类似于Pandas的DataFrame的列名,使得对单个列进行操作更加容易。这是一个原型实现。与Pandas不同,namedarray不允许不同数据类型的列。代码可以在这里找到:https://github.com/mwojnars/nifty/blob/master/math.py(搜索“namedarray”)。