Järjestettyjen indeksien suorituskykyedut
Järjestäkää MultiIndex sort_index()-menetelmällä, mitatkaa viipaleiden suorituskykyä timeit-työkalulla ja käyttäkää is_monotonic_increasing-arvoa tarkistusehtona.
Järjestettyjen indeksien suorituskykyedut on ilmainen Pandas & NumPy Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Pandas & NumPy Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Pandas & NumPy Academy-kurssilla on yhteensä 4 oppituntia.
Miksi indeksin järjestämisellä on merkitystä suorituskyvyn kannalta
Järjestetty indeksi mahdollistaa sen, että Pandas käyttää binäärihakua (O(log n)) täyden lineaarisen läpikäynnin (O(n)) sijaan etsiessään tunnistealueita. Miljoonan rivin DataFramessa binäärihaku löytää kohdealueen noin 20 vertailulla, kun taas lineaarinen läpikäynti voi vaatia jopa miljoona vertailua. Tämän ansiosta viipalointitoiminnot ovat järjestetyillä MultiIndex-indekseillä moninkertaisesti nopeampia kuin järjestämättömillä, ja ero muuttuu ratkaisevaksi tuotantoputkissa, jotka käsittelevät miljoonia rivejä.
import pandas as pd
import numpy as np
np.random.seed(42)
# Create a large DataFrame with a MultiIndex
countries = ['DE', 'UK', 'USA', 'FR', 'JP']
dates = pd.date_range('2020-01-01', periods=200)
mi = pd.MultiIndex.from_product([countries, dates], names=['country', 'date'])
df = pd.DataFrame({'value': np.random.randn(len(mi))}, index=mi)
print(f'DataFrame shape: {df.shape}')
print(f'Index is sorted: {df.index.is_monotonic_increasing}')Indeksin järjestyksen tarkistaminen
Tarkistakaa indeksin nouseva järjestys käyttämällä df.index.is_monotonic_increasing-ominaisuutta. Se palauttaa totuusarvon. MultiIndex-indeksillä Pandas tarkistaa järjestyksen leksikografisesti kaikilla tasoilla. Tarkistakaa tämä aina ennen .loc[start:end]-kutsua käyttävää viipalointia MultiIndex-indeksillä — järjestämätön indeksi joko aiheuttaa UnsortedIndexError-virheen tai palauttaa Pandas-version mukaan huomaamatta virheellisiä tuloksia.
import pandas as pd
# Sorted MultiIndex
tuples_sorted = [('A', 1), ('A', 2), ('B', 1), ('B', 2)]
mi_sorted = pd.MultiIndex.from_tuples(tuples_sorted)
df_sorted = pd.DataFrame({'v': [10, 20, 30, 40]}, index=mi_sorted)
# Unsorted MultiIndex
tuples_unsorted = [('B', 2), ('A', 1), ('B', 1), ('A', 2)]
mi_unsorted = pd.MultiIndex.from_tuples(tuples_unsorted)
df_unsorted = pd.DataFrame({'v': [10, 20, 30, 40]}, index=mi_unsorted)
print('Sorted index is_monotonic_increasing:', df_sorted.index.is_monotonic_increasing)
print('Unsorted index is_monotonic_increasing:', df_unsorted.index.is_monotonic_increasing)Järjestäminen sort_index()-kutsulla
df.sort_index() palauttaa uuden DataFramen, jonka rivit on järjestetty indeksitunnisteen mukaan nousevaan järjestykseen. Käyttäkää laskevaan järjestykseen asetusta ascending=False. MultiIndex-indeksillä järjestys on leksikografinen: ensin järjestetään uloimman tason mukaan ja sen jälkeen sisemmät tasot kunkin ulomman ryhmän sisällä. Järjestäkää indeksi aina minkä tahansa sen järjestyksen mahdollisesti rikkovan operaation jälkeen — tällaisia ovat esimerkiksi pd.concat, suodatus ja uusien rivien lisääminen.
import pandas as pd
import numpy as np
np.random.seed(0)
countries = ['USA', 'UK', 'DE']
years = [2021, 2022, 2023]
mi = pd.MultiIndex.from_product([countries, years], names=['country', 'year'])
df = pd.DataFrame({'gdp': np.random.randint(3000, 26000, 9)}, index=mi)
print('Before sort_index():')
print(df.head(4))
df_sorted = df.sort_index()
print('\nAfter sort_index():')
print(df_sorted.head(4))
print('Is sorted:', df_sorted.index.is_monotonic_increasing)Hakuajan mittaaminen timeit-moduulilla
Pythonin timeit-moduuli mittaa, kuinka kauan lauseen suorittaminen kestää, suorittamalla sen useita kertoja ja laskemalla keskiarvon. Käyttäkää sitä järjestettyjen ja järjestämättömien indeksihakujen vertailuun. IPythonissa ja Jupyterissa %timeit-taikakomento tarjoaa saman toiminnallisuuden selkeämmin tuloksin. Mittaaminen on ainoa luotettava tapa varmistaa, että suorituskykyoptimointi todella auttoi — älkää koskaan olettako muutoksen olevan nopeampi ilman mittausta.
import pandas as pd
import numpy as np
import timeit
np.random.seed(0)
N = 500000
idx = np.random.choice(['A','B','C','D','E'], N)
df_unsorted = pd.DataFrame({'v': np.random.randn(N)}, index=idx)
df_sorted = df_unsorted.sort_index()
# Time label lookup: sorted vs unsorted
t_unsorted = timeit.timeit(lambda: df_unsorted.loc['C'], number=100)
t_sorted = timeit.timeit(lambda: df_sorted.loc['C'], number=100)
print(f'Unsorted lookup (100 runs): {t_unsorted:.3f}s')
print(f'Sorted lookup (100 runs): {t_sorted:.3f}s')
print(f'Speedup: {t_unsorted/t_sorted:.1f}x')PerformanceWarning järjestämättömästä MultiIndex-indeksistä
Pandas antaa PerformanceWarning-varoituksen, kun viipaloitte leksikografisesti järjestämätöntä MultiIndex-indeksiä: 'indexing past lexsort depth may impact performance'. Tämä varoitus tarkoittaa, että Pandas joutui käyttämään lineaarista läpikäyntiä binäärihaun sijaan. Vaikka tulokset ovat yksinkertaisissa tapauksissa edelleen oikein, sisempien tasojen viipalointi järjestämättömässä monitasoisessa indeksissä voi tuottaa virheellisiä tuloksia. Käsitelkää tätä varoitusta virheenä ja korjatkaa sen perimmäinen syy järjestämällä indeksi.
import pandas as pd
import warnings
# Create an unsorted MultiIndex and trigger the warning
tuples = [('B', 2), ('A', 1), ('B', 1), ('A', 2)]
mi = pd.MultiIndex.from_tuples(tuples, names=['letter', 'num'])
df = pd.DataFrame({'v': [10, 20, 30, 40]}, index=mi)
print('Index sorted?', df.index.is_monotonic_increasing)
# This may trigger PerformanceWarning in some Pandas versions
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter('always')
try:
result = df.loc['A':'B', :]
print('Result:', result)
if w:
print('Warning:', str(w[0].message))
except Exception as e:
print('Error (common with newer Pandas):', type(e).__name__)Järjestetyn ja järjestämättömän MultiIndex-indeksin viipaloinnin vertailumittaus
Järjestetyn MultiIndex-indeksin viipalointi on huomattavasti nopeampaa, koska Pandas voi tehdä binäärihaun sekä uloimpien että sisempien tasojen taulukoista. Mitataan suuren, miljoonan rivin MultiIndex-indeksin viipalointia — tämä on tuotannon analytiikkaputkissa yleinen koko. Järjestetty versio välttää lineaarisen läpikäynnin ja saavuttaa viipaleen valikoivuudesta riippuen toistuvasti 5–50-kertaisen nopeutuksen.
import pandas as pd
import numpy as np
import timeit
np.random.seed(42)
countries = ['DE', 'UK', 'USA', 'FR', 'JP']
dates = pd.date_range('2010-01-01', periods=200000)
# Sample a random subset for timing test
sample_countries = np.random.choice(countries, 100000)
sample_dates = np.random.choice(dates, 100000)
df = pd.DataFrame({
'country': sample_countries,
'date': sample_dates,
'value': np.random.randn(100000)
}).set_index(['country', 'date'])
df_sorted = df.sort_index()
print('Dataset size:', len(df))
print('Sorted:', df_sorted.index.is_monotonic_increasing)
t = timeit.timeit(lambda: df_sorted.loc['USA'], number=50)
print(f'Sorted lookup (50 runs): {t:.3f}s')sort_index level-parametrilla
MultiIndex-indeksillä voitte järjestää tietyn tason kaikkien tasojen sijaan käyttämällä level-parametria: df.sort_index(level='year'). Tämä on hyödyllistä, kun haluatte säilyttää ulomman tason ryhmittelyn mutta järjestää rivit uudelleen kunkin ulomman ryhmän sisällä. sort_remaining=True-argumentti (oletusarvo) järjestää lisäksi kaikki määritetyn tason jälkeiset järjestämättömät tasot ja varmistaa täyden leksikografisen järjestyksen.
import pandas as pd
import numpy as np
countries = ['USA', 'UK']
years = [2023, 2021, 2022] # deliberately unordered
mi = pd.MultiIndex.from_product([countries, years], names=['country', 'year'])
df = pd.DataFrame({'v': range(6)}, index=mi)
print('Before sorting by year level:')
print(df)
# Sort by the inner level (year) only
df_ysorted = df.sort_index(level='year')
print('\nAfter sort_index(level="year"):')
print(df_ysorted)is_monotonic_increasing putken suojauksena
Lisätkää tuotantoputkissa järjestyksen tarkistus jokaisen sellaisen funktion alkuun, joka vastaanottaa MultiIndex-indeksillä varustetun DataFramen ja suorittaa viipalointia. Jos indeksiä ei ole järjestetty, järjestäkää se automaattisesti ja kirjatkaa varoitus lokiin. Näin estätte suorituskyvyn huomaamattoman heikkenemisen tai virheelliset tulokset, jos lähdekoodin muutos muuttaa DataFramen järjestystä. Funktion rajalla tehty tarkistus on luotettavampi kuin oletus siitä, että kutsujat välittävät aina järjestettyä dataa.
import pandas as pd
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def safe_slice(df, key):
'''Slice a MultiIndex DataFrame, sorting if necessary.'''
if not df.index.is_monotonic_increasing:
logger.warning('Index not sorted — sorting now. This is a performance cost.')
df = df.sort_index()
return df.loc[key]
# Test with an unsorted DataFrame
tuples = [('B', 2), ('A', 1), ('B', 1), ('A', 2)]
mi = pd.MultiIndex.from_tuples(tuples, names=['letter', 'num'])
df = pd.DataFrame({'v': [10, 20, 30, 40]}, index=mi)
result = safe_slice(df, 'A')
print('Slice result for A:')
print(result)Järjestetty indeksi binäärihakua varten yksinkertaisilla indekseillä
Järjestämisen suorituskykyhyödyt koskevat myös tavallisia (ei-monitasoisia) indeksejä. Aikasarja-analyysissä käytetty DatetimeIndex mahdollistaa huomattavasti nopeamman päivämäärävälin viipaloinnin, kun indeksi on järjestetty. Aakkosjärjestykseen järjestetty merkkijonoindeksi mahdollistaa binäärihaun tunnisteita haettaessa. Aikaleimoilla indeksoidussa suuressa osakehintojen Series-objektissa DatetimeIndexin järjestäminen voi lyhentää viipaloinnin 100 millisekunnista alle millisekuntiin.
import pandas as pd
import numpy as np
import timeit
np.random.seed(0)
# Random timestamps — unsorted
timestamps = pd.date_range('2020-01-01', periods=500000, freq='min')
shuffled = np.random.permutation(timestamps)
prices = pd.Series(np.random.randn(500000), index=shuffled)
prices_sorted = prices.sort_index()
# Time a date range slice
t_unsorted = timeit.timeit(lambda: prices['2020-06-01':'2020-06-30'], number=20)
t_sorted = timeit.timeit(lambda: prices_sorted['2020-06-01':'2020-06-30'], number=20)
print(f'Unsorted: {t_unsorted:.3f}s')
print(f'Sorted: {t_sorted:.3f}s')
print(f'Speedup: {t_unsorted/t_sorted:.0f}x')Järjestämisen muistihinta
Järjestäminen ei ole ilmaista — sort_index() luo DataFramesta uuden kopion (ellei käytetä inplace=True-asetusta, joka muuttaa objektia paikallaan). Erittäin suurilla DataFrameilla tämä kaksinkertaistaa tilapäisesti huippumuistinkulutuksen. Käytännöllinen strategia on järjestää kerran latauksen yhteydessä ja säilyttää järjestetty versio koko putken ajan sen sijaan, että järjestäisitte datan toistuvasti. Jos muistia on niukasti, käyttäkää paikallaan suoritettavaa järjestämistä komennolla df.sort_index(inplace=True) väliaikaisen kopion välttämiseksi.
import pandas as pd
import numpy as np
np.random.seed(0)
countries = ['DE', 'UK', 'USA']
years = [2021, 2022, 2023]
mi = pd.MultiIndex.from_product([countries, years], names=['country', 'year'])
df = pd.DataFrame({'v': np.random.randn(9)}, index=mi)
# Sort once at load time — best practice
df.sort_index(inplace=True) # no temporary copy
assert df.index.is_monotonic_increasing, 'Index must be sorted!'
print('Pipeline-ready DataFrame (sorted in place):')
print(df)Järjestettyjen indeksien parhaiden käytäntöjen yhteenveto
Indeksin suorituskyvyn keskeiset säännöt: 1) Kutsukaa aina sort_index()-metodia minkä tahansa indeksin järjestyksen mahdollisesti rikkovan operaation jälkeen (concat, merge, append, filter). 2) Käyttäkää is_monotonic_increasing-ominaisuutta tarkistuksena indeksiä viipaloivissa funktioissa. 3) Järjestäkää data latauksen yhteydessä ja säilyttäkää järjestetty DataFrame koko putken ajan toistuvan järjestämisen välttämiseksi. 4) Varmistakaa MultiIndex-indekseillä, että kaikki tasot on järjestetty, ei vain ulointa tasoa. 5) Käyttäkää timeit-moduulia varmistaaksenne, että järjestäminen todella tuottaa odotetun nopeutuksen juuri omassa putkessanne.
Pikatarkistus
Testatkaa tässä oppitunnissa oppimaanne järjestetyn indeksin suorituskyvystä.
Oppitunnin yhteenveto
Tässä oppitunnissa opitte, että is_monotonic_increasing tarkistaa, onko indeksi järjestetty ja onko binäärihaku käytettävissä, sort_index() järjestää indeksin paikallaan tai palauttaa järjestetyn kopion ja timeit mittaa todellisen nopeutuksen hyödyn vahvistamiseksi. Seuraavaksi tutustumme ikkunafunktioihin — aikasarja- ja talousdatan liukuviin ja kumuloituviin tilastoihin.
Opi Python tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 30
- Oppitunnit
- 120
Usein kysytyt kysymykset
Onko oppitunti ”Järjestettyjen indeksien suorituskykyedut” ilmainen?
Kyllä – oppitunnin ”Järjestettyjen indeksien suorituskykyedut” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Pandas & NumPy Academy-kurssin, päivitä CoddyKit PROhon. Pandas & NumPy Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Järjestettyjen indeksien suorituskykyedut”?
Järjestäkää MultiIndex sort_index()-menetelmällä, mitatkaa viipaleiden suorituskykyä timeit-työkalulla ja käyttäkää is_monotonic_increasing-arvoa tarkistusehtona. Harjoittelet Pandas & NumPy Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Pandas & NumPy Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Pandas & NumPy Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.
Kuinka kauan ”Järjestettyjen indeksien suorituskykyedut”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Pandas & NumPy Academy-oppitunnilla?
Kyllä. Jokainen Pandas & NumPy Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- MultiIndex-indeksin luominen
- Datan valinta MultiIndex-indeksistä
- Indeksien kohdistus ja uudelleenindeksointi
- Järjestettyjen indeksien suorituskykyedut