Numpy 和 Pandas 之间有性能差异吗?

问题描述 投票:0回答:4

我编写了一堆代码,假设我将使用 Numpy 数组。结果我得到的数据是通过 Pandas 加载的。我现在记得我将它加载到 Pandas 中,因为我在 Numpy 中加载它时遇到了一些问题。我认为数据太大了。

因此我想知道,使用 Numpy 和 Pandas 时计算能力有区别吗?

如果 Pandas 更高效,那么我宁愿为 Pandas 重写所有代码,但如果没有更高的效率,那么我只会使用 numpy 数组...

python numpy pandas
4个回答
37
投票

可能存在显着的性能差异,乘法有一个数量级,索引一些随机值有多个数量级。

我实际上也想知道同样的事情,并发现了这个有趣的比较: http://penandpants.com/2014/09/05/performance-of-pandas-series-vs-numpy-arrays/


13
投票

我认为更多的是根据您看到的性能战略性地使用这两者并转移数据(从 numpy 到 pandas 或反之亦然)。作为最近的示例,我尝试使用 numpy 连接 4 个小 pickle 文件,每个文件有 10k 行

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 个压缩的 pickled 文件每个大约 5 MB 左右。 同样的事情,在熊猫上效果很好。

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 最适合在较小的数据集上进行矢量化和递归工作(可能是更数学密集的工作)。

在两者之间移动数据是没有麻烦的,所以我想,策略性地使用两者是正确的方法。


13
投票
慢 20 倍

。这是一个巨大的差异,因为只执行了简单的算术运算:列切片、mean()、searchsorted() - 见下文。最初,我认为 Pandas 是基于 numpy 的,或者至少它的实现是 C 优化的,就像 numpy 的一样。然而,考虑到巨大的性能差距,这些假设被证明是错误的。 在下面的示例中,

data

是一个具有 8M 行和 3 列(int32、float32、float32)的 pandas 框架,没有 NaN 值,第 0 列(时间)已排序。

data_np
被创建为
data.values.astype('float32')
。 Python 3.8、Ubuntu 上的结果:

A。列切片和mean():

# 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 毫秒 vs 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)。

编辑:

我实现了一个命名数组类,它弥补了 Pandas 和 Numpy 之间的差距,因为它基于 Numpy 的 ndarray 类,因此性能比 Pandas 更好(通常快 7 倍),并且与 Numpy'a API 和所有内容完全兼容其运营商;但同时它保持列名称类似于 Pandas 的 DataFrame,因此对各个列的操作更容易。这是一个原型实现。与 Pandas 不同,namedarray not 允许列使用不同的数据类型。代码可以在这里找到:https://github.com/mwojnars/nifty/blob/master/math.py(搜索“namedarray”)。


0
投票

# The pandas function def make_data(dataframe: pd.DataFrame, ws: int) -> Tuple[List, List]: features = [dataframe.iloc[i:i+ws, :-1].values for i in range(len(dataframe) - ws)] targets = [dataframe.iloc[i+ws, -1] for i in range(len(dataframe) - ws)] return features, targets start_time = time.time() features, targets = make_data(arranged_dataframe, ws=ws) end_time = time.time() print(f"Time taken: {end_time - start_time} seconds") # the numpy function def make_data(dataframe: pd.DataFrame, ws: int) -> Tuple[np.ndarray, np.ndarray]: data = dataframe.to_numpy() num_samples = len(data) - ws features = np.empty((num_samples, ws, data.shape[1]), dtype=data.dtype) targets = np.empty(num_samples, dtype=data.dtype) for i in range(num_samples): features[i] = data[i:i+ws, ] targets[i] = data[i+ws, -1] return features, targets start_time = time.time() features, targets = make_data(arranged_dataframe, ws=16) end_time = time.time() print(f"Time taken: {end_time - start_time} seconds")

输出:

Time taken: 0.25033116340637207 seconds Time taken: 1020.9403311634064 seconds

	
© www.soinside.com 2019 - 2024. All rights reserved.