我的程序需要从一个巨大的Pandas Dataframe中根据列中的值获取一行。响应时间很关键。我使用最常见的方法来完成它,例如:
df.loc[df['id'] == 500000, :]
字符串在我的Mac上,每timeit需要4毫秒才能在一个有100万行的嵌套框架上完成上述操作。但我的目标是将时间减少到0.4毫秒。我曾经考虑将这个嵌套框架转换为Set,但Set不是有序的,并且本身不支持索引或切片。有什么建议吗?
timeit
olhwl3o21#
让我们设置这个:
import pandas as pd import numpy as np df = pd.DataFrame({"id": np.random.randint(100,size=(1000000,))})
字符串然后让我们对一些选项进行基准测试。您当前的boolean + .loc:
.loc
>>> timeit.timeit("df.loc[df['id'] == 50, :]", setup = "from __main__ import df", number=1000) 2.566220869999597
型查询引擎:
>>> timeit.timeit("df.query('id == 50')", setup = "from __main__ import df", number=1000) 14.591400260000228
型使用索引作为单独的查找:
>>> idx = pd.Index(df['id']) >>> timeit.timeit("df.loc[idx == 50, :]", setup = "from __main__ import df, idx", number=1000) 2.2155187300013495
型使用索引进行查找:
>>> df.index = df["id"] >>> timeit.timeit("df.loc[50, :]", setup = "from __main__ import df", number=1000) 2.625610274999417
型评论中有人提出的.isin()想法:
.isin()
>>> timeit.timeit("df.loc[df['id'].isin([50]), :]", setup = "from __main__ import df", number=1000) 9.542700138999862
型看起来,除了查询引擎对于简单的等式很慢(正如预期的那样)之外,您不会得到比查找时间更好的结果。
df_unique = pd.DataFrame({'id': range(1000000)})
型让我们看看一个唯一的ID可能会有帮助:
>>> timeit.timeit("df_unique.loc[df_unique['id'] == 50, :]", setup = "from __main__ import df_unique", number=1000) 1.9672015519990964
型然后是一个命令:
>>> df_unique.index = df_unique['id'] >>> df_dict = df_unique.to_dict(orient='index') >>> timeit.timeit("df_dict[50]", setup = "from __main__ import df_dict", number=1000) 6.247700002859347e-05
型看起来这是一个明显的赢家。
>>> timeit.timeit("pd.Series(df_dict[50])", setup = "from __main__ import df_dict, pd", number=1000) 0.2747819870000967
型即使你必须将它转换回一个序列,这也比以前快了一个数量级。(如果需要的话,你也可以很容易地将一个序列Map回dict,并保持dict查找的速度,而不会产生开销)
rnmwe5a22#
检查工作速度 df.query('id == 500000')。
ua4mk5z43#
使用df.id.values:让我们创建一个包含1000000行的嵌套框架:
df.id.values
import pandas as pd import numpy as np np.random.seed(3) df = pd.DataFrame({"id": np.random.randint(100,size=(1000000,))})
字符串方法一:
%%time df.loc[df['id'] == 50, :] #CPU times: user 6.64 ms, sys: 57 µs, total: 6.69 ms #Wall time: 5.39 ms
型
的数据方法二:
%%time df.loc[df.id.values == 50, :] #CPU times: user 3.97 ms, sys: 0 ns, total: 3.97 ms #Wall time: 2.82 ms
的
方法一:
import timeit timeit.timeit("df.loc[df['id'] == 50, :]", setup = "from __main__ import df", number=1000) #1.5578972157090902
型方法二:
timeit.timeit("df.loc[df.id.values == 50, :]", setup = "from __main__ import df", number=1000) #1.3210897352546453
3条答案
按热度按时间olhwl3o21#
让我们设置这个:
字符串
然后让我们对一些选项进行基准测试。您当前的boolean +
.loc
:型
查询引擎:
型
使用索引作为单独的查找:
型
使用索引进行查找:
型
评论中有人提出的
.isin()
想法:型
看起来,除了查询引擎对于简单的等式很慢(正如预期的那样)之外,您不会得到比查找时间更好的结果。
型
让我们看看一个唯一的ID可能会有帮助:
型
然后是一个命令:
型
看起来这是一个明显的赢家。
型
即使你必须将它转换回一个序列,这也比以前快了一个数量级。(如果需要的话,你也可以很容易地将一个序列Map回dict,并保持dict查找的速度,而不会产生开销)
rnmwe5a22#
检查工作速度 df.query('id == 500000')。
ua4mk5z43#
使用
df.id.values
:让我们创建一个包含1000000行的嵌套框架:
字符串
方法一:
型
的数据
方法二:
型
的
让我们使用timeit模块对测试进行基准测试。
方法一:
型
方法二:
型