繁体   English   中英

如何像pandas数据帧一样快速访问numpy数组

[英]How do I access a numpy array as quickly as a pandas dataframe

我对几种访问DataFrame数据的方法进行了比较。 见下面的结果。 最快的访问是在DataFrame上使用get_value方法。 我在这篇文章中提到了这一点。

令我惊讶的是,通过get_value访问比通过底层numpy对象df.values访问更快。

我的问题是,有没有办法像我可以通过get_value访问pandas数据帧一样快速访问numpy数组的元素?

设定

import pandas as pd
import numpy as np

df = pd.DataFrame(np.arange(16).reshape(4, 4))

测试

%%timeit
df.iloc[2, 2]

10000循环,最佳3:每循环108μs

%%timeit
df.values[2, 2]

最慢的运行时间比最快的运行时长5.42倍。 这可能意味着正在缓存中间结果。 100000次循环,最佳3:每循环8.02μs

%%timeit
df.iat[2, 2]

最慢的运行时间比最快的运行时长4.96倍。 这可能意味着正在缓存中间结果。 100000个循环,最佳3:9.85μs/循环

%%timeit
df.get_value(2, 2)

最慢的跑步比最快跑的时间长19.29倍。 这可能意味着正在缓存中间结果。 100000个循环,最佳3:每循环3.57μs

iloc很通用,接受切片和列表以及简单的整数。 在上面的例子中,你有简单的整数索引,pandas首先确定它是一个有效的整数,然后它将请求转换为一个iat索引,所以很明显它会慢得多。 iat最终解析为对get_value的调用,所以直接调用get_value会很快。 get_value本身是缓存的,因此像这样的微基准测试可能无法反映实际代码中的性能。

df.values确实返回一个ndarray,但只有在检查它是一个连续的块之后。 这需要一些查找和测试,因此它比从缓存中检索值要慢一些。

我们可以通过每次创建一个新的数据框来打败缓存。 这表明values访问器是最快的,至少对于统一类型的数据:

In [111]: %timeit df = pd.DataFrame(np.arange(16).reshape(4, 4))
10000 loops, best of 3: 186 µs per loop

In [112]: %timeit df = pd.DataFrame(np.arange(16).reshape(4, 4)); df.values[2,2]
1000 loops, best of 3: 200 µs per loop

In [113]: %timeit df = pd.DataFrame(np.arange(16).reshape(4, 4)); df.get_value(2,2)
1000 loops, best of 3: 309 µs per loop

In [114]: %timeit df = pd.DataFrame(np.arange(16).reshape(4, 4)); df.iat[2,2]
1000 loops, best of 3: 308 µs per loop

In [115]: %timeit df = pd.DataFrame(np.arange(16).reshape(4, 4)); df.iloc[2,2]
1000 loops, best of 3: 420 µs per loop

In [116]: %timeit df = pd.DataFrame(np.arange(16).reshape(4, 4)); df.ix[2,2]
1000 loops, best of 3: 316 µs per loop

该代码声称ix是最通用的,因此理论上应该比iloc慢; 可能是你的特定测试有利于ix但其他测试可能只是因为将索引标识为标量索引所需的测试顺序而有利于iloc

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM