Lösa dubbletter och nullvärden

Slutförd

Datakvalitetsproblem som duplicerade poster och nullvärden kan äventyra dina analys- och nedströmsprocesser. Oavsett om dubbletter uppstår från samtidiga datainläsningar eller nullvärden på grund av ofullständiga källdata, är det ett huvudansvar för datatekniker som arbetar i Azure Databricks att åtgärda dessa problem.

I den här lektionen får du lära dig hur du identifierar och löser duplicerade, saknade och null-värden med hjälp av både SQL- och PySpark-metoder.

Identifiera duplicerade poster

Innan du kan ta bort dubbletter måste du hitta dem. Dubbletter inträffar vanligtvis när samma post visas flera gånger i en tabell, ofta på grund av dataintegreringsproblem, upprepad inmatning eller samtidiga skrivåtgärder.

Diagram som förklarar hur du identifierar duplicerade poster.

Använd GROUP BY och HAVING för att hitta dubbletter

Det enklaste sättet att identifiera dubbletter är genom att gruppera poster och räkna förekomster. Satsen HAVING filtrerar de grupperade resultaten så att endast värden som visas mer än en gång visas.

SELECT 
    customer_id, 
    email, 
    COUNT(*) AS occurrence_count
FROM sales.customers
GROUP BY customer_id, email
HAVING COUNT(*) > 1
ORDER BY occurrence_count DESC;

Den här frågan returnerar alla kombinationer av customer_id och email som visas flera gånger i tabellen, vilket hjälper dig att förstå omfånget för duplicering.

Använd KVALIFICERA med fönsterfunktioner

Klausulen QUALIFY ger en enklare metod genom att filtrera resultatet av fönsterfunktioner direkt, utan att kräva underfrågor. Den här metoden är särskilt användbar när du behöver se de faktiska duplicerade raderna, inte bara antalet.

SELECT *
FROM sales.customers
QUALIFY COUNT(*) OVER (PARTITION BY customer_id, email) > 1;

Den här frågan kan returnera resultat som:

customer_id Mejladress name skapad_tid status
1001 jane@contoso.com Jane Doe 2024-01-15 Active
1001 jane@contoso.com Jane D. 2024-03-20 Active
1002 bob@fabrikam.com Bob Smith 2024-02-10 Avvaktan
1002 bob@fabrikam.com Robert Smith 2024-02-11 Active

Med det här mönstret får du alla kolumner från de duplicerade raderna, vilket gör det lättare att undersöka källan för duplicering.

Hitta dubbletter med PySpark

I PySpark kan du använda fönsterfunktioner i kombination med filtrering för att identifiera dubbletter av poster:

from pyspark.sql.functions import count
from pyspark.sql.window import Window

window_spec = Window.partitionBy("customer_id", "email")

duplicates_df = (
    df.withColumn("row_count", count("*").over(window_spec))
    .filter("row_count > 1")
    .drop("row_count")
)

display(duplicates_df)

Du kan också använda exceptAll() metoden för att jämföra den ursprungliga DataFrame med en deduplicerad version:

df_duplicates = df.exceptAll(df.dropDuplicates(["customer_id", "email"]))
display(df_duplicates)

Metoden exceptAll() utför en uppsättningsskillnad som bevarar dubbletter. Den returnerar alla rader från den första DataFrame som inte finns i den andra dataramen och behåller duplicerade förekomster. Så här fungerar det:

  1. df.dropDuplicates(["customer_id", "email"]) skapar en DataFrame med en rad per unik kombination
  2. exceptAll() jämför den ursprungliga DataFrame med den här deduplicerade versionen
  3. För varje unik kombination "matchas" en förekomst och tas bort, vilket endast lämnar kvar de överflödiga dubbletterna.

Om kund 1001 till exempel visas tre gånger i den ursprungliga DataFrame och en gång i den deduplicerade versionen exceptAll() returnerar två rader (de extra förekomsterna).

Anmärkning

Till skillnad från except(), som tar bort alla matchande rader och returnerar distinkta resultat, exceptAll() bevarar dubblettstrukturen. Om du har tre identiska rader i originalet och en i den deduplicerade uppsättningen exceptAll() returnerar exakt två rader.

Ta bort dubblettposter

När du har identifierat dubbletter kan du välja en lösningsstrategi baserat på dina datakrav.

Ett diagram som visar hur du tar bort dubblettposter.

Ta bort dubbletter i PySpark

Metoden dropDuplicates() tar bort dubblettrader baserat på angivna kolumner och behåller en rad för varje kombination. När raderna skiljer sig åt i andra kolumner garanteras inte den rad som finns kvar:

df_clean = df.dropDuplicates(["customer_id", "email"])

För fullständig raddeduplicering i alla kolumner använder du distinct():

df_unique = df.distinct()

Behåll specifika rader med hjälp av ROW_NUMBER

När du behöver kontroll över vilken dubblett du vill behålla, använder du ROW_NUMBER() med QUALIFY för att välja poster baserat på kriterier såsom den senaste uppdateringen:

SELECT *
FROM sales.customers
QUALIFY ROW_NUMBER() OVER (
    PARTITION BY customer_id 
    ORDER BY updated_at DESC
) = 1;

Den här frågan partitionerar poster efter customer_id, sorterar dem efter updated_at i fallande ordning och behåller endast den senast uppdaterade posten för varje kund.

Hantera null- och saknade värden

Null-värden representerar saknade eller okända data. Beroende på dina analyskrav kan du behöva ta bort rader med nullvärden, ersätta dem med standardvärden eller använda statistisk imputation.

Diagram som förklarar hur du hanterar null- och saknade värden.

Identifiera null-värden

isnull() Använd funktionen eller IS NULL operatorn för att hitta poster med saknade värden:

SELECT *
FROM sales.transactions
WHERE amount IS NULL 
   OR customer_id IS NULL;

Så här räknar du null-förekomster per kolumn:

SELECT 
    COUNT(*) AS total_rows,
    COUNT(*) - COUNT(amount) AS null_amount_count,
    COUNT(*) - COUNT(customer_id) AS null_customer_count
FROM sales.transactions;

Ta bort rader med null-värden

I PySpark dropna() tar metoden bort rader som innehåller null-värden:

# Drop rows where any column is null
df_clean = df.dropna()

# Drop rows where all columns are null
df_clean = df.dropna(how="all")

# Drop rows where specific columns are null
df_clean = df.dropna(subset=["customer_id", "amount"])

Parametern how styr beteendet: "any" tar bort rader med minst en null (standard), medan "all" endast rader tas bort när alla angivna kolumner är null.

Fyll null-värden med standardvärden

Metoden fillna() ersätter null-värden med angivna standardvärden:

# Fill null values with a single value (applies only to columns whose data type matches)
df_filled = df.fillna(0)

# Fill specific columns with different values
df_filled = df.fillna({
    "amount": 0,
    "status": "Unknown",
    "quantity": 1
})

I SQL använder du COALESCE funktionen för att ange standardvärden:

SELECT 
    customer_id,
    COALESCE(amount, 0) AS amount,
    COALESCE(status, 'Unknown') AS status
FROM sales.transactions;

Välj rätt strategi

Lämplig strategi för null-hantering beror på din datakontext:

Scenario Rekommenderad metod
Nullvärden i obligatoriska fält som identifierare Släpp raderna
Null i numeriska fält för aggregering Fyll med noll eller medelvärde
Null i valfria kategorifält Fyll med platshållare som "Okänd"
Null-värden som skulle förvränga analysen Släpp eller fyll baserat på domänkunskap

Tips/Råd

Dokumentera dina beslut om hantering av null-värden. Framtida analytiker måste förstå varför vissa värden har ersatts eller tagits bort för att korrekt tolka frågeresultat.

Om du förstår hur du identifierar och löser dessa problem med datakvaliteten kan du skapa mer tillförlitliga datapipelines. Med rena data ger dina nedströmstransformeringar och analyser tillförlitliga resultat.