Korte Python-handleiding: Geavanceerde onderwerpen in Pandas (2023)

Gepubliceerd op:
Mijn ervaring met het onderzoeken van de geavanceerde functies van Pandas voor Python in 2023.

Inleiding

Ik heb jarenlang diep in de wereld van gegevensverwerking en -analyse gezeten, en ik kan je vertellen: Pandas is veel meer dan zomaar een Python-bibliotheek. Of je nu bezig bent met ingewikkelde datasets of de prestaties bij grote data-operaties wil verbeteren, Pandas is de ruggengraat voor effectieve en betrouwbare gegevensmanipulatie. Het is een hulpmiddel dat ik keer op keer heb gebruikt, niet alleen voor basisdingen, maar ook voor de beslissende stappen in machine learning. Door vallen en opstaan en vele uren coderen, heb ik inzichten en beste praktijken verzameld die ik graag wil delen – tips die vooral belangrijk zijn voor degenen die beginnen in de wereld van Python data science.

Geavanceerde Gegevensmanipulatie met MultiIndex

Toen ik voor het eerst begon met het gebruiken van Pandas, was het werken met eenvoudige data gemakkelijk. Maar zodra ik moest omgaan met complexere datastructuren, zoals meerdere niveaus van groepering binnen één dataset, werd het wat lastiger. Daar kwam MultiIndex: een doorbraak voor het werken met data met meerdere dimensies in een tweedimensionale structuur.

Maar wat is MultiIndex nou eigenlijk? Stel je voor dat je werkt met verkoopgegevens over verschillende regio's, diverse producten, en meerdere tijdperiodes. Zonder MultiIndex zou je met meerdere draaitabellen of datasets moeten jongleren. Met MultiIndex kun je deze data in één DataFrame structureren, met indices die meerdere dimensies vertegenwoordigen.

Hier is een voorbeeld. Stel dat we verkoopgegevens hebben voor twee producten ("Widgets" en "Gadgets") in twee regio's ("Noord" en "Zuid") voor twee kwartalen:

import pandas as pd

arrays = [['Noord', 'Noord', 'Zuid', 'Zuid'], ['K1', 'K2', 'K1', 'K2'], ['Widgets', 'Widgets', 'Gadgets', 'Gadgets']]
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=['Regio', 'Kwartaal', 'Product'])
data = {'Verkoop': [25000, 30000, 15000, 20000]}
df = pd.DataFrame(data, index=index)

Dit geeft ons een DataFrame met hiërarchische indexering, wat je kunt verifiëren door simpelweg df af te drukken.

Stel dat ik naar de totale verkoop per regio wil kijken, ongeacht kwartaal of product. De sum-functie met de level-parameter komt dan goed van pas:

regionale_verkoop = df.sum(level='Regio')
print(regionale_verkoop)

Je zult merken dat deze operatie de hiërarchische structuur respecteert, door alleen binnen het opgegeven niveau op te tellen.

Als je de data wilt omvormen, is dat met MultiIndex heel eenvoudig. Stel dat ik de producten naast elkaar wil vergelijken per kwartaal. De unstack-methode kan onze MultiIndex DataFrame herschikken naar iets conventioneels:

df_unstacked = df.unstack(level="Product")
print(df_unstacked)

Het tegenovergestelde van unstack is stack. Dit voegt een niveau van de DataFrame samen, wat handig kan zijn wanneer je data moet serialiseren of in een machine learning model moet stoppen.

Gebruikmakend van pd.IndexSlice, kun je ook eenvoudig data eruit halen. Stel dat ik gegevens nodig heb voor "Widgets" in de "Noord" regio:

idx = pd.IndexSlice
widgets_noord_data = df.loc[idx['Noord', :, 'Widgets'], :]
print(widgets_noord_data)

Vrij simpel als je er eenmaal aan gewend bent, toch?

Voor degenen die nog dieper willen duiken, is er uitgebreide documentatie over MultiIndex in de officiële Pandas-documentatie (https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html). En als je, net als ik, beter leert door naar voorbeelden te kijken, dan is de Pandas GitHub repository (https://github.com/pandas-dev/pandas) vol met eenheden en praktijkvoorbeelden van MultiIndex.

Ik moet zeggen, het beheersen van MultiIndex heeft zijn vruchten afgeworpen bij mijn data-manipulatie taken. Het brengt een krachtige dimensie in DataFrame-operaties, waardoor ogenschijnlijk complexe taken in enkele regels code worden omgezet. En voor beginners, voel je niet overweldigd. Hoe meer ik MultiIndex in mijn werkstromen integreerde, hoe intuïtiever het werd. Veel plezier met indexeren!

Prestatieoptimalisatie in Pandas

Prestatieoptimalisatie is cruciaal bij het werken met grote datasets in Pandas. Efficiëntie kan vaak het verschil maken tussen een taak die minuten duurt en een die uren aansleept. Ik heb een aantal trucs ontdekt die de uitvoeringstijd van mijn code aanzienlijk verkorten, en ik ben enthousiast om een paar van deze optimalisatiestrategieën te delen.

Een van de eerste dingen die ik leerde, was het belang van het kiezen van de juiste datatypes. Pandas gebruikt standaard 64-bits types, wat overdreven kan zijn en onnodig veel geheugen kan verbruiken. Door naar kleinere datatypes om te zetten, kun je het geheugenverbruik drastisch verminderen. Hier is een eenvoudig voorbeeld:

import pandas as pd

# Stel dat df onze grote DataFrame is

# Controleer de datatypes en het geheugengebruik
print(df.dtypes)
print(df.memory_usage(deep=True))

# Converteer int64 naar int32 en float64 naar float32
df_int = df.select_dtypes(include=['int64']).astype('int32')
df[df_int.columns] = df_int

df_float = df.select_dtypes(include=['float64']).astype('float32')
df[df_float.columns] = df_float

# Controleer het verminderde geheugengebruik
print(df.memory_usage(deep=True))

Als je te maken hebt met categorische data, kan het datatype category in Pandas een redding zijn. Vooral als je een aanzienlijke hoeveelheid herhaling in je tekstdataset hebt:

# Converteer object naar category
df_object = df.select_dtypes(include=['object']).nunique().sort_values()
# Stel dat we een 'category' kolom hebben met een beperkt aantal unieke waarden
df['category'] = df['category'].astype('category')

# Controleer het voor en na geheugengebruik
print(df.memory_usage(deep=True))

Een andere prestatie-tip die ik volg, is het vermijden van loops waar dat mogelijk is en gebruik te maken van de gevectoriseerde bewerkingen van Pandas. Dit was een openbaring toen ik voor het eerst mijn script vol loops herschreef. Hier is hoe dat eruitziet in de praktijk:

# Slechte praktijk met loop
for index, row in df.iterrows():
    df.at[index, 'new_col'] = row['col1'] * row['col2']

# Betere praktijk met vectorisatie
df['new_col'] = df['col1'] * df['col2']

Tot slot maak ik vaak gebruik van de methoden query() en eval() om mijn booleaanse indexering en berekeningen te versnellen. In plaats van de standaard pandas-bewerkingen, die traag kunnen zijn, versnellen deze methoden operaties door Numexpr te gebruiken. Hier is een vergelijking:

# Gebruik van standaard Pandas-bewerkingen
df_filtered = df[df['col']  0]

# Gebruik van query voor snellere bewerking
df_filtered = df.query('col  0')

En voor berekeningen:

# Gebruik van standaard Pandas-bewerkingen
df['new_col'] = df['col1'] * df['col2'] + df['col3']

# Gebruik van eval voor snellere bewerking
df.eval('new_col = col1 * col2 + col3', inplace=True)

Een combinatie van deze technieken verbetert meestal de prestaties spectaculair, maar onthoud dat de resultaten kunnen variëren op basis van de grootte en aard van je dataset. Het belangrijkste inzicht dat ik heb opgedaan, is altijd om verschillende benaderingen te testen om de meest geschikte oplossing te vinden.

Voor verder lezen en een diepere duik in Panda's prestatieoptimalisatie, raad ik aan om de officiële Pandas documentatie over prestatieverbetering te bekijken. Blijf experimenteren om de optimale setup voor jouw specifieke situatie te ontdekken.

Tijdreeksanalyse Eenvoudig Gemaakt

Tijdreeksanalyse is een essentieel hulpmiddel voor iedereen die met gegevens werkt die door tijd worden beïnvloed. Met pandas, een van Python's belangrijkste bibliotheken, kun je efficiënt tijdreeksgegevens manipuleren en analyseren, zelfs met beperkte ervaring in data-analyse. Ik deel een paar basisvaardigheden om je snel op weg te helpen.

Controleer eerst of pandas is geïnstalleerd:

pip install pandas

Stel dat we een CSV-bestand hebben genaamd 'stock_data.csv' met dagelijkse aandelenkoersen en een datumkolom. Het maken van een pandas DataFrame van dit bestand is eenvoudig:

import pandas as pd

df = pd.read_csv('stock_data.csv', parse_dates=['Date'], index_col='Date')

De parameter parse_dates zorgt ervoor dat pandas onze 'Date'-kolom als datetime objecten herkent, wat essentieel is voor tijdreeksanalyse. Door deze kolom met index_col als index in te stellen, kunnen we eenvoudig gegevens op datum opvragen.

Met deze instellingen kan ik snel de aandelenkoersen op een specifieke dag bekijken:

specific_day = df.loc['2023-01-01']

Of als ik alle aandelenkoersen voor januari 2023 nodig heb, gebruik ik:

january_data = df['2023-01']

Een veelvoorkomende bewerking is resampling, wat de frequentie van de datapunten in de reeks verandert. Om bijvoorbeeld onze dagelijkse gegevens in maandelijkse gegevens om te zetten en de gemiddelde prijs per maand te berekenen:

monthly_data = df.resample('M').mean()

Voortschrijdende gemiddelden worden vaak gebruikt om kortetermijnfluctuaties glad te strijken en langetermijntrends te benadrukken. Het berekenen van een eenvoudige voortschrijdend gemiddelde over 7 dagen doe je zo:

df['7_day_rolling_avg'] = df['Price'].rolling(window=7).mean()

Voor tijdreeksvoorspellingen kan pandas de gegevensstructuur voorbereiden die vervolgens in een voorspellingsmodel wordt gevoerd. We gaan een hypothetisch machine learning model gebruiken dat toekomstige aandelenkoersen voorspelt op basis van historische gegevens. Onze eerste stap zou zijn om een getrapt kenmerk te maken: de prijs van de vorige dag:

df['Prev_day_price'] = df['Price'].shift(1)

Maar er is meer aan tijdreeksen dan eenvoudige manipulaties. Vaak hebben we te maken met ontbrekende waarden, vooral als de aandelenmarkt in het weekend en op feestdagen gesloten is. We kunnen deze ontbrekende waarden door vooruitvullen opvullen met pandas:

df = df.asfreq('D', method='ffill')

Plotten is ook een belangrijk onderdeel van de analyse. Met pandas is het visualiseren van je tijdreeksgegevens eenvoudig. Hier is hoe ik snel onze monthly_data DataFrame kan plotten:

import matplotlib.pyplot as plt

monthly_data.plot()
plt.title('Maandelijkse Gemiddelde Aandelenkoers')
plt.show()

Als je verder wilt leren voorbij de basis die ik heb getoond, zijn er talloze bronnen beschikbaar. Voor diepgaande technieken en complexe scenario's is de pandas documentatie (pandas.pydata.org) bijzonder gedetailleerd. Daarnaast is Jake VanderPlas's "Python Data Science Handbook" een fantastische bron met een bijbehorende GitHub repository (github.com/jakevdp/PythonDataScienceHandbook) die voorbeeldnotebooks heeft om te volgen.

Om verder te komen dan het beginnersniveau, overweeg dan een project met echte gegevens aan te pakken. De beroemde Tijdreeks Voorspellen Oefening op Kaggle (kaggle.com) biedt datasets en uitdagingen die je vaardigheden testen en je begrip ontwikkelen.

Onthoud, hoewel dit overzicht de belangrijkste aspecten van tijdreeksanalyse met pandas behandelt, gebeurt het leren echt door te oefenen. Dus pak een dataset en ga op ontdekking!

Pandas integreren met moderne Python Async IO

Integreren van async IO met Pandas lijkt een beetje alsof je een vierkante pen in een rond gat probeert te krijgen; ze zijn niet van nature ontworpen om soepel samen te werken. Maar de asynchrone functies van Python kunnen grote prestatievoordelen bieden bij het uitvoeren van I/O-gebaseerde operaties. Als iemand die met grote, onhandelbare datasets heeft gewerkt die afhankelijk zijn van live datafeeds, heb ik een aantal strategieën ontwikkeld om de synchrone wereld van Pandas te combineren met asynchrone Python-functies. Laten we deze eens doornemen.

De asyncio-bibliotheek in Python maakt het mogelijk om simultaan te werken via coroutines. Traditionele synchrone operaties blokkeren de thread tot ze voltooid zijn, terwijl een asynchrone operatie wordt onderbroken wanneer er op een resultaat wordt gewacht dat niet direct beschikbaar is, zodat de thread ondertussen ander werk kan doen.

Echter, de meeste functies van Pandas zijn synchroon en zullen de evenementlus blokkeren wanneer ze draaien. Om dit te voorkomen, moeten we Pandas-operaties uitvoeren in een thread-pool met behulp van de run_in_executor-methode van asyncio. Dit biedt een niet-blokkerende manier om Pandas binnen een asynchroon programma te gebruiken. Laten we dit met een voorbeeld laten zien.

Stel dat we een asynchrone functie hebben om data over het netwerk op te halen (een veelgebruikte async-operatie). We zullen het ophalen asynchroon uitvoeren en vervolgens de opgehaalde data met Pandas verwerken in een thread-pool.

import aiohttp
import pandas as pd
import asyncio
from concurrent.futures import ThreadPoolExecutor

# Haal data asynchroon op
async def fetch_data(session, url):
    async with session.get(url) as response:
        return await response.text()

# Verwerk data met Pandas op een thread-veilige manier
def process_data(data):
    df = pd.read_csv(data)
    # Voer enkele Pandas-operaties uit op de df
    return df

async def main():
    # Lijst met URLs om data op te halen
    urls = ["http://example.com/data1.csv", "http://example.com/data2.csv"]
    # Maak een ThreadPoolExecutor
    executor = ThreadPoolExecutor(max_workers=2)

    async with aiohttp.ClientSession() as session:
        # Plan alle ophaaloperaties om asynchroon te draaien
        fetch_futures = [fetch_data(session, url) for url in urls]
        raw_data_list = await asyncio.gather(*fetch_futures)

        # Zodra we de data hebben, verwerken we het parallel met Pandas op een thread-veilige manier
        loop = asyncio.get_event_loop()
        df_list = await asyncio.gather(*(loop.run_in_executor(executor, process_data, data) for data in raw_data_list))

        # Nu bevat df_list al onze verwerkte DataFrames
        print(df_list)

if __name__ == "__main__":
    asyncio.run(main())

De code gebruikt aiohttp voor asynchrone HTTP-verzoeken, waarbij CSV-data wordt opgehaald via voorbeeld-URLs. Vervolgens wordt de data verwerkt tot Pandas DataFrames op een thread-veilige manier met behulp van een ThreadPoolExecutor. Dit is een vereenvoudigd voorbeeld, maar het laat de essentiële opzet zien.

Het is belangrijk op te merken dat, hoewel asyncio en Pandas niet direct communiceren, deze methode van het uitvoeren van het zware werk van Pandas in een aparte thread uw applicatie laat profiteren van asynchrone IO. Het aantal workers in de ThreadPoolExecutor moet worden aangepast aan de mogelijkheden van uw systeem, aangezien het creëren van te veel threads een negatief effect kan hebben op de prestaties.

Door deze hybride aanpak toe te passen in uw Python-ontwikkeling, combineert u de kracht van zowel asynchrone programmering als de sterke data-manipulatie van Pandas. Hoewel we Pandas zelf niet omtoveren tot een asynchrone bibliotheek, maken we het wel mogelijk om soepel binnen een asynchroon framework te passen.

Voor beginnende ontwikkelaars en data-analisten kan het beheersen van de details van zowel Pandas als de asynchrone IO van Python het verschil maken tussen een applicatie die gewoon werkt en een die excelleert in efficiëntie. Vergeet niet dat de asynchrone wereld vol valkuilen zit, test daarom elke stap grondig en houd uw oog op de evenementlus!

Pandas benutten voor machine learning-workflows

Na het verkennen van de vele mogelijkheden van Pandas voor geavanceerde datamanipulatie, prestatie-optimalisatie, en tijdreeksen, wil ik je aandacht vestigen op hoe deze krachtige bibliotheek samengaat met machine learning workflows.

In machine learning is datavoorbereiding een cruciale stap. Pandas blinkt hier echt in uit. Data schoonmaken, ontbrekende waarden aanpakken en feature engineering zijn slechts enkele voorbeelden waar Pandas een belangrijke rol speelt nog voordat je modellen gaat trainen.

Laten we beginnen met het importeren van de essentiële bibliotheken:

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

Stel dat je een dataset in een Pandas DataFrame hebt geladen. Je zou eerst eventuele ontbrekende waarden willen aanpakken:

# Voorbeeldcode om ontbrekende waarden aan te pakken
df.fillna(df.mean(), inplace=True)

Nadat de ontbrekende waarden zijn opgelost, neem je de volgende stap in het coderen van categorische variabelen indien aanwezig:

# Zet categorische kolom 'Category' om naar numerieke waarden
df['Category'] = df['Category'].astype('category').cat.codes

Voor je je data door een machine learning model stuurt, is het belangrijk om features te standaardiseren:

# Standaardiseren van de feature kolommen
scaler = StandardScaler()
df[['Feature1', 'Feature2']] = scaler.fit_transform(df[['Feature1', 'Feature2']])

Het splitsen van je dataset in trainings- en testsets wordt eenvoudig afgehandeld door sklearn’s train_test_split. Het is goed om te weten dat Pandas hier prima mee samenwerkt:

# Opmerking: Veronderstelt dat 'Label' de kolom is die je voorspelt
X = df.drop('Label', axis=1)
y = df['Label']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

Zoals je ziet, kan ik Pandas-structuren direct doorgeven aan de trainings- en testfuncties, wat het proces stroomlijnt. De meeste van sklearn’s API kan Pandas DataFrames en Series zonder problemen aan.

Feature selectie is een ander gebied waar Pandas zijn kracht toont. Stel dat je de correlatiematrix hebt berekend en hoog geassocieerde features wilt verwijderen:

# Bereken de correlatiematrix
corr_matrix = df.corr().abs()

# Selecteer de bovenste driehoek van de correlatiematrix
upper = corr_matrix.where(np.triu(np.ones(corr_matrix.shape), k=1).astype(np.bool))

# Vind features met correlatie groter dan 0.95
to_drop = [column for column in upper.columns if any(upper[column]  0.95)]

# Verwijder features
df.drop(to_drop, axis=1, inplace=True)

Wanneer je je model hebt getraind, kan Pandas ook helpen bij het evalueren van de resultaten. Stel dat je voorspellingen hebt gedaan, je kan deze naast de daadwerkelijke waarden zetten en direct vanuit de DataFrame de metriek berekenen:

from sklearn.metrics import accuracy_score

predictions = model.predict(X_test)
results = pd.DataFrame({'Actual': y_test, 'Predicted': predictions})
print(accuracy_score(results['Actual'], results['Predicted']))

Gedurende je machine learning pipeline, zal je merken dat Pandas intuïtieve, flexibele en efficiënte manieren biedt om je data te manipuleren. Van schoonmaken tot feature-extractie, en zelfs naar de postmodellering analyse – door Pandas omarmen tijdens de reis, kan het proces aanzienlijk soepeler verlopen.

Hoewel dit veel kan lijken voor een beginner, wil ik je verzekeren dat zodra je deze handelingen onder de knie hebt, ze als tweede natuur voelen in je data science praktijk. Onthoud, de sleutel is volharding en experimenteren met deze tools zal zich terugbetalen terwijl je dieper in machine learning projecten duikt.

Tot slot, door het benutten van de kracht van Pandas naast je machine learning algoritmen, optimaliseer je de voorbereidende fase van de pipeline, waardoor je je kunt richten op het bouwen en optimaliseren van geavanceerde modellen. De wisselwerking tussen data voorbereiding met Pandas en modelbouw is symbiotisch, waarbij elk het succes van de ander versterkt. Omarm deze technieken; ze zijn noodzakelijke hulpmiddelen in je data science arsenaal.


Delen

Opmerkingen (0)

Een reactie plaatsen

© 2023 - 2025 — TensorScience. Alle rechten voorbehouden.