为什么不使用.values而不是.iat来提高6倍的性能?

时间:2016-10-04 15:41:23

标签: python pandas

我对使用my_series.values[0]而不是my_series.iat[0]访问系列元素所获得的6倍性能提升感到惊讶。

根据documentation.iat是快速访问标量的推荐方法。我使用.values遗漏了什么吗?

import numpy as np
import pandas as pd

n = 1000
dct = {'A': np.random.rand(n)}
df = pd.DataFrame(dct)
s = df['A']
vals = s.values

%timeit -n 10000 val = s.iloc[0]
%timeit -n 10000 val = s.iat[0]
%timeit -n 10000 val = s.values[0]
%timeit -n 10000 vals[0]

**Output**
10000 loops, best of 3: 24.3 µs per loop
10000 loops, best of 3: 13.4 µs per loop
10000 loops, best of 3: 2.06 µs per loop
10000 loops, best of 3: 337 ns per loop

1 个答案:

答案 0 :(得分:2)

根据一些实验,如果您有多列(通常是这种情况),iatvalues之间的速度差异会显着缩小。

n = 1000
dct = {'A': np.random.rand(n), 'B': np.random.rand(n) }
df = pd.DataFrame(dct)

%timeit df.iat[n-5,1]
100000 loops, best of 3: 9.72 µs per loop

%timeit df.B.values[n-5]
100000 loops, best of 3: 7.3 µs per loop

有趣的是,无论是直接访问单元格,还是首先选择列,然后选择行,都可能很重要。

如果是iat,最好在整个数据框中使用它:

%timeit df.iat[n-5,1]
100000 loops, best of 3: 9.72 µs per loop

%timeit df.B.iat[n-5]
100000 loops, best of 3: 15.4 µs per loop

但是对于values,最好选择列,然后使用values

%timeit df.values[n-5,1]
100000 loops, best of 3: 9.42 µs per loop

%timeit df.B.values[n-5]
100000 loops, best of 3: 7.3 µs per loop

但无论如何,使用values代替iat似乎在最差时提供可比速度,因此iatvalues的增值似乎很少您正在使用基于位置的索引(除非您更喜欢语法)。

相反,values无法使用基于标签的索引,在这种情况下,at比将locvalues结合使用要快得多。

(使用pandas版本0.18.0上面的时间安排)