Manglende verdier er vanlige og oppstår enten på grunn av menneskelig feil, instrumentfeil, behandling fra et annet team, eller på annen måte bare mangel på data for en bestemt observasjon.
I denne byten skal vi ta en titt på hvordan du fyller NaNs i en
DataFrame
, hvis du velger å håndtere NaNs ved å fylle dem.
Først av alt, la oss lage en hån DataFrame
med noen tilfeldige verdier falt ut:
import numpy as np
array = np.random.randn(25, 3)
mask = np.random.choice([1, 0], array.shape, p=[.3, .7]).astype(bool)
array[mask] = np.nan
df = pd.DataFrame(array, columns=['Col1', 'Col2', 'Col3'])
Col1 Col2 Col3
0 -0.671603 -0.792415 0.783922
1 0.207720 NaN 0.996131
2 -0.892115 -1.282333 NaN
3 -0.315598 -2.371529 -1.959646
4 NaN NaN -0.584636
5 0.314736 -0.692732 -0.303951
6 0.355121 NaN NaN
7 NaN -1.900148 1.230828
8 -1.795468 0.490953 NaN
9 -0.678491 -0.087815 NaN
10 0.755714 0.550589 -0.702019
11 0.951908 -0.529933 0.344544
12 NaN 0.075340 -0.187669
13 NaN 0.314342 -0.936066
14 NaN 1.293355 0.098964
La oss plotte, si, den tredje kolonnen:
plt.plot(df['Col3'])
Når den er fylt med ulike teknikker – kan denne NaN-fylte grafen erstattes med:
fillna() – Gjennomsnitt, median, modus
Du kan fylle disse verdiene inn i en ny kolonne og tilordne den til kolonnen du ønsker å fylle, eller på plass ved å bruke inplace
argument. Her vil vi trekke ut de utfylte verdiene i en ny kolonne for enkel inspeksjon:
mean = df['Col3'].fillna(df['Col3'].mean(), inplace=False)
median = df['Col3'].fillna(df['Col3'].median(), inplace=False)
mode = df['Col3'].fillna(df['Col3'].mode(), inplace=False)
Median, gjennomsnitt og modus for kolonnen er -0.187669
, -0.110873
og 0.000000
og disse verdiene vil bli brukt for hver NaN henholdsvis. Dette er effektivt å fylle med konstante verdier, der verdien som legges inn avhenger av kolonnen.
For det første resulterer fylling med medianverdier i:
Med middelverdier:
Med modusverdier:
fillna() – konstant verdi
Du kan også fylle med en konstant verdi i stedet:
Sjekk ut vår praktiske, praktiske guide for å lære Git, med beste praksis, bransjeaksepterte standarder og inkludert jukseark. Slutt å google Git-kommandoer og faktisk lære den!
constant = df['Col3'].fillna(0, inplace=False
Dette resulterer i at en konstant verdi (0) settes i stedet for hver NaN. 0
er nær vår median og gjennomsnitt og lik modusen, så de fylte verdiene vil ligne den metoden tett for vårt falske datasett:
0 0.783922
1 0.996131
2 0.000000
3 -1.959646
4 -0.584636
5 -0.303951
6 0.000000
7 1.230828
8 0.000000
9 0.000000
10 -0.702019
11 0.344544
12 -0.187669
13 -0.936066
14 0.098964
fillna() – Forover og bakover fyll
På hver rad – du kan fylle forover eller bakover, og ta verdien enten fra raden før eller etter:
ffill = df['Col3'].fillna(method='ffill')
bfill = df['Col3'].fillna(method='bfill')
Med foroverfylling, siden vi mangler fra rad 2 – blir verdien fra rad 1 tatt for å fylle den andre. Verdiene forplanter seg fremover:
0 0.783922
1 0.996131
2 0.996131
3 -1.959646
4 -0.584636
5 -0.303951
6 -0.303951
7 1.230828
8 1.230828
9 1.230828
10 -0.702019
11 0.344544
12 -0.187669
13 -0.936066
14 0.098964
Med bakoverfylling skjer det motsatte. Rad 2 er fylt med verdien fra rad 3:
0 0.783922
1 0.996131
2 -1.959646
3 -1.959646
4 -0.584636
5 -0.303951
6 1.230828
7 1.230828
8 -0.702019
9 -0.702019
10 -0.702019
11 0.344544
12 -0.187669
13 -0.936066
14 0.098964
Skjønt, hvis det er mer enn én NaN
i en sekvens – disse vil ikke gjøre det bra og kan kaskade NaN lenger ned, skjeve dataene og fjerne faktisk registrerte verdier.
interpolere()
De interpolate()
metoden delegerer interpolering av verdier til SciPy's en rekke metoder for å interpolere verdier. Den aksepterer en lang rekke argumenter, inkludert, nearest
, zero
, slinear
, quadratic
, cubic
, spline
, barycentric
, polynomial
, krogh
, piecewise_polynomial
, spline
, pchip
, akima
, cubicspline
Osv
Interpolering er mye mer fleksibelt og "smart" enn å bare fylle verdier med konstanter eller halvvariabler som tidligere metoder.
Interpolering kan fylle en sekvens på en måte som ingen andre metoder kan, for eksempel:
s = pd.Series([0, 1, np.nan, np.nan, np.nan, 5])
s.fillna(s.mean()).values
s.fillna(method='ffill').values
s.interpolate().values
Standardinterpolasjonen er lineær, og forutsatt det 1...5
er sannsynligvis en 1, 2, 3, 4, 5
sekvensen er ikke langsøkt (men er ikke garantert). Både konstant fylling og forover- eller bakoverfylling mislykkes her. Generelt sett vil interpolering vanligvis være en god venn når det kommer til å fylle NaN-er i støyende signaler, eller korrupte datasett.
Eksperimentering med typer interpolering kan gi bedre resultater.
Her er to interpolasjonsmetoder (splice
og polynomial
krever en order
argument):
nearest = df['Col3'].interpolate(method='nearest')
polynomial = df['Col3'].interpolate(method='polynomial', order=3)
Disse resulterer i:
Og: