Trasformare dati per gruppo

Trasformazione dei dati con Polars

Liam Brannigan

Data Scientist & Polars Contributor

Perché confrontare con statistiche di gruppo?

Serie temporale dei prezzi dell’elettricità in un giorno

  • I prezzi sono sopra o sotto la norma?
Trasformazione dei dati con Polars

Perché confrontare con statistiche di gruppo?

Serie temporale dei prezzi dell’elettricità in un giorno con le medie orarie

Trasformazione dei dati con Polars

Perché confrontare con statistiche di gruppo?

Serie temporale dei prezzi dell’elettricità in un giorno con medie orarie e annotazione che evidenzia prezzi bassi a mezzogiorno

Trasformazione dei dati con Polars

Perché confrontare con statistiche di gruppo?

Serie temporale dei prezzi dell’elettricità in un giorno con medie orarie e annotazione che evidenzia prezzi normali la sera

Trasformazione dei dati con Polars

Estrarre l’ora

prices.with_columns(
    pl.col("time").dt.hour().alias("hour")
)
| time                | price | solar   | hour |
| ---                 | ---   | ---     | ---  |
| datetime[µs]        | f64   | f64     | i8   |
|---------------------|-------|-------  |------|
| 2025-07-05 10:00:00 | 2.3   | 419.0   | 10   |
| 2025-07-05 11:00:00 | 0.5   | 481.0   | 11   |
| 2025-07-05 12:00:00 | 0.0   | 462.0   | 12   |
Trasformazione dei dati con Polars

Finestra con .over()

prices.with_columns(
    pl.col("price").mean()
)
Trasformazione dei dati con Polars

Finestra con .over()

prices.with_columns(
    pl.col("price").mean().over("hour")
)
Trasformazione dei dati con Polars

Finestra con .over()

prices.with_columns(
    pl.col("price").mean().over("hour").alias("hourly_avg")
)
Trasformazione dei dati con Polars

Finestra con .over()

prices.with_columns(
    pl.col("price").mean().over("hour").alias("hourly_avg")
)
| time                | price | solar | hour | hourly_avg |
| ---                 | ---   | ---   | ---  | ---        |
| datetime[µs]        | f64   | f64   | i8   | f64        |
|---------------------|-------|-------|------|------------|
| 2025-07-05 10:00:00 | 2.3   | 419.0 | 10   | 49.6       |
| 2025-07-05 11:00:00 | 0.5   | 481.0 | 11   | 44.4       |
| 2025-07-05 12:00:00 | 0.0   | 462.0 | 12   | 39.5       |
Trasformazione dei dati con Polars

Creare una categoria meteo

  • Sole: solar > 400 W/m²
  • Nuvole: solar <= 400 W/m²
Trasformazione dei dati con Polars

Creare una categoria meteo

prices.with_columns(
    pl.when(pl.col("solar") > 400)
    .then(pl.lit("sunny"))
    .otherwise(pl.lit("cloudy"))

.alias("weather")
)
| time                | price | solar | weather |
| ---                 | ---   | ---   | ---     |
| datetime[µs]        | f64   | f64   | str     |
|---------------------|-------|-------|---------|
| 2025-07-05 10:00:00 | 2.3   | 419.0 | sunny   |
| 2025-07-06 10:00:00 | 80.5  | 181.0 | cloudy  |
| 2025-07-07 10:00:00 | 41.5  | 150.0 | cloudy  |
Trasformazione dei dati con Polars

Raggruppare per più colonne

prices.with_columns(
    pl.col("price").mean()
)
Trasformazione dei dati con Polars

Raggruppare per più colonne

prices.with_columns(
    pl.col("price").mean().over("hour", "weather")
)
Trasformazione dei dati con Polars

Raggruppare per più colonne

prices.with_columns(
    pl.col("price").mean().over("hour", "weather").alias("avg_by_hour_weather")
)
Trasformazione dei dati con Polars

Raggruppare per più colonne

prices.with_columns(
    pl.col("price").mean().over("hour", "weather").alias("avg_by_hour_weather")
)
| time                | price | hour | weather | avg_by_hour_weather |
| ---                 | ---   | ---  | ---     | ---                 |
| datetime[µs]        | f64   | i8   | str     | f64                 |
|---------------------|-------|------|---------|---------------------|
| 2025-07-05 10:00:00 | 2.3   | 10   | sunny   | 34.2                |
| 2025-07-06 10:00:00 | 80.5  | 10   | cloudy  | 58.0                |
| 2025-07-07 10:00:00 | 41.5  | 10   | cloudy  | 58.0                |
Trasformazione dei dati con Polars

Confrontare con la media del gruppo

prices.with_columns(
    (pl.col("price")                                     )

)
Trasformazione dei dati con Polars

Confrontare con la media del gruppo

prices.with_columns(
    (pl.col("price") - pl.col("price").mean().over("hour"))

)
Trasformazione dei dati con Polars

Confrontare con la media del gruppo

prices.with_columns(
    (pl.col("price") - pl.col("price").mean().over("hour"))
    .alias("diff_from_hourly_avg")
)
| time                | price | hour | diff_from_hourly_avg |
| ---                 | ---   | ---  | ---                  |
| datetime[µs]        | f64   | i8   | f64                  |
|---------------------|-------|------|----------------------|
| 2025-07-05 10:00:00 | 2.3   | 10   | -47.3                |
| 2025-07-06 10:00:00 | 25.1  | 10   | -24.5                |
| 2025-07-07 10:00:00 | 2.7   | 10   | -46.9                |
Trasformazione dei dati con Polars

Altre aggregazioni finestra

.over() funziona con molte aggregazioni:

  • .sum().over() - totali del gruppo
  • .max().over() - massimi del gruppo
  • .count().over() - dimensioni del gruppo
Trasformazione dei dati con Polars

Ayo berlatih!

Trasformazione dei dati con Polars

Preparing Video For Download...