Pandas & NumPy Academy · Lekcja

Interpolacja i zaawansowane uzupełnianie

Użyj interpolate() do płynnego uzupełniania danych zależnych od czasu i dowiedz się, kiedy odpowiednie jest uzupełnianie średnią, a kiedy medianą.

Lekcja 4 z 413 kroki

Interpolacja i zaawansowane uzupełnianie to bezpłatna lekcja Pandas & NumPy Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Pandas & NumPy Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Pandas & NumPy Academy zawiera 4 lekcji w sumie.

Kiedy interpolacja jest lepsza niż fillna()

Uzupełnianie w przód i wstecz przenosi najbliższą znaną wartość bez uwzględniania trendu danych. Interpolacja szacuje brakujące wartości, zakładając płynne przejście między znanymi wartościami — na przykład jeśli temperatura wynosiła 20°C w poniedziałek i 30°C w piątek, interpolacja oszacuje 25°C w środę. Zapewnia to bardziej realistyczną imputację w przypadku płynnie zmieniających się sygnałów, takich jak dane z czujników, ceny lub liczebność populacji.

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'day': [1, 2, 3, 4, 5],
    'temp': [20.0, np.nan, np.nan, np.nan, 30.0]
})

# Linear interpolation fills gaps smoothly
df['temp_interp'] = df['temp'].interpolate(method='linear')
print(df)
#    day  temp  temp_interp
# 0    1  20.0         20.0
# 1    2   NaN         22.5
# 2    3   NaN         25.0
# 3    4   NaN         27.5
# 4    5  30.0         30.0

Metody interpolate()

Metoda Pandas interpolate() obsługuje wiele metod. Najczęściej używane to 'linear' (wartości rozmieszczone równomiernie między znanymi wartościami), 'time' (uwzględnia nierówne odstępy czasu, gdy ustawiono DatetimeIndex), 'polynomial' (dopasowuje krzywą wielomianową i wymaga argumentu order) oraz 'spline' (wygładzony wielomian odcinkowy). Metoda liniowa jest najbezpieczniejszym wyborem domyślnym; metody wyższych rzędów mogą prowadzić do nadmiernego dopasowania w przypadku małych luk.

import pandas as pd
import numpy as np

s = pd.Series([0, np.nan, np.nan, 8.0])

print('linear:', s.interpolate('linear').tolist())
# [0.0, 2.6666..., 5.3333..., 8.0]

print('polynomial(2):', s.interpolate('polynomial', order=2).tolist())
# [0.0, 2.222..., 5.111..., 8.0]

Interpolacja time z użyciem DatetimeIndex

Gdy obiekt Series ma DatetimeIndex z nierównymi odstępami czasu (np. obejmuje tylko dni robocze i pomija weekendy), method='time' interpoluje proporcjonalnie do rzeczywiście upływającego czasu, a nie tylko na podstawie pozycji. Jest to dokładniejsze niż interpolacja liniowa, która traktuje każdy wiersz jako równomiernie rozmieszczony, niezależnie od przerwy w kalendarzu.

import pandas as pd
import numpy as np

# Unequal gaps: Jan 1, Jan 3, Jan 10
idx = pd.to_datetime(['2024-01-01', '2024-01-03', '2024-01-10'])
s = pd.Series([100.0, np.nan, 170.0], index=idx)

# linear treats gaps as equal (position-based)
print(s.interpolate('linear').tolist())  # [100.0, 135.0, 170.0]

# time accounts for actual day count
# Jan 1 to Jan 3 = 2 days, Jan 1 to Jan 10 = 9 days
# fraction: 2/9 of the way from 100 to 170
print(s.interpolate('time').tolist())   # [100.0, 115.55..., 170.0]

Ograniczanie zakresu interpolacji

Podobnie jak ffill(), interpolate() przyjmuje parametr limit, który ogranicza liczbę kolejnych pozycji NaN podlegających uzupełnieniu. Pozostałe wartości NaN po przekroczeniu limitu pozostają brakujące. Zapobiega to interpolowaniu przez bardzo długie przerwy, w których rzeczywista wartość mogłaby być dowolna — długie przerwy należy oznaczyć do ręcznej weryfikacji.

import pandas as pd
import numpy as np

s = pd.Series([1.0, np.nan, np.nan, np.nan, np.nan, 10.0])

# Only fill the first 2 NaN positions
filled = s.interpolate('linear', limit=2)
print(filled.tolist())
# [1.0, 2.8, 4.6, NaN, NaN, 10.0]

Wybór imputacji średnią lub medianą

Imputacja średnią i medianą jest prosta, ale wiąże się z istotnymi kompromisami. Średnia jest wrażliwa na wartości odstające — kilka bardzo dużych wartości podnosi jej poziom, przez co jest ona kiepskim uzupełnieniem dla rozkładu prawoskośnego, takiego jak rozkład dochodów lub cen nieruchomości. Mediana jest odporna na wartości odstające i stanowi lepszy wybór dla skośnych kolumn. Średniej należy używać tylko wtedy, gdy dane są w przybliżeniu symetryczne i nie zawierają skrajnych wartości odstających.

import pandas as pd
import numpy as np

# Skewed income data with an outlier
income = pd.Series([30000, 35000, 32000, 1_000_000, np.nan])

print('Mean:  ', income.mean())    # ~274000 — pulled by outlier
print('Median:', income.median())  # ~33500 — robust choice

# Prefer median for skewed data
filled = income.fillna(income.median())
print(filled.tolist())
# [30000, 35000, 32000, 1000000, 33500.0]

Koncepcja imputacji KNN

Imputacja metodą K-Nearest Neighbour (KNN) zastępuje brakującą wartość średnią (lub średnią ważoną) z k najbardziej podobnych wierszy, mierzonych odległością wzdłuż niebrakujących cech. Jest to strategia wielowymiarowa — wykorzystuje informacje z innych kolumn do określenia sposobu uzupełnienia, dzięki czemu przy skorelowanych cechach jest dokładniejsza niż imputacja średnią z pojedynczej kolumny.

Scikit-learn's KNNImputer integruje się bezpośrednio z tablicami NumPy i obiektami DataFrame biblioteki Pandas.

import pandas as pd
import numpy as np
from sklearn.impute import KNNImputer

df = pd.DataFrame({
    'age': [25, 35, np.nan, 45],
    'income': [50000, 70000, 60000, np.nan]
})

imputer = KNNImputer(n_neighbors=2)
df_imputed = pd.DataFrame(
    imputer.fit_transform(df),
    columns=df.columns
)
print(df_imputed.round(1))
#     age   income
# 0  25.0  50000.0
# 1  35.0  70000.0
# 2  30.0  60000.0   <- filled from neighbours
# 3  45.0  65000.0   <- filled from neighbours

Wielokrotna imputacja za pomocą IterativeImputer

Wielokrotna imputacja jest uznawana za najlepszą metodę obsługi brakujących danych w badaniach statystycznych. Narzędzie Scikit-learn IterativeImputer implementuje podejście MICE (Multiple Imputation by Chained Equations): modeluje każdą kolumnę zawierającą braki jako funkcję pozostałych kolumn i iteracyjnie wykonuje imputację do momentu ustabilizowania się wartości. Dzięki temu lepiej odwzorowuje zależności między cechami niż strategie wykorzystujące pojedyncze kolumny.

import pandas as pd
import numpy as np
from sklearn.experimental import enable_iterative_imputer  # noqa
from sklearn.impute import IterativeImputer

df = pd.DataFrame({
    'x1': [1, 2, np.nan, 4, 5],
    'x2': [2, np.nan, 6, 8, 10],
    'y':  [3, 5, 7, np.nan, 11]
})

imp = IterativeImputer(max_iter=10, random_state=0)
df_filled = pd.DataFrame(imp.fit_transform(df), columns=df.columns)
print(df_filled.round(2))

Kolumny wskaźnikowe dla brakujących danych

Zamiast ukrywać fakt, że wartość została imputowana, dobrą praktyką jest dodanie binarniej kolumny wskaźnikowej, która oznacza wiersze zawierające brakujące wartości przed imputacją. Dzięki temu modele używane w dalszej części przetwarzania mogą uczyć się na podstawie samego wzorca braków — czasami informacja o tym, że wartości brakuje, ma taką samą moc predykcyjną jak sama wartość.

import pandas as pd
import numpy as np

df = pd.DataFrame({'salary': [50000, np.nan, 70000, np.nan, 90000]})

# Add indicator before filling
df['salary_was_missing'] = df['salary'].isna().astype(int)

# Then fill
df['salary'] = df['salary'].fillna(df['salary'].median())
print(df)
#    salary  salary_was_missing
# 0  50000.0                   0
# 1  70000.0                   1
# 2  70000.0                   0
# 3  70000.0                   1
# 4  90000.0                   0

Imputacja a wyciek danych

Kluczowa zasada w potokach uczenia maszynowego: statystyki używane do imputacji (średnią, medianę, dominantę) należy obliczać wyłącznie na zbiorze treningowym, a następnie stosować te same wartości do zbioru testowego. Obliczenie statystyk na całym zbiorze danych przed jego podziałem powoduje wyciek danych — model pośrednio widzi dane testowe podczas treningu, co zawyża szacowaną skuteczność. Zawsze należy dopasowywać imputery do danych treningowych, a następnie transformować zarówno zbiór treningowy, jak i testowy.

import pandas as pd
import numpy as np
from sklearn.impute import SimpleImputer
from sklearn.model_selection import train_test_split

df = pd.DataFrame({'feature': [1, 2, np.nan, 4, np.nan, 6, 7, 8]})
train, test = train_test_split(df, test_size=0.25, random_state=0)

# Fit ONLY on training data
imp = SimpleImputer(strategy='mean')
train['feature'] = imp.fit_transform(train[['feature']])

# Transform test using training statistics
test['feature'] = imp.transform(test[['feature']])
print('Train mean used:', imp.statistics_[0])

Wizualne porównywanie strategii imputacji

Po zastosowaniu wielu metod imputacji należy porównać ich wpływ, przedstawiając obok siebie rozkłady oryginalnych i imputowanych kolumn. Dobra imputacja powinna możliwie wiernie zachowywać kształt rozkładu oryginalnego (średnią, wariancję i skośność). Imputacja średnią zawęża rozkład, natomiast KNN i MICE zwykle lepiej go zachowują.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(0)
original = np.random.exponential(scale=5, size=200)
with_nan = original.copy()
with_nan[np.random.choice(200, 40, replace=False)] = np.nan

s = pd.Series(with_nan)

fig, axes = plt.subplots(1, 2, figsize=(10, 4))
s.dropna().hist(ax=axes[0], bins=20, title='Original (no NaN)')
s.fillna(s.mean()).hist(ax=axes[1], bins=20, title='Mean-imputed')
plt.tight_layout()
plt.savefig('imputation_comparison.png')
print('Saved comparison chart')

Wybór właściwej strategii imputacji

Nie istnieje jedna uniwersalnie najlepsza strategia imputacji — właściwy wybór zależy od kontekstu. Średnią lub medianę należy stosować w prostych przypadkach jednowymiarowych, przy niewielkiej liczbie braków. ffill/bfill sprawdza się w szeregach czasowych o stabilnych trendach. KNN lub IterativeImputer warto stosować, gdy cechy są skorelowane i chcą Państwo wykorzystać istniejące między nimi zależności. Stałe wartości wynikające z dziedziny (np. 0 dla braku, -1 dla wartości nieznanej) należy wybierać, gdy brakująca wartość ma jasne znaczenie biznesowe. Zawsze należy udokumentować swój wybór.

# Decision guide (no runnable code)
#
# Missing < 5%  AND data is MCAR?  -> Mean/median fill is fine
# Time series with stable trend?   -> ffill() with limit
# Features are correlated?         -> KNNImputer or IterativeImputer
# Categorical column?              -> Mode fill or 'Unknown' sentinel
# Going into ML model?             -> Add indicator column + fill
# Research / publication quality?  -> Multiple imputation (MICE)
print('Strategy selected based on context')

Szybkie sprawdzenie

Sprawdź swoją wiedzę na temat interpolacji i zaawansowanej imputacji.

Podsumowanie lekcji

W tej lekcji nauczyłeś się, że: interpolate() szacuje brakujące wartości, zakładając płynny trend między znanymi wartościami, method='time' obsługuje nierówne odstępy w DatetimeIndex, a zaawansowane strategie, takie jak KNNImputer i IterativeImputer, wykorzystują inne kolumny do określania sposobu uzupełniania. Przed imputacją zawsze należy dodać kolumny wskaźnikowe, a statystyki dopasowywać wyłącznie na zbiorze treningowym, aby uniknąć wycieku danych. W następnej części zajmiemy się sprawdzaniem i konwersją typów danych kolumn obiektu DataFrame.

Bezpłatny start

Ucz się Python dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
30
Lekcje
120

Często zadawane pytania

Czy lekcja „Interpolacja i zaawansowane uzupełnianie” jest bezpłatna?

Tak — pełny tekst „Interpolacja i zaawansowane uzupełnianie” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Pandas & NumPy Academy, przejdź na CoddyKit PRO. Kurs Pandas & NumPy Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Interpolacja i zaawansowane uzupełnianie”?

Użyj interpolate() do płynnego uzupełniania danych zależnych od czasu i dowiedz się, kiedy odpowiednie jest uzupełnianie średnią, a kiedy medianą. Ćwiczysz Pandas & NumPy Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Pandas & NumPy Academy?

Nie wymagamy żadnego doświadczenia. Pandas & NumPy Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Interpolacja i zaawansowane uzupełnianie”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Pandas & NumPy Academy?

Tak. Każda lekcja Pandas & NumPy Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Wykrywanie brakujących wartości
  2. Usuwanie brakujących wartości
  3. Uzupełnianie brakujących wartości
  4. Interpolacja i zaawansowane uzupełnianie
← Powrót do Pandas & NumPy Academy