Po eksperymentach z synchronizacją różnych typów wyszukiwań w Pandas DataFrame pozostaje mi kilka pytań.Porównanie czasów wyszukiwania Pandy
Oto skonfigurować ...
import pandas as pd
import numpy as np
import itertools
letters = [chr(x) for x in range(ord('a'), ord('z'))]
letter_combinations = [''.join(x) for x in itertools.combinations(letters, 3)]
df1 = pd.DataFrame({
'value': np.random.normal(size=(1000000)),
'letter': np.random.choice(letter_combinations, 1000000)
})
df2 = df1.sort_values('letter')
df3 = df1.set_index('letter')
df4 = df3.sort_index()
Więc DF1 wygląda mniej więcej tak ...
print(df1.head(5))
>>>
letter value
0 bdh 0.253778
1 cem -1.915726
2 mru -0.434007
3 lnw -1.286693
4 fjv 0.245523
Oto kod, aby sprawdzić różnice w wydajności odnośników ...
print('~~~~~~~~~~~~~~~~~NON-INDEXED LOOKUPS/UNSORTED DATASET~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
%timeit df1[df1.letter == 'ben']
%timeit df1[df1.letter == 'amy']
%timeit df1[df1.letter == 'abe']
print('~~~~~~~~~~~~~~~~~NON-INDEXED LOOKUPS/SORTED DATASET~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
%timeit df2[df2.letter == 'ben']
%timeit df2[df2.letter == 'amy']
%timeit df2[df2.letter == 'abe']
print('~~~~~~~~~~~~~~~~~~~~~INDEXED LOOKUPS~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
%timeit df3.loc['ben']
%timeit df3.loc['amy']
%timeit df3.loc['abe']
print('~~~~~~~~~~~~~~~~~~~~~SORTED INDEXED LOOKUPS~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
%timeit df4.loc['ben']
%timeit df4.loc['amy']
%timeit df4.loc['abe']
A wyniki ...
~~~~~~~~~~~~~~~~~NON-INDEXED LOOKUPS/UNSORTED DATASET~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10 loops, best of 3: 59.7 ms per loop
10 loops, best of 3: 59.7 ms per loop
10 loops, best of 3: 59.7 ms per loop
~~~~~~~~~~~~~~~~~NON-INDEXED LOOKUPS/SORTED DATASET~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10 loops, best of 3: 192 ms per loop
10 loops, best of 3: 192 ms per loop
10 loops, best of 3: 193 ms per loop
~~~~~~~~~~~~~~~~~~~~~INDEXED LOOKUPS~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The slowest run took 4.66 times longer than the fastest. This could mean that an intermediate result is being cached
10 loops, best of 3: 40.9 ms per loop
10 loops, best of 3: 41 ms per loop
10 loops, best of 3: 40.9 ms per loop
~~~~~~~~~~~~~~~~~~~~~SORTED INDEXED LOOKUPS~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The slowest run took 1621.00 times longer than the fastest. This could mean that an intermediate result is being cached
1 loops, best of 3: 259 µs per loop
1000 loops, best of 3: 242 µs per loop
1000 loops, best of 3: 243 µs per loop
pytania ...
To całkiem jasne, dlaczego wyszukiwanie na indeksie segregowanych jest tak dużo szybciej, wyszukiwanie binarne, aby uzyskać O (log (n)) vs wydajność O (n) dla pełnego skanowanie tablicy. Ale dlaczego wyszukiwanie na posortowanej nieindeksowanej kolumnie jest niepoparte indeksowaniem nieposortowanej nieindeksowanej kolumny
df1
?Co się stanie z
The slowest run took x times longer than the fastest. This could mean that an intermediate result is being cached
. Z pewnością wyniki nie są buforowane. Czy to dlatego, że utworzony indeks jest leniwy i czy nie jest ponownie indeksowany, dopóki nie jest potrzebny? To by wyjaśniało, dlaczego jest to tylko przy pierwszym połączeniu z.loc[]
.Dlaczego domyślnie nie jest posortowany indeks? Stały koszt tego rodzaju może być zbyt duży?
'3. Dlaczego domyślnie nie jest sortowany indeks? '- wyobraź sobie, że ustawiłeś niestandardowy indeks i został posortowany, nie pytając cię ... – MaxU
1. - ślad pamięci' df2' wynosi ok.50% większy w porównaniu do 'df1' – MaxU
@MaxU Powodem, dla którego pytam, jest fakt, że inne narzędzia (DBs i R's data.table) sortują według indeksu domyślnie –