我对几种访问DataFrame
数据的方法进行了比较。见下面的结果。最快的访问是在get_value
上使用DataFrame
方法。我在post上提到了这一点。
我感到惊讶的是,通过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
答案 0 :(得分:2)
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
。