Pandas & NumPy Academy · Lektion

Kategorisk datatyp

Konvertera strängkolumner med få unika värden till pandas Categorical för att minska minnesanvändningen och snabba upp groupby-operationer.

Lektion 3 av 413 steg

Kategorisk datatyp är en gratis lektion i Pandas & NumPy Academy på CoddyKit. Detta är lektion 3 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Pandas & NumPy Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Pandas & NumPy Academy innehåller totalt 4 lektioner.

Vad är dtype Categorical?

Dtypen Categorical i Pandas är utformad för kolumner som innehåller en begränsad uppsättning diskreta värden (låg kardinalitet), till exempel kön, status, region eller produktkategori. I stället för att lagra hela strängen för varje rad lagrar Pandas de unika värdena (så kallade categories) en gång och använder en heltalskod per rad för att referera till dem. Detta liknar hur databaser använder uppslagstabeller eller enum-typer.

import pandas as pd

df = pd.DataFrame({
    'region': ['North', 'South', 'East', 'North', 'East', 'South'] * 1000
})

# Without Categorical: object dtype stores every string
print('object dtype memory:', df['region'].memory_usage(deep=True))

# With Categorical: only stores 3 unique values + integer codes
df['region_cat'] = df['region'].astype('category')
print('category dtype memory:', df['region_cat'].memory_usage(deep=True))

Skapa en Categorical Series

Konvertera en kolumn till Categorical genom att anropa .astype('category') på valfri Series. Den resulterande Categorical Series lagrar de unika värdena som .cat.categories och heltalskoderna för positionerna som .cat.codes. Du kan också skapa en Categorical direkt med pd.Categorical() för att ange kategorierna och deras ordning från början.

import pandas as pd

s = pd.Series(['low', 'high', 'med', 'high', 'low'])
s_cat = s.astype('category')

print(s_cat.cat.categories)  # Index(['high', 'low', 'med'], dtype='object')
print(s_cat.cat.codes)       # integer codes per row
# 0    1
# 1    0
# 2    2
# 3    0
# 4    1

Minnesbesparingar med Categorical

Minnesbesparingarna med dtype Categorical beror på kardinalitetskvoten (unika värden ÷ totalt antal rader). Med 5 unika strängar i en kolumn med 1 000 000 rader lagrar dtypen object 1 miljon strängpekare (cirka 50+ byte vardera), medan Categorical endast lagrar 5 strängar plus 1 miljon 8-bitars heltal. Besparingen kan bli 5–20 gånger, så att en kolumn på 50 MB minskar till 2–5 MB.

import pandas as pd
import numpy as np

n = 1_000_000
statuses = np.random.choice(['active', 'inactive', 'pending'], size=n)
df = pd.DataFrame({'status': statuses})

object_mem = df['status'].memory_usage(deep=True) / 1e6
df['status'] = df['status'].astype('category')
cat_mem = df['status'].memory_usage(deep=True) / 1e6

print(f'Object dtype:    {object_mem:.1f} MB')
print(f'Category dtype:  {cat_mem:.1f} MB')
print(f'Reduction:       {object_mem/cat_mem:.1f}x')

Ordnad Categorical för rangordning

Ibland har kategorier en naturlig ordning – till exempel 'low' < 'medium' < 'high' eller T-shirtstorlekarna XS < S < M < L < XL. En ordnad Categorical fångar denna rangordning, möjliggör meningsfulla jämförelseoperatorer (<, >= och så vidare) och säkerställer att groupby-resultat sorteras i rätt semantisk ordning i stället för alfabetiskt.

import pandas as pd

df = pd.DataFrame({
    'priority': ['high', 'low', 'medium', 'high', 'low']
})

priority_type = pd.CategoricalDtype(
    categories=['low', 'medium', 'high'],
    ordered=True
)
df['priority'] = df['priority'].astype(priority_type)

# Comparison now works correctly
print(df['priority'] >= 'medium')
# 0     True
# 1    False
# 2     True
# 3     True
# 4    False

Sortera ordnade Categorical-värden

När du sorterar en ordnad Categorical-kolumn använder Pandas den definierade kategoriordningen i stället för alfabetisk ordning. Det innebär att 'low' kommer före 'medium', som kommer före 'high', oavsett hur de skulle sorteras som strängar. Detta är avgörande för att skapa korrekt ordnade sammanfattningstabeller och diagram.

import pandas as pd

df = pd.DataFrame({
    'severity': pd.Categorical(
        ['high', 'low', 'medium', 'low', 'high'],
        categories=['low', 'medium', 'high'],
        ordered=True
    ),
    'count': [5, 20, 8, 15, 3]
})

# sort_values respects the categorical order
print(df.sort_values('severity')[['severity', 'count']])
#   severity  count
# 1      low     20
# 3      low     15
# 2   medium      8
# 0     high      5
# 4     high      3

GroupBy-hastighet med Categorical

Pandas kan optimera groupby()-operationer på Categorical-kolumner eftersom alla möjliga grupper är kända i förväg. Det kan göra groupby 2–5 gånger snabbare på stora DataFrame-objekt. Dessutom returnerar groupby alla kategorier, inklusive tomma kategorier, vilket säkerställer att sammanfattningstabeller alltid innehåller en rad för varje förväntad grupp, även om vissa har noll observationer.

import pandas as pd
import numpy as np

np.random.seed(0)
df = pd.DataFrame({
    'region': pd.Categorical(
        np.random.choice(['North', 'South', 'East', 'West'], 10),
        categories=['North', 'South', 'East', 'West']
    ),
    'sales': np.random.randint(100, 1000, 10)
})

# observed=False shows ALL categories even empty ones
print(df.groupby('region', observed=False)['sales'].sum())

Lägga till och ta bort kategorier

Använd accessorn .cat för att hantera kategorilistan. .cat.add_categories() lägger till nya tillåtna värden, vilket är användbart innan nya data infogas, och .cat.remove_unused_categories() tar bort kategorietiketter som inte har några motsvarande rader, vilket är praktiskt efter filtrering. Du kan inte tilldela ett värde som inte finns bland kategorierna utan att först lägga till det.

import pandas as pd

s = pd.Categorical(['a', 'b', 'a'], categories=['a', 'b', 'c'])
s = pd.Series(s)

print(s.cat.categories)  # Index(['a', 'b', 'c'], dtype='object')
print(s.value_counts())  # a:2, b:1, c:0

# Remove unused category 'c'
s = s.cat.remove_unused_categories()
print(s.cat.categories)  # Index(['a', 'b'], dtype='object')

Byta namn på kategorietiketter

.cat.rename_categories() låter dig ändra kategorietiketter utan att ändra de underliggande koderna. Det är användbart när du vill visa tydligare namn, till exempel 'M' → 'Male', eller korrigera inkonsekvent användning av versaler i etiketter utan att konvertera tillbaka till object och mappa om. Metoden accepterar en lista (positionsbaserad) eller en ordlista (målinriktad).

import pandas as pd

s = pd.Series(pd.Categorical(['M', 'F', 'M', 'F'], categories=['M', 'F']))

# Rename using a dict
s = s.cat.rename_categories({'M': 'Male', 'F': 'Female'})
print(s)
# 0      Male
# 1    Female
# 2      Male
# 3    Female
print(s.cat.categories)  # Index(['Male', 'Female'], dtype='object')

När Categorical INTE bör användas

Datatypen Categorical är ett dåligt val när kardinaliteten är hög – om nästan varje rad har ett unikt värde, som användar-ID:n, fritextkommentarer eller UUID:er, är kategoriindexet nästan lika stort som originaldata och ger ingen minnesbesparing. En tumregel är att endast använda Categorical när antalet unika värden är mindre än ungefär 50 % av det totala antalet rader, särskilt när antalet unika värden ligger i tiotals eller hundratals.

import pandas as pd
import numpy as np

df = pd.DataFrame({'user_id': range(1_000_000)})

# High-cardinality: every value is unique — don't use Categorical
object_mem = df['user_id'].astype(str).memory_usage(deep=True) / 1e6
cat_mem = df['user_id'].astype(str).astype('category').memory_usage(deep=True) / 1e6

print(f'String: {object_mem:.1f} MB')
print(f'Category: {cat_mem:.1f} MB')
# Category is WORSE for high-cardinality data!

Categorical i pivottabeller och Groupby

Genom att använda Categorical säkerställs en konsekvent resultatstruktur i resultat från groupby och pivottabeller. Utan Categorical utelämnas grupper som råkar ha noll observationer tyst från resultatet, vilket kan orsaka feljusterade resultat när olika dataurval jämförs. Med Categorical och observed=False visas alltid alla grupper i resultatet.

import pandas as pd

df = pd.DataFrame({
    'quarter': pd.Categorical(
        ['Q1', 'Q1', 'Q3'],
        categories=['Q1', 'Q2', 'Q3', 'Q4']
    ),
    'revenue': [100, 200, 300]
})

# observed=False includes Q2 and Q4 even though they have no rows
result = df.groupby('quarter', observed=False)['revenue'].sum()
print(result)
# quarter
# Q1    300
# Q2      0
# Q3    300
# Q4      0

Categorical och maskininlärning

Många estimatorer i scikit-learn förväntar sig numerisk indata. Om du vill konvertera en Categorical-kolumn till tal för en modell använder du .cat.codes (etikettkodning) eller pd.get_dummies() (one-hot-kodning). One-hot-kodning undviker att antyda ett ordningsförhållande mellan kategorierna. För ordnade kategorier, som prioritetsnivåer, är etikettkodning (de direkta koderna) lämplig och bevarar ordningsinformationen.

import pandas as pd

df = pd.DataFrame({
    'colour': pd.Categorical(['red', 'blue', 'green', 'red'])
})

# One-hot encode for unordered categories
one_hot = pd.get_dummies(df['colour'], prefix='colour')
print(one_hot)
#    colour_blue  colour_green  colour_red
# 0            0             0           1
# 1            1             0           0
# 2            0             1           0
# 3            0             0           1

<p>Testa din förståelse av datatypen Categorical.</p>

Testa din förståelse av datatypen Categorical.

Lektionssammanfattning

I den här lektionen har du lärt dig att datatypen Categorical lagrar unika värden en gång och använder heltalskoder per rad, vilket ger stora minnesbesparingar för kolumner med låg kardinalitet, att ordnad Categorical stöder meningsfulla jämförelser och korrekt sortering, samt att groupby med observed=False inkluderar alla kategorier, även tomma. Undvik Categorical för kolumner med hög kardinalitet. Nästa steg är att tolka datumsträngar korrekt med pd.to_datetime().

Gratis att börja

Lär dig Python med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
30
Lektioner
120

Vanliga frågor

Är lektionen ”Kategorisk datatyp” gratis?

Ja – hela texten till ”Kategorisk datatyp” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Pandas & NumPy Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Pandas & NumPy Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Kategorisk datatyp”?

Konvertera strängkolumner med få unika värden till pandas Categorical för att minska minnesanvändningen och snabba upp groupby-operationer. Ni övar på Pandas & NumPy Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Pandas & NumPy Academy?

Du behöver inga förkunskaper. Utbildningen i Pandas & NumPy Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.

Hur lång tid tar lektionen ”Kategorisk datatyp”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Pandas & NumPy Academy-lektionen?

Ja. Varje Pandas & NumPy Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Inspektera kolumnernas datatyper
  2. Typkonvertering med astype()
  3. Kategorisk datatyp
  4. Tolka datum korrekt
← Tillbaka till Pandas & NumPy Academy