我在考虑在一个解析问题中使用polars
代替numpy
,将结构化文本文件转换为字符表并对不同列进行操作。然而,似乎在我执行的大多数操作中,polars
比numpy
慢了约5倍。我想知道这是为什么,以及是否有什么我做错了,因为polars
应该更快。
例如:
import requests
import numpy as np
import polars as pl
# Download the text file
text = requests.get("https://files.rcsb.org/download/3w32.pdb").text
# Turn it into a 2D array of characters
char_tab_np = np.array(file.splitlines()).view(dtype=(str,1)).reshape(-1, 80)
# Create a polars DataFrame from the numpy array
char_tab_pl = pl.DataFrame(char_tab_np)
# Sort by first column with numpy
char_tab_np[np.argsort(char_tab_np[:,0])]
# Sort by first column with polars
char_tab_pl.sort(by="column_0")
在Jupyter
中使用%%timeit
,numpy
排序大约需要320微秒,而polars
排序大约需要1.3毫秒,即慢了约五倍。
我还尝试了char_tab_pl.lazy().sort(by="column_0").collect()
,但对持续时间没有影响。
另一个例子(获取第一列等于'A'的所有行):
# with numpy
%%timeit
char_tab_np[char_tab_np[:, 0] == "A"]
# with polars
%%timeit
char_tab_pl.filter(pl.col("column_0") == "A")
再次测试发现,numpy
耗时 226 微秒,而 polars
耗时 673 微秒,慢了三倍左右。
更新
根据评论中的建议,我尝试了两个方法:
1. 将文件增大1000倍,观察是否能在更大的数据上提高 polars 的性能。
结果:时间仍旧是 numpy
快约2倍(1.3毫秒对比2.1毫秒)。此外,创建字符数组需要的时间是 numpy
约2秒钟,而 polars
需要约2分钟才能创建数据帧,即慢了60倍。
要复制,请在上面的代码中创建 numpy 数组之前添加 text *= 1000
。
2. 将数据转换为整数类型。
对于原始(较小)文件,将其转换为整数可以加快numpy
和polars
的处理速度。在numpy
中进行的过滤仍然比polars
快约5倍(30微秒对120微秒),而排序时间变得更加相似(numpy为150微秒,polars为200微秒)。
然而,对于大文件,polars
略快于numpy
,但巨大的实例化时间只有在数据框需要被查询数千次时才值得使用。
char_tab_np = np.array(text.splitlines()).view(dtype='|U1').view(np.int32).astype(np.uint8).reshape(-1,80)
。 - Nick ODell