Eleccions municipals

Els partits polítics estan començant a dissenyar la seva estratègia electoral de cara a les pròximes eleccions municipals. Volen saber en quins municipis van ser el partit més votat a les eleccions del 2015, per tal d’intentar fidelitzar els seus votants multiplicant els actes electorals en aquests municipis. Exclouen Barcelona d’aquesta cerca perquè els actes electorals a la capital s’organitzen a part.

L’objectiu de l’exercici és crear una funció que donades les sigles d’un partit polític, retorni la llista dels municipis on aquest partit va ser el més votat i el percentatge de vots que aquest partit ha obtingut respecte del total. Per a resoldre aquest problema, cal que que utilitzeu la llibreria pandas. Utilitzarem el fitxer FilesVots_M20151_MU_ca_ES.csv que conté els resultats de les eleccions del 2015. Aquests resultats són públics i es poden obtenir de la url següent. Resoldrem el problema a través de diverses funcions que desarem al fitxer municipals.py (mòdul municipals). També farem altres funcions no directament relacionades amb el nostre objectiu, però que ens ajudaran a explorar les dades.

Abans de començar, descarregueu el fitxer de dades en el directori de treball.

  1. Dissenyeu la funció creaDataFrame() que donat el nom d’un fitxer amb el resultat de les eleccions municipals, com l’indicat en el paràgraf anterior, el llegeix i retorna un DataFrame. Les dades estan en format CSV separades per un punt i coma. Consulteu la documentació de la funció read_csv per saber com fer-ho.

    >>> url = 'FilesVots_M20151_MU_ca_ES.csv'
    >>> df = creaDataFrame(url)
    >>> len(df)
    3681
    >>> df.columns
    Index(['Codi Província', 'Nom Província', 'Codi Vegueria', 'Nom Vegueria',
           'Codi Comarca', 'Nom Comarca', 'Codi Municipi', 'Nom Municipi',
           'Sigles', 'Candidatures', 'Vots', '% vàlids', 'Escons'],
          dtype='object')
    >>> df.loc[0, 'Nom Comarca']
    'Baix Llobregat'
    >>> df.loc[len(df)-1]['Nom Municipi']
    'Xerta'
    >>> df[df['Nom Municipi']=='Barcelona'].head(4)['Sigles']
    83    BARCELONA EN COMÚ-E
    84            CiU        
    85            C's        
    86    ERC-MESBcnCO-ACatSí
    Name: Sigles, dtype: object
    
  2. Com que ens interessen els resultats a nivell dels municipis i volem excloure Barcelona, filtrarem el DataFrame i guardarem només les files que tenen un valor vàlid a la columna de 'Nom Municipi' i que no sigui Barcelona. Per això, dissenyeu la funció filtraFiles() que rep com a paràmetre el DataFrame llegit a la pregunta anterior i el filtra. Utilizeu el mètode notna(), per determinar si un valor existeix o no. Investigueu com filtrar amb una doble condició llegint l’apartat de la documentació: Boolean indexing.

    >>> df2 = filtraFiles(df)
    >>> len(df2) 
    3659
    
  3. Ara voldrem reduir el nombre de columnes i quedar-nos només amb les corresponents al nom del municipi, les sigles de partit i els vots de partits. Dissenyeu la funció filtraColumnes() que rep com a paràmetre un DataFrame com l’obtingut a la pregunta 2 i n’obté un altre que només té les columnes indicades.

    >>> df3 = filtraColumnes(df2)
    >>> df3.head()
      Nom Municipi          Sigles  Vots
    0       Abrera          PSC-CP  1478
    1       Abrera           Ad Ab   947
    2       Abrera  ABRERA EN COMÚ   898
    3       Abrera     ERC-AM        555
    4       Abrera     C's           445
    
  4. Ens volem centrar en el cas particular d’un municipi del que no recordem exactament el nom. Creiem recordar que era quelcom de l’estil no_sé_què de Llobregat. En el shell de python, intenteu filtrar les dades de tots municipis que contenen “de Llobregat” en el seu nom. Investigueu les eines de treball amb strings. Dissenyeu la funció filtraPerMunicipi() que donat un dataframe com l’obtingut a la pregunta 3 (on totes les files tenen un valor vàlid a la columna “Nom Municipi”), i donat un substring, retorni un nou DataFrame format només per les files corresponents a municipis que contenen el substring en el seu nom. Com a suggeriment podeu usar el mètode contains().

    
    >>> filtraPerMunicipi(df3, 'Prat de Llobregat')
                  Nom Municipi       Sigles  Vots
    583  Prat de Llobregat, el   ICV-EUiA-E  9380
    584  Prat de Llobregat, el       PSC-CP  3850
    585  Prat de Llobregat, el  PP           2386
    586  Prat de Llobregat, el  ERC-AM       2355
    587  Prat de Llobregat, el  C's          2275
    588  Prat de Llobregat, el  SE PUEDE EL  1938
    589  Prat de Llobregat, el      GANEMOS  1697
    590  Prat de Llobregat, el  CiU          1474
    591  Prat de Llobregat, el  PxC           360
    592  Prat de Llobregat, el        AE-EP   344
    
  5. Ara, dissenyeu la funció ordenaDades() que, a partir d’un DataFrame com l’obtingut a la pregunta 3, en crea un de nou que té per files el nom dels municipis i per columna les sigles del partit més votat. Per això, primer crearem un dataframe per cada municipi utilitzant el mètode groupby(). Per cada DataFrame municipal, calcularem l’índex del partit més votat utilitzant el mètode idxmax() i finalment reduirem les dades a només el nom del municipi (que ha de ser l’índex) i les sigles del partit més votat.

    >>> df6 = ordenaDades(df3)
    >>> df6.head()
                             Sigles
    Nom Municipi                   
    Abella de la Conca    JIAB - AM
    Abrera                   PSC-CP
    Agramunt                AD'E-AM
    Aguilar de Segarra  CiU        
    Agullana            ERC-AM     
    >>> df6.tail()
                            Sigles
    Nom Municipi                  
    Viver i Serrateix  CiU        
    Xerta                  MX - AM
    Àger                  IxA - AM
    Òdena                   PSC-CP
    Òrrius             ERC-AM     
    
  6. Dissenyeu finalment la funció llistaMunicipis(), que a partir d’un DataFrame com l’obtingut a la pregunta 1 i de les sigles d’un partit, retorna la llista de municipis on el partit donat ha estat el més votat ordenada alfabèticament. Aquesta funció simplement crida seqüencialment algunes de les funcions anteriors, passant els paràmetres adients. Noteu, però, que les sigles d’un partit poden aparèixer soles o bé formant part d’una candidatura. Per exemple, 'ERC' pot aparèixer així o bé com 'ERC-AM' o 'ERC-SxA', entre altres possibles combinacions.

    >>> l = llistaMunicipis(df, 'CiU')
    >>> len(l)
    439
    >>> l[:10]
    ['Aguilar de Segarra', 'Aiguafreda', 'Aiguamúrcia', 'Aitona', 'Albanyà', 'Albatàrrec', 'Albesa', "Albi, l'", 'Albinyana', 'Albons']
    
    >>> l = llistaMunicipis(df, 'ERC')
    >>> len(l)
    131
    >>> l[:10]
    ['Agullana', "Albiol, l'", 'Alcanar', 'Alcarràs', "Aldea, l'", 'Alella', 'Almoster', 'Arenys de Munt', 'Argençola', 'Arsèguel']
    
    >>> l = llistaMunicipis(df, 'CUP')
    >>> len(l)
    15
    >>> l[:10]
    ['Berga', 'Beuda', 'Biosca', 'Capellades', 'Celrà', 'Colomers', 'Guiamets, els', 'Monistrol de Calders', 'Navàs', 'Ordis']
    

Disposeu de jocs de proves al fitxer test-municipals.txt.

Solució

Disposeu d’una solució al fitxer municipals.py.