Cens¶
Una jove enginyera a punt d’emancipar-se creu haver trobat el pis de lloguer ideal. El seu xicot, però, li desaconsella al·legant que el pis es troba en un «barri de gent gran» i que li convé un barri on visqui més gent de la seva edat.
― «I com ho saps?», pregunta l’enginyera.
― «És de domini públic», respon el xicot. «Tothom ho sap que en aquest barri hi viuen sobretot persones de més de 65 anys.»
La nostra enginyera ha decidit esbrinar si aquesta afirmació té base
científica, analitzant les dades obertes que l’Ajuntament de Barcelona
posa a disposició dels ciutadans. Concretament, les dades de la
distribució demogràfica de les seccions censals de la ciutat són al
fitxer TAULA_MAP_SCENSAL.csv que es pot descarregar de
l’enllaç seccions censals. D’altra
banda, el fitxer TAULA_DIRELE_SEC_CENS.csv conté les
adreces assignades a cada secció censal i es pot descarregar de
l’enllaç adreces. Combinant
els dos jocs de dades i gràcies als seus coneixements de python, la
protagonista del problema intentarà esbrinar si l’afirmació és certa o
no.
Primer, visiteu les dues url i intenteu entendre què signifiquen les columnes. Observareu que en les dades que relacionen adreces i seccions censals hi ha diverses columnes com l’Àrea Estadística Bàsica (AEB), la secció censal i la secció estadística. Si voleu més informació sobre el tema, exploreu la url: territori. En particular, hi trobareu l’explicació de la denominació de les seccions censals que és el resultat de la concatenació del número de districte i del número de secció censal.
Dissenyeu la funció
llegeixCens()que retorna un DataFrame que conté les dades demogràfiques de les seccions censals del fitxerTAULA_MAP_SCENSAL.csv. Cal que la columna SECCIO_CENSAL sigui un string. Indexeu elDataFrameper la columna SECCIO_CENSAL. Podeu usar el mètodeset_index().>>> df1 = llegeixCens() >>> len(df1) 1068 >>> df1.head()[['HOMES', 'DONES']].mean() HOMES 1291.6 DONES 1078.4 dtype: float64
Dissenyeu la funció
llegeixAdreces()que retorna un DataFrame que conté la relació entre adreces i seccions censals del fitxerTAULA_DIRELE_SEC_CENS.csv. El DataFrame retornat ha de tenir les columnes següents: NOM_CARRER, PRIMER_NUM, ULTIM_NUM i una columna nova: SECCIO_CENSAL que conté la denominació de la secció censal.Per a resoldre aquest exercici, podeu llegir les columnes DISTRICTE i SECC_CENS com a strings i concatenar les dues columnes amb l’operador +. Finalment, elimineu les columnes sobrants amb el mètode
drop()>>> df2 = llegeixAdreces() >>> df2.head() NOM_CARRER PRIMER_NUM ULTIM_NUM SECCIO_CENSAL 0 Llebrencs 0001 0017 05003 1 Llebrencs 0002 0026 05003 2 A 0003 0119 03025 3 A 0002 0106 03025 4 Guerau de Liost 0001 0017 05003
Dissenyeu la funció
buscaSecció()que a partir d’un DataFrame com l’obtingut a la pregunta 2 i d’una adreça de la ciutat de Barcelona, retorna la secció censal corresponent o -1 si no la troba. L’adreça ha de ser una tupla formada pel nom del carrer i el número, per exemple: (“Diputació”, 165).Observareu que algunes adreces tenen un número extrany, per exemple “0045B” o “0002D”. Per simplificar, ignoreu aquestes files.
Tingueu en compte la paritat dels números per decidir la secció censal. Per exemple, el número 165 del carrer Diputació està entre els números 157 i 169 que corresponen a la secció censal 2096, però també està entre els números 150 i 166 que corresponen a la secció censal 2095. Cal tenir en compte que el número 165 és senar per decidir que la secció censal que li correspon és la 2096.
Per a resoldre aquest problema, podeu obtenir DataFrame que només contingui les dades del carrer en qüestió. Després, itereu la columna PRIMER_NUM per trobar la fila que conté el número donat. Per això podeu utilitzar el mètode
itertuples(). Alternativament, podeu convertir les columnes PRIMER_NUM i ULTIM_NUM a valors numèrics usant la funcióto_numeric()i utilitzar aquestes columnes per seleccinar les files delDataFrameque corresponen al carrer i al número donat.>>> adr = ('GV Corts Catalanes', 1005) >>> sc = buscaSecció(df2, adr) >>> sc '10105' >>> adr = ('Aragó', 641) >>> sc = buscaSecció(df2, adr) >>> sc '10031'
Dissenyeu la funció
percentatgeGentGran()que donat un DataFrame com l’obtingut a la pregunta 1 i una secció censal, retorna el percentatge de persones més grans de 65 anys sobre la població total de la secció censal.>>> pgg = percentatgeGentGran(df1, '10237') >>> round(pgg, 2) 28.28 >>> pgg = percentatgeGentGran(df1, '10031') >>> round(pgg, 2) 21.24
La nostra amiga no ha quedat satisfeta amb la resposta de la pregunta 4, perquè no sap si el percentatge obtingut és alt o baix en comparació d’altres barris. Ara vol saber situar aquest percentatge respecte a les dades de tota la ciutat, concretament, vol determinar en quin decil es troba. Dissenyeu la funció
decilPercentatge()que donat un DataFrame com l’obtingut a la pregunta 1 i donat el percentatge de persones grans que hi ha en una secció censal (com s’ha calculat a la pregunta 4), retorna el decil en què es troba aquest percentatge en relació a tota la ciutat.Per a resoldre aquesta pregunta, podeu utilitzar el mètode
quantile()i calcular el percentatge corresponent a cada decil. Després haureu de dissenyar una funció inversa que donat un percentatge retorna el decil corresponent.>>> dcl = decilPercentatge(df1, 20) >>> round(dcl, 1) 4 >>> dcl = decilPercentatge(df1, 5) >>> round(dcl, 1) 0
Finalment, dissenyeu la funció
comÉsElBarri()que integra totes les funcionalitats desenvolupades i, donada una adreça de Barcelona, retorna un enter que indica el decil del percentatge de gent gran d’aquesta secció censal en relació a la tota la ciutat o -1 si l’adreça no es troba a les dades.>>> adr = ('GV Corts Catalanes', 200) >>> dcl = comÉsElBarri(adr) >>> round(dcl, 1) 6 >>> adr = ('Aragó', 641) >>> dcl = comÉsElBarri(adr) >>> round(dcl, 1) 5
Disposeu de jocs de proves al fitxer test-cens.txt.
Solució
Disposeu d’una solució al fitxer cens.py.
P.D: La nostra amiga ha agafat el pis. No sabem si el xicot tenia raó o no. Ben abans d’esbrinar la veritat, la noia ja havia decidit que la distribució demogràfica del barri no li importava el més mínim.