Spróbuj tego dla siebie:Dlaczego DataFrame.loc [[1]] 1 800 x wolniej niż df.ix [[1]] i 3500x niż df.loc [1]?
import pandas as pd
s=pd.Series(xrange(5000000))
%timeit s.loc[[0]] # You need pandas 0.15.1 or newer for it to be that slow
1 loops, best of 3: 445 ms per loop
Aktualizacja: który jest a legitimate bug in pandas że prawdopodobnie został wprowadzony w 0.15.1 w sierpniu 2014 roku lub tak. Obejścia: poczekaj na nowe wydanie, korzystając ze starej wersji pandy; zdobyć nowatorskiego dewelopera. wersja z github; ręcznie wykonaj jednoliniową modyfikację w wydaniu pandas
; tymczasowo użyj .ix
zamiast .loc
.
mam DataFrame 4,8 miliona rzędach, i wybranie jednego rzędu przez .iloc[[ id ]]
(z listy jednoelementowych) trwa 489 ms, prawie pół sekundy 1,800x razy wolniej niż identyczne .ix[[ id ]]
i 3.500x razy wolniej niż.iloc[id]
(przekazując identyfikator jako wartość, a nie jako listę). Aby być uczciwym, .loc[list]
zajmuje mniej więcej ten sam czas, niezależnie od długości listy, ale nie chcę wydać na nim 489 ms, zwłaszcza gdy .ix
jest tysiąc razy szybszy i daje taki sam wynik. Rozumiem, że powinno być wolniej, nieprawdaż?
Używam pand 0.15.1. Doskonały samouczek na temat Indexing and Selecting Data sugeruje, że .ix
jest jakoś bardziej ogólny i prawdopodobnie wolniejszy niż .loc
i .iloc
. Konkretnie, to mówi
Jednak, gdy oś jest liczbą całkowitą oparte tylko dostęp w oparciu etykiety i nie pozycyjną dostępu jest obsługiwana. Dlatego w takich przypadkach zwykle lepiej jest jawnie i użyć .iloc lub .loc.
Oto sesja ipython z benchmarków:
print 'The dataframe has %d entries, indexed by integers that are less than %d' % (len(df), max(df.index)+1)
print 'df.index begins with ', df.index[:20]
print 'The index is sorted:', df.index.tolist()==sorted(df.index.tolist())
# First extract one element directly. Expected result, no issues here.
id=5965356
print 'Extract one element with id %d' % id
%timeit df.loc[id]
%timeit df.ix[id]
print hash(str(df.loc[id])) == hash(str(df.ix[id])) # check we get the same result
# Now extract this one element as a list.
%timeit df.loc[[id]] # SO SLOW. 489 ms vs 270 microseconds for .ix, or 139 microseconds for .loc[id]
%timeit df.ix[[id]]
print hash(str(df.loc[[id]])) == hash(str(df.ix[[id]])) # this one should be True
# Let's double-check that in this case .ix is the same as .loc, not .iloc,
# as this would explain the difference.
try:
print hash(str(df.iloc[[id]])) == hash(str(df.ix[[id]]))
except:
print 'Indeed, %d is not even a valid iloc[] value, as there are only %d rows' % (id, len(df))
# Finally, for the sake of completeness, let's take a look at iloc
%timeit df.iloc[3456789] # this is still 100+ times faster than the next version
%timeit df.iloc[[3456789]]
wyjściowa:
The dataframe has 4826616 entries, indexed by integers that are less than 6177817
df.index begins with Int64Index([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], dtype='int64')
The index is sorted: True
Extract one element with id 5965356
10000 loops, best of 3: 139 µs per loop
10000 loops, best of 3: 141 µs per loop
True
1 loops, best of 3: 489 ms per loop
1000 loops, best of 3: 270 µs per loop
True
Indeed, 5965356 is not even a valid iloc[] value, as there are only 4826616 rows
10000 loops, best of 3: 98.9 µs per loop
100 loops, best of 3: 12 ms per loop
Należy zauważyć, że za pomocą '[[id]] 'i' [id]' nie są równoważne. '[id]' zwróci Serię, ale '[[id]]' zwróci jednorzędowe DataFrame. – BrenBarn
@BrenBarn, tak, to wyjaśnia różnicę dla '.ix': 141 μs vs. 270 μs. Ale dlaczego ".loc [[id]]" jest tak wolny? – osa