Skip to content

PySpark Select, Filter e withColumn: Receitas Essenciais de DataFrame

Updated on

DataFrames desorganizados atrasam qualquer pipeline: colunas erradas, filtros inseguros e casts frágeis criam erros silenciosos. As equipes precisam de padrões repetíveis para selecionar, filtrar e derivar colunas, para manter os jobs Spark previsíveis.

As APIs select, filter/where e withColumn do PySpark resolvem isso ao manter as transformações explícitas, com tipos seguros e testáveis. Este guia mostra os principais padrões e como evitar armadilhas comuns.

Quer criar rapidamente Data Visualization a partir de um DataFrame do Python Pandas sem escrever código?

PyGWalker é uma biblioteca Python para Exploratory Data Analysis com Visualização. O PyGWalker (opens in a new tab) pode simplificar seu fluxo de análise e visualização de dados no Jupyter Notebook, transformando seu pandas dataframe (e polars dataframe) em uma interface de usuário alternativa ao Tableau para exploração visual.

PyGWalker for Data visualization (opens in a new tab)

Mapa para leitura

TarefaAPIQuando usar
Escolher/renomear colunasselect, aliasManter apenas as colunas necessárias; evite selectExpr quando for simples
Filtragem de linhasfilter / whereAmbas idênticas; encadeie condições com & e |
Colunas derivadas/condicionaiswithColumn, when/otherwiseAdicionar ou substituir colunas com lógica
Expressões estilo SQLselectExpr, exprAritmética rápida ou funções SQL sem muitos imports
Casting segurocast, try_cast (Spark 3.5+)Impor tipos sem lançar erro em valores ruins

Configuração e dados de exemplo

from pyspark.sql import SparkSession
from pyspark.sql import functions as F
 
spark = SparkSession.builder.appName("select-filter-withcolumn").getOrCreate()
 
df = spark.createDataFrame(
    [
        (1, "Alice", "2025-11-01", "premium", "42"),
        (2, "Bob",   "2025-11-02", "basic",   "x"),
        (3, "Cara",  "2025-11-02", None,      "7"),
    ],
    "id INT, name STRING, signup_date STRING, tier STRING, score STRING",
)

Selecione apenas o que você precisa

slim = df.select(
    "id",
    F.col("name").alias("customer_name"),
    F.to_date("signup_date").alias("signup_dt"),
)
  • select mantém as projeções explícitas e evita leituras amplas desnecessárias.
  • Use alias para nomes mais amigáveis.

Filter / where: APIs idênticas

active = slim.where(
    (F.col("signup_dt") >= "2025-11-01")
    & (F.col("customer_name") != "Bob")
)
  • filter e where são iguais; escolha uma por legibilidade.
  • Combine condições com & e |; coloque cada condição entre parênteses.
  • Verificações de nulo: isNull() / isNotNull() evitam surpresas.

withColumn para valores derivados e condicionais

scored = active.withColumn(
    "score_int",
    F.when(F.col("score").rlike("^[0-9]+$"), F.col("score").cast("int"))
     .otherwise(None),
)
  • withColumn adiciona ou substitui colunas; mantenha nomes únicos para evitar sobrescritas acidentais.
  • when/otherwise define uma lógica de ramificação clara.

selectExpr para expressões rápidas

expr_df = df.selectExpr(
    "id",
    "upper(name) AS name_upper",
    "to_date(signup_date) AS signup_dt",
    "CASE WHEN tier = 'premium' THEN 1 ELSE 0 END AS is_premium",
)
  • Útil para cálculos no estilo SQL sem muitos imports de functions.
  • Mantenha lógicas complexas em withColumn normal para melhor legibilidade e testes.

Padrões de casting seguro

typed = (
    df
    .withColumn("score_int", F.col("score").cast("int"))
    .withColumn("signup_ts", F.to_timestamp("signup_date"))
)
  • Prefira casts explícitos; evite depender de inferência de schema em fontes CSV.
  • No Spark 3.5+, try_cast retorna null em vez de falhar em valores inválidos.

Verificações rápidas de qualidade de dados

from pyspark.sql import functions as F
 
bad_counts = df.select(
    F.sum(F.col("score").rlike("^[0-9]+$").cast("int")).alias("valid_scores"),
    F.sum(F.col("score").rlike("^[^0-9]").cast("int")).alias("invalid_scores"),
)
  • Valide antes de escrever; agregações pequenas revelam problemas cedo.
  • Use count + isNull para medir taxas de ausência em colunas chave.

Armadilhas comuns e correções

  • Condições sem parênteses: sempre envolva cada cláusula booleana ao usar &/|.
  • Sobrescrita acidental de coluna: confira df.columns ou use novos nomes com withColumn.
  • Datas em string sem parsing: converta com to_date/to_timestamp antes de comparar.
  • Comparações sensíveis a null: use isNull/isNotNull para evitar surpresas de lógica de três valores.

Exemplo de pipeline mínimo

clean = (
    df
    .select("id", "name", "signup_date", "tier", "score")
    .where(F.col("tier").isNotNull())
    .withColumn("signup_dt", F.to_date("signup_date"))
    .withColumn(
        "score_int",
        F.when(F.col("score").rlike("^[0-9]+$"), F.col("score").cast("int")),
    )
)

Isso mantém as seleções enxutas, filtros explícitos e colunas derivadas tipadas antes das etapas posteriores de escrita.