El mòdul 10 va acabar amb un avís: en obrir Papyrus al món, la web va començar a generar dades. Cada venda que la Marta registra, cada cerca que la Júlia tecleja, cada visita a una fitxa de llibre deixa rastre. I amb el rastre van arribar les preguntes de l'Anna: quins títols es consulten molt però es compren poc?, quin dia de la setmana ven més?, quant estoc convé demanar de cara a Sant Jordi? Cap d'aquestes preguntes no es respon programant la botiga: es responen entenent-ne els números. Aquest ofici es diu ciència de dades, i aquest mòdul et dona les seves tres eines fonamentals — NumPy, pandas i Matplotlib — més una primera mirada honesta a l'aprenentatge automàtic. Aquesta lliçó prepara el terreny: què és (i què no és) la ciència de dades, com s'hi treballa, quines peces formen l'ecosistema i amb quin dataset respondrem les preguntes de l'Anna.

Contingut

  1. Què és la ciència de dades (i què no és)
  2. El flux de treball: de la pregunta a la conclusió
  3. Els rols de l'ofici: analista, científic i enginyer de dades
  4. L'ecosistema PyData: quina peça fa què
  5. Jupyter Notebook: l'entorn habitual de l'anàlisi
  6. El dataset del mòdul: vendes_2026.csv
  7. El que ja saps fer: statistics i els seus límits

Què és la ciència de dades (i què no és)

La ciència de dades és la disciplina d'extreure coneixement útil de les dades per respondre preguntes i prendre decisions. Combina tres ingredients que, per separat, ja coneixes o intueixes:

  • Programació — per llegir, transformar i automatitzar. És el que portes 10 mòduls fent.
  • Estadística — per resumir, comparar i no enganyar-se amb l'atzar.
  • Coneixement del negoci — l'Anna sap que Sant Jordi (23 d'abril) és el seu pic anual; cap algorisme no ho sap si ningú no li ho explica.

Igual d'important és el que no és:

Mite Realitat
"És fer gràfics bonics" El gràfic és el final; el 80% de la feina és aconseguir i netejar dades
"És intel·ligència artificial" El ML és una eina més (la veurem a 11-05); la majoria de preguntes es responen comptant i agrupant bé
"Necessites big data" Papyrus té centenars de files, no milions, i tot i així hi ha decisions valuoses a prendre
"És màgia predictiva" Un model només projecta patrons del passat; si el futur canvia (una pandèmia, una moda), el model no ho veu venir

El flux de treball: de la pregunta a la conclusió

Tota anàlisi seriosa recorre el mateix camí, i convé tenir-lo al davant abans d'escriure una línia de codi. Amb les preguntes de Papyrus com a exemple:

flowchart LR
    A["1. Pregunta<br>Quant estoc demanar<br>per a Sant Jordi?"] --> B["2. Dades<br>vendes_2026.csv<br>logs de la web (M10)"]
    B --> C["3. Neteja<br>files corruptes,<br>duplicats, forats"]
    C --> D["4. Exploració<br>agrupar, resumir,<br>visualitzar"]
    D --> E["5. Conclusió o model<br>'demana ~220 unitats,<br>El Quixot el que més'"]
    E -.->|noves preguntes| A

Fixa't en la fletxa de tornada: explorar les dades gairebé sempre genera preguntes noves ("per què Faust es consulta tant i es ven tan poc?"), i el cicle torna a començar. No és una cadena de muntatge: és un bucle.

El repartiment del mòdul sobre aquest flux: la neteja i exploració són territori de pandas (11-03), la visualització de Matplotlib (11-04), el model de scikit-learn (11-05), i NumPy (11-02) és el motor numèric que els sosté tots.

Els rols de l'ofici

"Ciència de dades" és un paraigua. En una empresa real la feina es reparteix en (com a mínim) tres perfils; a Papyrus els tres són l'Anna amb barrets diferents:

Rol Pregunta típica A Papyrus Eines estrella
Analista de dades Què va passar i per què? "Quin dia venem més?" pandas, SQL, Matplotlib
Científic de dades Què passarà? Quina decisió prenc? "Quantes unitats demanar a l'abril?" pandas, scikit-learn, estadística
Enginyer de dades Com arriben les dades netes i a temps? L'script que consolida vendes de botiga i web cada nit Python, pipelines (els teus generadors de M8!), bases de dades

Aquest mòdul et dona la base dels dos primers rols; del tercer ja en tens més del que et penses: llegir CSV (M6), pipelines amb generadors (M8) i una web que produeix dades (M10) és enginyeria de dades a petita escala.

L'ecosistema PyData

Totes aquestes peces s'instal·len amb pip al teu entorn virtual de M1 (pip install numpy pandas matplotlib scikit-learn). Cadascuna té un paper clar:

Mòdul Rol en el flux Lliçó
NumPy Arrays numèrics ràpids; el motor que tots els altres usen per sota 11-02
pandas Taules (DataFrames): carregar, netejar, agrupar, unir — el csv.DictReader de M6 amb esteroides 11-03
Matplotlib Gràfics: convertir números en històries que l'Anna entengui d'un cop d'ull 11-04
scikit-learn Aprenentatge automàtic: models que aprenen patrons de l'històric 11-05
Jupyter L'entorn interactiu on tot això s'explora còmodament aquí mateix

La dependència entre elles no és casual: pandas està construït sobre NumPy, Matplotlib dibuixa arrays de NumPy, i scikit-learn espera arrays de NumPy o DataFrames de pandas com a entrada. Per això el mòdul comença per NumPy encara que en el dia a dia escriguis sobretot pandas.

Jupyter Notebook, breument

L'anàlisi de dades és conversacional: proves una cosa, mires el resultat, ajustes, repeteixes. Els notebooks (quaderns) estan fets per a això: documents vius amb cel·les de codi que s'executen una a una, intercalades amb text i gràfics que queden desats al costat del codi.

pip install notebook
jupyter notebook   # obre el navegador a http://localhost:8888

A dins, cada cel·la s'executa amb Shift+Enter i el seu resultat apareix a sota — l'última expressió de la cel·la es mostra sola, sense print(). Quan usar cada format?

Situació Notebook (.ipynb) Script (.py)
Explorar dades, provar hipòtesis Ideal Incòmode (rellançar-ho tot cada vegada)
Informe amb codi, text i gràfics Ideal No aplica
Codi de producció (la web de M10, el paquet papyrus) Mala idea Ideal
Tests (M9), control de versions net Difícil de testejar i de diffejar Ideal
Executar cada nit automatitzat Possible però forçat Ideal

Tot el codi d'aquest mòdul funciona igual en un script .py — si prefereixes continuar amb el teu editor de sempre, endavant. El notebook és una comoditat, no un requisit. L'única diferència pràctica: en un script, per veure un DataFrame l'hauràs d'embolicar en un print().

El dataset del mòdul: vendes_2026.csv

A M6 vas crear dades/vendes.csv (columnes data,titol,quantia). Des de M10, a més, la web registra les seves pròpies vendes. L'Anna ha consolidat tots dos orígens — la feina d'enginyer de dades de la taula anterior — en un únic fitxer que farem servir durant tot el mòdul: dades/vendes_2026.csv, amb les vendes de gener a juny de 2026.

Columna Tipus Significat
data data yyyy-mm-dd Dia de la venda
titol text Un dels 4 títols del catàleg
unitats enter Exemplars venuts en aquesta operació
quantia decimal Total cobrat (si el client és soci, s'aplica la tarifa de soci de M3)
canal text botiga (caixa física) o web (la botiga de M10)

Així comença el fitxer (que té 487 files en total):

data,titol,unitats,quantia,canal
2026-01-02,L'Odissea,1,12.50,botiga
2026-01-02,Hamlet,2,19.90,web
2026-01-03,El Quixot,1,15.71,botiga
2026-01-03,Faust,1,21.00,web
2026-01-05,El Quixot,2,31.80,botiga
...
2026-04-23,El Quixot,3,47.70,botiga
2026-04-23,L'Odissea,2,25.00,web
...

Dos detalls que ja pots llegir amb el que has après: la fila del 3 de gener cobra 15.71 per El Quixot — la tarifa de soci que vas calcular a M3 (15.90 amb IVA del 4 % i descompte de soci del 5 %: 15.90 * 1.04 * 0.95 ≈ 15.71) — i les files del 23 d'abril s'acumulen sospitosament: és Sant Jordi.

El que ja saps fer: statistics i els seus límits

Abans d'instal·lar res de nou, siguem justos amb la biblioteca estàndard. Amb csv.DictReader (M6) i el mòdul statistics (M3) ja pots respondre preguntes senzilles:

import csv
import statistics
from collections import Counter
from pathlib import Path

quanties = []
titols = []
with open(Path("dades") / "vendes_2026.csv", encoding="utf-8", newline="") as f:
    for fila in csv.DictReader(f):
        quanties.append(float(fila["quantia"]))
        titols.append(fila["titol"])

print(f"Vendes registrades: {len(quanties)}")
print(f"Quantia mitjana: {statistics.mean(quanties):.2f} €")
print(f"Quantia mediana: {statistics.median(quanties):.2f} €")
print(f"Titol mes frequent: {Counter(titols).most_common(1)}")
Vendes registrades: 487
Quantia mitjana: 15.03 €
Quantia mediana: 12.50 €
Titol mes frequent: [('El Quixot', 168)]

Aquí ja hi ha una lliçó estadística: la mitjana (15.03 €) és més gran que la mediana (12.50 €). Unes poques vendes grans (packs de Faust a 21 € o l'allau de Sant Jordi) estiren la mitjana cap amunt; la mediana — el valor central — resisteix millor aquests extrems. Quan algú et doni "el promig", pregunta sempre quin dels dos és.

Ara els límits. Prova de respondre "quin dia de la setmana ven més?" amb la stdlib:

from datetime import date

per_dia = Counter()
with open(Path("dades") / "vendes_2026.csv", encoding="utf-8", newline="") as f:
    for fila in csv.DictReader(f):
        dia = date.fromisoformat(fila["data"]).weekday()   # 0=dilluns ... 6=diumenge
        per_dia[dia] += int(fila["unitats"])
print(per_dia)

Funciona — i a 11-03 comprovarem que dona dissabte com a guanyador. Però fixa't en el cost: conversió de tipus a mà a cada fila, un Counter per a cada pregunta, i si ara vols "unitats per dia de la setmana i per canal, només de socis, ordenat" el codi creix en bucles imbricats. I tot és text: "12.50" no es pot sumar fins que tu el converteixis, fila a fila. La ciència de dades fa aquestes preguntes a dotzenes; necessites eines on cada pregunta costi una línia, no un bucle. Això són NumPy i pandas.

Errors Comuns i Consells

  • Saltar-se la pregunta i anar directe al codi. L'error número u. "Analitzar les dades" no és un objectiu; "decidir quantes unitats demanar per a Sant Jordi" sí. Escriu la pregunta abans d'obrir l'editor.
  • Instal·lar les llibreries fora de l'entorn virtual. Els pip install d'aquest mòdul van dins del venv del projecte (M1). Si import pandas falla amb ModuleNotFoundError, gairebé segur que l'entorn no està activat.
  • Confondre mitjana i mediana. Amb dades asimètriques (i les vendes gairebé sempre ho són) expliquen històries diferents. Reporta totes dues, o com a mínim sigues conscient de quina uses i per què.
  • Refiar-se de dades que no has mirat. Abans de calcular res, obre el CSV i llegeix 20 files. Dates impossibles, quanties negatives o títols mal escrits es detecten abans amb els ulls que amb codi.
  • Executar cel·les de notebook en desordre. L'estat viu en memòria: si executes la cel·la 5 abans que la 3, els resultats poden ser incoherents. En cas de dubte: Kernel → Restart & Run All.

Exercicis

  1. Classifica aquestes tasques de Papyrus segons el rol (analista, científic o enginyer de dades) que hi encaixa millor: (a) un script nocturn que aboca les vendes de la web de Django al CSV consolidat; (b) un informe mensual d'unitats venudes per títol; (c) estimar quants exemplars d'El Quixot es vendran el proper Sant Jordi.
  2. Amb csv.DictReader i statistics, calcula la quantia mitjana de les vendes de vendes_2026.csv només del canal web i compara-la amb la del canal botiga. Quina hipòtesi se t'acut per explicar la diferència?
  3. Sense escriure codi: per a la pregunta "quins títols es consulten a la web però no es compren?", quines dades necessites a més de vendes_2026.csv? En quin pas del flux de treball ets quan t'adones que et falta informació?

Solucions

  1. (a) Enginyer de dades: mou i consolida dades, no respon preguntes. (b) Analista: descriu què va passar. (c) Científic de dades: prediu i dona suport a una decisió. A Papyrus les tres tasques les fa la mateixa persona; els rols descriuen el tipus de feina, no un carnet.
  2. import csv, statistics
    from pathlib import Path
    
    web, botiga = [], []
    with open(Path("dades") / "vendes_2026.csv", encoding="utf-8", newline="") as f:
        for fila in csv.DictReader(f):
            desti = web if fila["canal"] == "web" else botiga
            desti.append(float(fila["quantia"]))
    
    print(f"web:    {statistics.mean(web):.2f} € en {len(web)} vendes")
    print(f"botiga: {statistics.mean(botiga):.2f} € en {len(botiga)} vendes")
    
    Hipòtesis raonables (a verificar a 11-03, no a donar per certes!): a la botiga es compren més unitats per operació (la Marta recomana en persona), o a la web hi pesen més els títols barats. Formular hipòtesis comprovables és exactament el pas 4 del flux.
  3. Necessites les visites a les fitxes de llibre — són als logs de la web de M10 (cada request a /llibre/<titol> deixa rastre), no al CSV de vendes. Te n'adones al pas 2 (dades): la pregunta compara dues magnituds (consultes i compres) i només en tens una. Tornar de l'exploració a la cerca de dades és el bucle del diagrama funcionant.

Conclusió

Ja tens el mapa: la ciència de dades és respondre preguntes amb dades seguint el cicle pregunta → dades → neteja → exploració → conclusió; l'ecosistema PyData reparteix la feina entre NumPy (números), pandas (taules), Matplotlib (gràfics) i scikit-learn (models); Jupyter és la taula de treball habitual encara que tot funcioni en scripts; i vendes_2026.csv — 487 vendes de gener a juny, amb Sant Jordi bategant el 23 d'abril — és el material sobre el qual respondrem les preguntes de l'Anna. També has vist el límit: statistics i Counter arriben fins on arriben, i cada pregunta nova costa un altre bucle amb conversions a mà. L'arrel del problema és que les llistes de Python no saben de matemàtiques: sumar dues llistes les concatena, no en suma els números. La propera lliçó presenta l'estructura que sí que en sap: l'array de NumPy, on quanties * 1.04 fa en una línia — i mil vegades més ràpid — el que fins ara exigia un bucle.

Curs de Programació en Python

Mòdul 1: Introducció a Python

Mòdul 2: Estructures de Control

Mòdul 3: Funcions i Mòduls

Mòdul 4: Estructures de Dades

Mòdul 5: Programació Orientada a Objectes

Mòdul 6: Gestió de Fitxers

Mòdul 7: Gestió d'Errors i Excepcions

Mòdul 8: Temes Avançats

Mòdul 9: Proves i Depuració

Mòdul 10: Desenvolupament Web amb Python

Mòdul 11: Ciència de Dades amb Python

Mòdul 12: Projecte Final

© Copyright 2026. Tots els drets reservats