Панды являются действительно великими, но я действительно удивлен тем, как неэффективный это должно получить значения от Панды. DataFrame. В следующем игрушечном примере даже метод DataFrame.iloc больше чем в 100 раз медленнее, чем словарь.
Вопрос: урок здесь просто, что словари являются лучшим способом искать значения? Да, я получаю это, которое является точно, для чего они были сделаны. Но я просто задаюсь вопросом, существует ли что-то, что я пропускаю о выполнении поиска DataFrame.
Я понимаю, что этот вопрос больше "размышляет", чем "выяснение", но я приму ответ, который обеспечивает понимание или взгляд на это.Спасибо.
import timeit
setup = '''
import numpy, pandas
df = pandas.DataFrame(numpy.zeros(shape=[10, 10]))
dictionary = df.to_dict()
'''
f = ['value = dictionary[5][5]', 'value = df.loc[5, 5]', 'value = df.iloc[5, 5]']
for func in f:
print func
print min(timeit.Timer(func, setup).repeat(3, 100000))
оцените = словарь [5] [5]
0.130625009537
оцените = df.loc [5, 5]
19.4681699276
оцените = df.iloc [5, 5]
17.2575249672
Я думаю самый быстрый способ получить доступ к ячейке,
df.get_value(row,column)
df.set_value(row,column,value)
, Оба быстрее, чем (я думаю)
df.iat(...)
df.at(...)
Я испытал другое явление о доступе к строке кадра данных. протестируйте этот простой пример на кадре данных приблизительно 10 000 000 строк. скалы словаря.
def testRow(go):
go_dict = go.to_dict()
times = 100000
ot= time.time()
for i in range(times):
go.iloc[100,:]
nt = time.time()
print('for iloc {}'.format(nt-ot))
ot= time.time()
for i in range(times):
go.loc[100,2]
nt = time.time()
print('for loc {}'.format(nt-ot))
ot= time.time()
for i in range(times):
[val[100] for col,val in go_dict.iteritems()]
nt = time.time()
print('for dict {}'.format(nt-ot))
Кажется, что различие в производительности намного меньше теперь (0.21.1 - я забыл то, что было версией Панд в исходном примере). Не только разрыв производительности между доступом словаря и .loc
уменьшенный (приблизительно с 335 раз к в 126 раз медленнее), loc
(iloc
) меньше чем в два раза медленнее, чем at
(iat
) теперь.
In [1]: import numpy, pandas
...: ...: df = pandas.DataFrame(numpy.zeros(shape=[10, 10]))
...: ...: dictionary = df.to_dict()
...:
In [2]: %timeit value = dictionary[5][5]
85.5 ns ± 0.336 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [3]: %timeit value = df.loc[5, 5]
10.8 µs ± 137 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [4]: %timeit value = df.at[5, 5]
6.87 µs ± 64.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [5]: %timeit value = df.iloc[5, 5]
14.9 µs ± 114 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [6]: %timeit value = df.iat[5, 5]
9.89 µs ± 54.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [7]: print(pandas.__version__)
0.21.1
----Исходный ответ ниже----
+1 для использования at
или iat
для скалярных операций. Сравнительный тест в качестве примера:
In [1]: import numpy, pandas
...: df = pandas.DataFrame(numpy.zeros(shape=[10, 10]))
...: dictionary = df.to_dict()
In [2]: %timeit value = dictionary[5][5]
The slowest run took 34.06 times longer than the fastest. This could mean that an intermediate result is being cached
1000000 loops, best of 3: 310 ns per loop
In [4]: %timeit value = df.loc[5, 5]
10000 loops, best of 3: 104 µs per loop
In [5]: %timeit value = df.at[5, 5]
The slowest run took 6.59 times longer than the fastest. This could mean that an intermediate result is being cached
100000 loops, best of 3: 9.26 µs per loop
In [6]: %timeit value = df.iloc[5, 5]
10000 loops, best of 3: 98.8 µs per loop
In [7]: %timeit value = df.iat[5, 5]
The slowest run took 6.67 times longer than the fastest. This could mean that an intermediate result is being cached
100000 loops, best of 3: 9.58 µs per loop
кажется, что использование at
(iat
) приблизительно в 10 раз быстрее, чем [1 111] (iloc
).