Почему бы не использовать .values, а не .iat для улучшения производительности 6 раз?

Я был удивлен улучшением производительности в 6 раз, которое я получил путем доступа к элементам серии, используя my_series.values[0], а не my_series.iat[0].

В соответствии с документацией .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

Основываясь на каком-то эксперименте, кажется, что разница в скорости между iat и values значительно сужается, если у вас несколько столбцов (как правило, это так).

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 похоже на сопоставимую скорость в худшем случае, поэтому в iat по сравнению с values добавлена ​​небольшая добавленная стоимость, если вы используете индексирование по позициям (если только вы предпочитаете синтаксис).

И наоборот, индексирование на основе меток невозможно с values, и в этом случае at будет намного быстрее, чем использование loc в комбинации с values.

(тайминг выше с использованием pandas версии 0.18.0)