Title:
Data cleaning for the DRC’s Mobility Tracking report (Part 2)
Objective:
Predominately working with the Democratic Republic of the Congo team as a Data and Reporting Analyst, it falls to me to provide all of the analysis in their regular reports. This is Part 2 of 3, where I will be showcasing some of the python code used for their Mobility Tracking reports.
Methods:
Python, Data Visualisation
Explanation
Predominately working with the Democratic Republic of the Congo Team as a Data and Reporting Analyst, it fell to me to provide all of the analysis in their regular reports. One of their most important reports is their Mobility Tracking Assessments, which track the intentions, needs and movements of internally displaced people and returnees for the four eastern provinces. This article is about how I use Python to verify and output the analysis needed for the North Kivu Mobility Tracking report – you can find a link to the full report and data here.
Analysis: Page 1
P-Code Example for North Kivu
Basic Checks
#Setting up the libraries and loading the sheet
import numpy as np
import pandas as pd
dfv = pd.read_excel(r'C:\Users\miredale\OneDrive - International Organization for Migration - IOM\Desktop\DRC Python Script\NK Error.xlsx', sheet_name='VILLAGES')
dfvc = pd.read_excel(r'C:\Users\miredale\OneDrive - International Organization for Migration - IOM\Desktop\DRC Python Script\NK.xlsx', sheet_name='VILLAGES')
dfac = pd.read_excel(r'C:\Users\miredale\OneDrive - International Organization for Migration - IOM\Desktop\DRC Python Script\NK.xlsx', sheet_name='APERCU')
dfcm = pd.read_excel(r'C:\Users\miredale\OneDrive - International Organization for Migration - IOM\Desktop\DRC Python Script\NK.xlsx', sheet_name='SITES_CCCM')
dfncm = pd.read_excel(r'C:\Users\miredale\OneDrive - International Organization for Migration - IOM\Desktop\DRC Python Script\NK.xlsx', sheet_name='SITES_NON_CCCM')
pdfv = pd.read_excel(r'C:\Users\miredale\OneDrive - International Organization for Migration - IOM\Desktop\DRC Python Script\NK P.xlsx', sheet_name='VILLAGES')
pdfcm = pd.read_excel(r'C:\Users\miredale\OneDrive - International Organization for Migration - IOM\Desktop\DRC Python Script\NK P.xlsx', sheet_name='SITES_CCCM')
pdfncm = pd.read_excel(r'C:\Users\miredale\OneDrive - International Organization for Migration - IOM\Desktop\DRC Python Script\NK P.xlsx', sheet_name='SITES_NON_CCCM')
#Define a function called Basic Checks that use a dictionary of the admin data and labels and verifies if the dataset is correct
def BasicChecks(dfv):
CompD1 = {'NORD-KIVU' : 'CD61'}
CompD2 = {'BENI (Territoire / Oicha)': 'CD6107',
'BENI (Ville)': 'CD6109',
'BUTEMBO (Ville)': 'CD6110',
'GOMA' : 'CD6101',
'LUBERO' : 'CD6105',
'MASISI' : 'CD6103',
'NYIRAGONGO' : 'CD6102',
'RUTSHURU' : 'CD6111',
'WALIKALE' : 'CD6104'}
CompD3 = {'KALUNGUTA': 'CD6107ZS01',
'KAMANGO': 'CD6107ZS02',
'KYONDO': 'CD6107ZS03',
'MABALAKO': 'CD6107ZS04',
'MUTWANGA': 'CD6107ZS05',
'OICHA': 'CD6107ZS06',
'VUHOVI': 'CD6107ZS07',
'BENI (ville)': 'CD6109ZS01',
'BUTEMBO': 'CD6110ZS01',
'KATWA': 'CD6110ZS02',
'GOMA': 'CD6101ZS01',
'KARISIMBI': 'CD6101ZS02',
'ALIMBONGO': 'CD6105ZS01',
'BIENA': 'CD6105ZS02',
'KAYNA': 'CD6105ZS03',
'LUBERO': 'CD6105ZS04',
'MANGUREDJIPA': 'CD6105ZS05',
'MASEREKA': 'CD6105ZS06',
'MUSIENENE': 'CD6105ZS07',
'KATOYI': 'CD6103ZS01',
'KIROTSHE': 'CD6103ZS02',
'MASISI': 'CD6103ZS03',
'MWESO': 'CD6103ZS04',
'NYIRAGONGO': 'CD6102ZS01',
'BAMBO': 'CD6111ZS01',
'BINZA': 'CD6111ZS02',
'BIRAMBIZO': 'CD6111ZS03',
'KIBIRIZI': 'CD6111ZS04',
'RUTSHURU': 'CD6111ZS05',
'RWANGUBA': 'CD6111ZS06',
'ITEBERO': 'CD6104ZS01',
'KIBUA': 'CD6104ZS02',
'PINGA': 'CD6104ZS03',
'WALIKALE': 'CD6104ZS04'}
Correct=True
#Province matches Territory
for index, row in dfv.iterrows():
if row['admin_1_code'][:4] != row['admin_2_code'][:4]:
print(f"Row {index} does not match: {row['admin_1_code']} -> {row['admin_2_code']}")
Correct = False
#Province matches Zone de Sante
for index, row in dfv.iterrows():
if row['admin_1_code'][:4] != row['admin_3_code'][:4]:
print(f"Row {index} does not match: {row['admin_1_code']} -> {row['admin_3_code']}")
Correct = False
#Territory matches Zone de Sante
for index, row in dfv.iterrows():
if row['admin_2_code'][:6] != row['admin_3_code'][:6]:
print(f"Row {index} does not match: {row['admin_2_code']} -> {row['admin_3_code']}")
Correct = False
#Province Check
for index, row in dfv.iterrows():
label1 = row['admin_1_label']
pcode1 = row['admin_1_code']
if CompD1.get(label1) != (pcode1):
print(f"Row {index} does not match: {label1} -> {pcode1}")
Correct = False
#Territory Checks
for index, row in dfv.iterrows():
label2 = row['admin_2_label']
pcode2 = row['admin_2_code']
if CompD2.get(label2) != (pcode2):
print(f"Row {index} does not match: {label2} -> {pcode2}")
Correct = False
#ZS Checks
for index, row in dfv.iterrows():
label3 = row['admin_3_label']
pcode3 = row['admin_3_code']
if CompD3.get(label3) != (pcode3):
print(f"Row {index} does not match: {label3} -> {pcode3}")
Correct = False
if Correct:
print("All good")
Output of the Code (from VSC)
Reasons for Return
This next piece of python code sort of acts like a SUMIF calculation in excel and it is used to assess the reasons that a returning IDP may return back to province, measured over a 4-year period. The output of the code is for Figures 10 and 11. Each block of code assess a particular reason for return. As you’ll notice the output of the code is French, as is the report. We rarely do English versions of the reports for DRC as it is a French-speaking country.
#Raisons de Retour
Security21 = dfvc[dfvc['actual_RET_arrived_2021_reason']== 'meilleur_secu']['actual_RET_ind_arrived_2021_total'].sum()
Security22 = dfvc[dfvc['actual_RET_arrived_2022_reason']== 'meilleur_secu']['actual_RET_ind_arrived_2022_total'].sum()
Security23 = dfvc[dfvc['actual_RET_arrived_2023_reason']== 'meilleur_secu']['actual_RET_ind_arrived_2023_total'].sum()
Security24 = dfvc[dfvc['actual_RET_arrived_2024_reason']== 'meilleur_secu']['actual_RET_ind_arrived_2024_total'].sum()
Security = Security21 + Security22 + Security23 + Security24
AL21 = dfvc[dfvc['actual_RET_arrived_2021_reason']== 'meilleur_sit_alimenitaire']['actual_RET_ind_arrived_2021_total'].sum()
AL22 = dfvc[dfvc['actual_RET_arrived_2022_reason']== 'meilleur_sit_alimenitaire']['actual_RET_ind_arrived_2022_total'].sum()
AL23 = dfvc[dfvc['actual_RET_arrived_2023_reason']== 'meilleur_sit_alimenitaire']['actual_RET_ind_arrived_2023_total'].sum()
AL24 = dfvc[dfvc['actual_RET_arrived_2024_reason']== 'meilleur_sit_alimenitaire']['actual_RET_ind_arrived_2024_total'].sum()
AL = AL21+ AL22 + AL23 + AL24
Regroup21 = dfvc[dfvc['actual_RET_arrived_2021_reason']== 'regroupement']['actual_RET_ind_arrived_2021_total'].sum()
Regroup22 = dfvc[dfvc['actual_RET_arrived_2022_reason']== 'regroupement']['actual_RET_ind_arrived_2022_total'].sum()
Regroup23 = dfvc[dfvc['actual_RET_arrived_2023_reason']== 'regroupement']['actual_RET_ind_arrived_2023_total'].sum()
Regroup24 = dfvc[dfvc['actual_RET_arrived_2024_reason']== 'regroupement']['actual_RET_ind_arrived_2024_total'].sum()
Regroup = Regroup21 + Regroup22 + Regroup23 + Regroup24
PCZD21 = dfvc[dfvc['actual_RET_arrived_2021_reason']== 'pire_conditions_zone_deplacement']['actual_RET_ind_arrived_2021_total'].sum()
PCZD22 = dfvc[dfvc['actual_RET_arrived_2022_reason']== 'pire_conditions_zone_deplacement']['actual_RET_ind_arrived_2022_total'].sum()
PCZD23 = dfvc[dfvc['actual_RET_arrived_2023_reason']== 'pire_conditions_zone_deplacement']['actual_RET_ind_arrived_2023_total'].sum()
PCZD24 = dfvc[dfvc['actual_RET_arrived_2024_reason']== 'pire_conditions_zone_deplacement']['actual_RET_ind_arrived_2024_total'].sum()
PCZD = PCZD21 + PCZD22 + PCZD23 + PCZD24
Econ21 = dfvc[dfvc['actual_RET_arrived_2021_reason']== 'opportunite_economique']['actual_RET_ind_arrived_2021_total'].sum()
Econ22 = dfvc[dfvc['actual_RET_arrived_2022_reason']== 'opportunite_economique']['actual_RET_ind_arrived_2022_total'].sum()
Econ23 = dfvc[dfvc['actual_RET_arrived_2023_reason']== 'opportunite_economique']['actual_RET_ind_arrived_2023_total'].sum()
Econ24 = dfvc[dfvc['actual_RET_arrived_2024_reason']== 'opportunite_economique']['actual_RET_ind_arrived_2024_total'].sum()
Econ = Econ21+ Econ22 + Econ23 + Econ24
Service21 = dfvc[dfvc['actual_RET_arrived_2021_reason']== 'meilleur_services']['actual_RET_ind_arrived_2021_total'].sum()
Service22 = dfvc[dfvc['actual_RET_arrived_2022_reason']== 'meilleur_services']['actual_RET_ind_arrived_2022_total'].sum()
Service23 = dfvc[dfvc['actual_RET_arrived_2023_reason']== 'meilleur_services']['actual_RET_ind_arrived_2023_total'].sum()
Service24 = dfvc[dfvc['actual_RET_arrived_2024_reason']== 'meilleur_services']['actual_RET_ind_arrived_2024_total'].sum()
Service = Service21 + Service22 + Service23 + Service24
San21 = dfvc[dfvc['actual_RET_arrived_2021_reason']== 'meilleur_sit_sanitaire']['actual_RET_ind_arrived_2021_total'].sum()
San22 = dfvc[dfvc['actual_RET_arrived_2022_reason']== 'meilleur_sit_sanitaire']['actual_RET_ind_arrived_2022_total'].sum()
San23 = dfvc[dfvc['actual_RET_arrived_2023_reason']== 'meilleur_sit_sanitaire']['actual_RET_ind_arrived_2023_total'].sum()
San24 = dfvc[dfvc['actual_RET_arrived_2024_reason']== 'meilleur_sit_sanitaire']['actual_RET_ind_arrived_2024_total'].sum()
San = San21 + San22 + San23 + San24
ISZD21 = dfvc[dfvc['actual_RET_arrived_2021_reason']== 'insecurite_zone_deplacement']['actual_RET_ind_arrived_2021_total'].sum()
ISZD22 = dfvc[dfvc['actual_RET_arrived_2022_reason']== 'insecurite_zone_deplacement']['actual_RET_ind_arrived_2022_total'].sum()
ISZD23 = dfvc[dfvc['actual_RET_arrived_2023_reason']== 'insecurite_zone_deplacement']['actual_RET_ind_arrived_2023_total'].sum()
ISZD24 = dfvc[dfvc['actual_RET_arrived_2024_reason']== 'insecurite_zone_deplacement']['actual_RET_ind_arrived_2024_total'].sum()
ISZD = ISZD21+ ISZD22 + ISZD23 + ISZD24
Reso21 = dfvc[dfvc['actual_RET_arrived_2021_reason']== 'resolution_litiges']['actual_RET_ind_arrived_2021_total'].sum()
Reso22 = dfvc[dfvc['actual_RET_arrived_2022_reason']== 'resolution_litiges']['actual_RET_ind_arrived_2022_total'].sum()
Reso23 = dfvc[dfvc['actual_RET_arrived_2023_reason']== 'resolution_litiges']['actual_RET_ind_arrived_2023_total'].sum()
Reso24 = dfvc[dfvc['actual_RET_arrived_2024_reason']== 'resolution_litiges']['actual_RET_ind_arrived_2024_total'].sum()
Reso = Reso21 + Reso22 + Reso23 + Reso24
RScol21 = dfvc[dfvc['actual_RET_arrived_2021_reason']== 'raison_scolaire']['actual_RET_ind_arrived_2021_total'].sum()
RScol22 = dfvc[dfvc['actual_RET_arrived_2022_reason']== 'raison_scolaire']['actual_RET_ind_arrived_2022_total'].sum()
RScol23 = dfvc[dfvc['actual_RET_arrived_2023_reason']== 'raison_scolaire']['actual_RET_ind_arrived_2023_total'].sum()
RScol24 = dfvc[dfvc['actual_RET_arrived_2024_reason']== 'raison_scolaire']['actual_RET_ind_arrived_2024_total'].sum()
RScol = RScol21 + RScol22 + RScol23 + RScol24
CZD21 = dfvc[dfvc['actual_RET_arrived_2021_reason']== 'catastrophe_zone_deplacement']['actual_RET_ind_arrived_2021_total'].sum()
CZD22 = dfvc[dfvc['actual_RET_arrived_2022_reason']== 'catastrophe_zone_deplacement']['actual_RET_ind_arrived_2022_total'].sum()
CZD23 = dfvc[dfvc['actual_RET_arrived_2023_reason']== 'catastrophe_zone_deplacement']['actual_RET_ind_arrived_2023_total'].sum()
CZD24 = dfvc[dfvc['actual_RET_arrived_2024_reason']== 'catastrophe_zone_deplacement']['actual_RET_ind_arrived_2024_total'].sum()
CZD = CZD21+ CZD22 + CZD23 + CZD24
Autre21 = dfvc[dfvc['actual_RET_arrived_2021_reason']== 'autre']['actual_RET_ind_arrived_2021_total'].sum()
Autre22 = dfvc[dfvc['actual_RET_arrived_2022_reason']== 'autre']['actual_RET_ind_arrived_2022_total'].sum()
Autre23 = dfvc[dfvc['actual_RET_arrived_2023_reason']== 'autre']['actual_RET_ind_arrived_2023_total'].sum()
Autre24 = dfvc[dfvc['actual_RET_arrived_2024_reason']== 'autre']['actual_RET_ind_arrived_2024_total'].sum()
Autre = Autre21 + Autre22 + Autre23 + Autre24
SL21 = dfvc[dfvc['actual_RET_arrived_2021_reason']== 'SL']['actual_RET_ind_arrived_2021_total'].sum()
SL22 = dfvc[dfvc['actual_RET_arrived_2022_reason']== 'SL']['actual_RET_ind_arrived_2022_total'].sum()
SL23 = dfvc[dfvc['actual_RET_arrived_2023_reason']== 'SLt']['actual_RET_ind_arrived_2023_total'].sum()
SL24 = dfvc[dfvc['actual_RET_arrived_2024_reason']== 'SL']['actual_RET_ind_arrived_2024_total'].sum()
SL = SL21+ SL22 + SL23 + SL24
Epi21 = dfvc[dfvc['actual_RET_arrived_2021_reason']== 'epidemie']['actual_RET_ind_arrived_2021_total'].sum()
Epi22 = dfvc[dfvc['actual_RET_arrived_2022_reason']== 'epidemie']['actual_RET_ind_arrived_2022_total'].sum()
Epi23 = dfvc[dfvc['actual_RET_arrived_2023_reason']== 'epidemie']['actual_RET_ind_arrived_2023_total'].sum()
Epi24 = dfvc[dfvc['actual_RET_arrived_2024_reason']== 'epidemie']['actual_RET_ind_arrived_2024_total'].sum()
Epi = Epi21 + Epi22 + Epi23 + Epi24
TotalRR = Security + AL + Regroup + PCZD + Econ + Service + San + ISZD + Reso + RScol + CZD + Autre + SL + Epi
#Printing out the individual results
print(f'Amélioration de la sit. Sécuritaire: {((Security/TotalRR)*100).round(0)}')
print(f'Amélioration de la sit. Alimentaire: {((AL/TotalRR)*100).round(0)}')
print(f'Regroupement: {((Regroup/TotalRR)*100).round(0)}')
print(f'Pire condition dans la zone de déplacement: {((PCZD/TotalRR)*100).round(0)}')
print(f'Opportunité économique: {((Econ/TotalRR)*100).round(0)}')
print(f'Amélioration de services: {((Service/TotalRR)*100).round(0)}')
print(f'Amélioration de la sit. Sanitaire: {((San/TotalRR)*100).round(0)}')
print(f'Insécurité dans la zone de déplacement: {((ISZD/TotalRR)*100).round(0)}')
print(f'Resolution de litiges: {((Reso/TotalRR)*100).round(0)}')
print(f'Raison scolaire: {((RScol/TotalRR)*100).round(0)}')
print(f'Catastrophe dans la zone de déplacement: {((CZD/TotalRR)*100).round(0)}')
print(f'Autre: {((Autre/TotalRR)*100).round(0)}')
print(f'SL: {((SL/TotalRR)*100).round(0)}')
print(f'Epidemie: {((Epi/TotalRR)*100).round(0)}')
SecT = ((Security/TotalRR)*100).round(0)
AlimenT = ((AL/TotalRR)*100).round(0)
RegT = ((Regroup/TotalRR)*100).round(0)
PCZDT = ((PCZD/TotalRR)*100).round(0)
OET = ((Econ/TotalRR)*100).round(0)
ServT = ((Service/TotalRR)*100).round(0)
SanT = ((San/TotalRR)*100).round(0)
InsT = ((ISZD/TotalRR)*100).round(0)
ResT = ((Reso/TotalRR)*100).round(0)
ScolT = ((RScol/TotalRR)*100).round(0)
CataT = ((CZD/TotalRR)*100).round(0)
AutT = ((Autre/TotalRR)*100).round(0)
SLT = ((SL/TotalRR)*100).round(0)
EpiT = ((Epi/TotalRR)*100).round(0)
#New frame of results
data = {
'Category' : ['Amélioration de la sit. Sécuritaire', 'Amélioration de la sit. Alimentaire',
'Regroupement','Pire condition dans la zone de déplacement','Opportunité économique', 'Amélioration de services',
'Amélioration de la sit. Sanitaire', 'Insécurité dans la zone de déplacement', 'Resolution de litiges', 'Raison scolaire',
'Catastrophe dans la zone de déplacement', 'Autre', 'SL', 'Epidemie'],
'Value' : [SecT, AlimenT,RegT,PCZDT,OET,ServT,SanT,InsT,ResT,ScolT,CataT,AutT,SLT,EpiT] }
#Sorting and printing the top 3 results
ReasonR = pd.DataFrame(data)
ReasonR = ReasonR.sort_values('Value', ascending=False)
ReasonR = ReasonR[0:3]
print(ReasonR)
Output of the Code: Reasons for Return (%)
End of Part 1
There you have it, some useful code for some simple and insightful analysis.