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
- Què és la ciència de dades (i què no és)
- El flux de treball: de la pregunta a la conclusió
- Els rols de l'ofici: analista, científic i enginyer de dades
- L'ecosistema PyData: quina peça fa què
- Jupyter Notebook: l'entorn habitual de l'anàlisi
- El dataset del mòdul:
vendes_2026.csv - El que ja saps fer:
statisticsi 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.
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 installd'aquest mòdul van dins delvenvdel projecte (M1). Siimport pandasfalla ambModuleNotFoundError, 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
- 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.
- Amb
csv.DictReaderistatistics, calcula la quantia mitjana de les vendes devendes_2026.csvnomés del canalwebi compara-la amb la del canalbotiga. Quina hipòtesi se t'acut per explicar la diferència? - 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
- (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.
-
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.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") - 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
- Introducció a Python
- Configuració de l'Entorn de Desenvolupament
- Sintaxi de Python i Tipus de Dades Bàsics
- Variables i Constants
- Entrada i Sortida Bàsica
- Entorns Virtuals i Gestió de Paquets
Mòdul 2: Estructures de Control
Mòdul 3: Funcions i Mòduls
- Definició de Funcions
- Arguments de Funció
- Funcions Lambda
- Mòduls i Paquets
- Visió General de la Biblioteca Estàndard
Mòdul 4: Estructures de Dades
Mòdul 5: Programació Orientada a Objectes
Mòdul 6: Gestió de Fitxers
- Lectura i Escriptura de Fitxers
- Treball amb Fitxers CSV
- Gestió de Dades JSON
- Operacions amb Fitxers i Directoris
Mòdul 7: Gestió d'Errors i Excepcions
- Introducció a les Excepcions
- Gestió d'Excepcions
- Llançament d'Excepcions
- Excepcions Personalitzades
- Bones Pràctiques i Registre d'Errors amb logging
Mòdul 8: Temes Avançats
- Anotacions de Tipus (type hints)
- Decoradors
- Generadors
- Gestors de Context
- Concurrència: Fils i Processos
- Asyncio per a la Programació Asíncrona
Mòdul 9: Proves i Depuració
- Introducció a les Proves
- Proves Unitàries amb unittest
- Proves amb pytest
- Desenvolupament Guiat per Proves
- Tècniques de Depuració
- Ús de pdb per a la Depuració
Mòdul 10: Desenvolupament Web amb Python
- Introducció al Desenvolupament Web
- Fonaments del Framework Flask
- Construcció d'APIs REST amb Flask
- Introducció a Django
- Construcció d'Aplicacions Web amb Django
Mòdul 11: Ciència de Dades amb Python
- Introducció a la Ciència de Dades
- NumPy per a la Computació Numèrica
- Pandas per a la Manipulació de Dades
- Matplotlib per a la Visualització de Dades
- Introducció a l'Aprenentatge Automàtic amb scikit-learn
