Commit 34036832 authored by Maria Marin's avatar Maria Marin

Upload New File

parent 17913b69
#! /usr/bin/env python
"""
# ---------------------------------------------------------------------------
#
# funciones_network_science.py
#
# Archivo con todas las funciones que he utilizado para aplicar métricas de
# ciencia de redes a redes bipartitas y proyectadas.
#
# TFG: Ciencia de redes y reposicionamiento de fármacos: potencial a través
# de la medicina de redes
#
# María Marín Tercero
# ----------------------------------------------------------------------------
"""
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import networkx as nx
from networkx.algorithms import bipartite
import nxpd
# =================================================================================
def asociaciones(archivo, var1, var2, nombre_var1, nombre_var2, ax):
"""
Esta función toma un archivo que representa asociaciones entre dos grupos disjuntos de nodos. Finalmente, representa en un histograma la distribución del número de asociaciones de un grupo de nodos con nodos de la otra clase.
Datos de entrada:
1. archivo: Archivo con asociaciones entre nodos organizado en dos columnas, una para cada grupo de nodos
2. var1: Nombre de una columna
3. var2: Nombre de la otra columna
4. nombre_var1: Nombre de los nodos representados en la columna 1
5 nombre_var2: Nombre de los nodos representados en la columna 2
6. ax: Variable empleada para la representación organizada en un subplot
"""
conteo = archivo.groupby(var1)[var2].count().reset_index() #cuento el número de asociaciones del grupo var1 con el grupo var2
#Represento los resultados
ax.hist(conteo[var2], bins=20, color='#79C4FF', edgecolor='black')
ax.set_xlabel('Nº de ' + nombre_var2, fontsize=12)
ax.set_ylabel(nombre_var1, fontsize=12)
ax.set_title('Distribución de '+ r'$\mathbf{' + nombre_var2 + '}$' + " por " + r'$\mathbf{' + nombre_var1 + '}$' , fontsize=12)
# =================================================================================
def matriz_spl_enfermedades_bip(archivo, graf):
"""
Esta función genera una matriz bidimensional que contiene los Shortest Path
Lenghts de todos los nodos enfermedades de una red bipartita compuesta por dos
grupos disjuntos de nodos.
Datos de entrada:
1. archivo: Archivo con los datos sobre los enlaces entre los nodos de la red
2. graf: Red bipartita
"""
enfermedades = list(set(archivo['dis'])) #lista de enfermedades (columna "dis" del archivo)
matriz_spl = np.zeros((len(enfermedades), len(enfermedades))) #Inicializo una matriz de ceros para almacenar los SPL
#Calculo los SPL entre todas las parejas de enfermedades
for i in range(len(enfermedades)): #enfermedad_i
for j in range(i + 1, len(enfermedades)): #enfermedad_i+1
enfermedad_i = enfermedades[i] #guardo el nodo enfermedad_i en la fila i de la matriz
enfermedad_j = enfermedades[j] #guardo el nodo enfermedad_i+1 en la columna j de la matriz
try: #me aseguro de que exista un camino entre ambas enfermedades
spl = nx.shortest_path_length(graf, source=enfermedad_i, target=enfermedad_j) #calculo su spl
matriz_spl[i, j] = spl #añado el valor a la matriz en su posición correspondiente
matriz_spl[j, i] = spl #añado el valor a la matriz en su posición correspondiente
except nx.NetworkXNoPath: #si no hay camino, continúo
pass
#Creo un DataFrame con la matriz de SPLs
df_matriz_spl = pd.DataFrame(matriz_spl, index=enfermedades, columns=enfermedades)
return df_matriz_spl
# =================================================================================
def matriz_spl_var_bip(archivo, graf, nombre_var):
"""
Esta función genera una matriz bidimensional que contiene los Shortest Path
Lenghts para el grupo de nodos distinto a enfermedades en una red bipartita
que contiene dos grupos diferenets de nodos, siendo uno enfermedades. El otro
grupo varía en función de la red.
Datos de entrada:
1. archivo: Archivo con los datos sobre los enlaces entre los nodos de la red
2. graf: Red bipartita
3. nombre_var: Identificador del grupo de nodos distinto a enfermedades en el archivo
"""
var = list(set(archivo[str(nombre_var)])) #lista de nodos del grupo disjunto a enfermedades (columna con el identificador añadido en los datos de entrada)
matriz_spl = np.zeros((len(var), len(var))) #Inicializo una matriz de ceros para almacenar los SPL
#Calculo los SPL entre todas las parejas de los nodos seleccionados
for i in range(len(var)): #nodos_i
for j in range(i + 1, len(var)): #nodo_i+1
var_i = var[i] #guardo el nodo_i en la fila i de la matriz
var_j = var[j] #guardo el nodo_i+1 en la columna j de la matriz
try: #me aseguro de que exista un camino entre ambos nodos
spl = nx.shortest_path_length(graf, source=var_i, target=var_j) #calculo su spl
matriz_spl[i, j] = spl #añado el valor a la matriz en su posición correspondiente
matriz_spl[j, i] = spl #añado el valor a la matriz en su posición correspondiente
except nx.NetworkXNoPath: #si no hay camino, continúo
pass
#Creo un DataFrame con la matriz de SPLs
df_matriz_spl = pd.DataFrame(matriz_spl, index=var, columns=var)
return df_matriz_spl
# =================================================================================
def matriz_spl_enfermedades_proj(archivo, graf):
"""
Esta función genera una matriz bidimensional que contiene los Shortest Path
Lenghts para las enfermedades en una red proyectada.
Datos de entrada:
1. archivo: Archivo con los datos sobre los enlaces entre los nodos de la red
2. graf: Red bipartita
"""
all_shortest_paths = dict(nx.all_pairs_shortest_path_length(graf)) #creo un diccionario con los spls entre todas las parejas de nodos de la red
enfermedades = list(graf.nodes) # Obtengo la lista de nodos enfermedades
matriz_spl = np.zeros((len(enfermedades), len(enfermedades))) #Inicializo una matriz de ceros para almacenar los SPL
for i, enfermedad_i in enumerate(enfermedades): #enfermedad_i
for j, enfermedad_j in enumerate(enfermedades): #enfermedad_j
matriz_spl[i, j] = all_shortest_paths[enfermedad_i].get(enfermedad_j, 0) #añado a la matriz el spl entre la enfermedad_i y la enfermedad_j según el diccionario con el total de spls
#Creo un DataFrame con la matriz de SPLs
df_matriz_spl = pd.DataFrame(matriz_spl, index=enfermedades, columns=enfermedades)
return df_matriz_spl
# =================================================================================
def degree_bip(graf, archivo, nombre_graf, nombre_var, ax, ax1):
"""
Esta función calcula y representa la distribución de grados de dos
grupos disjuntos de nodos en una red bipartita, siendo uno de esos grupos
el correspondiente a enfermedades
Datos de entrada:
1. graf: Red bipartita
2. archivo: Archivo con los datos sobre los enlaces entre los nodos de la red
3. nombre_graf: Nombre de la red
4. nombre_var: Nombre del grupo disjunto de nodos distinto a enfermedades
5. ax: Variable empleada para la representación organizada de la primera distribución en un subplot
6. ax1: Variable empleada para la representación organizada de la segunda distribución en un subplot
"""
degrees_dict = dict(graf.degree()) # diccionario con los grados de los nodos del grafo
nodos_enf = set(archivo.iloc[:, 0]) # selecciono el set de nodos enfermedades en el archivo (que se encuentran en la primera columna)
nodos_var = set(archivo.iloc[:, 1]) # selecciono el set de nodos del grupo variable en el archivo (que se encuentran en la segunda columna)
# Filtro los degrees para nodos de enfermedades y variables
degree_enf = [degrees_dict[clave] for clave in nodos_enf if clave in degrees_dict]
degree_var = [degrees_dict[clave] for clave in nodos_var if clave in degrees_dict]
# Represento la distribución de grados de las enfermedades
G_lista_enf = pd.DataFrame(list(zip(nodos_enf, degree_enf)), columns=['node', 'degree'])
G_plot_enf = G_lista_enf.groupby('degree').count()
ax.scatter(G_plot_enf.index, G_plot_enf['node'], marker='o', color='#79C4FF', s=10)
ax.set_yscale('log')
ax.set_xscale('log')
ax.set_xlabel('Grado', fontsize=10)
ax.set_ylabel('Nº nodos', fontsize=10)
ax.set_title('Distribución de grados de ' + r'$\mathbf{' + "enfermedades" + '}$' +' en\n' + r'$\mathbf{' + "red" + '}$' + " " + r'$\mathbf{' + "bipartita" + '}$'+ " "+ r'$\mathbf{' + nombre_graf + '}$' , fontsize=12)
# Represento la distribución de grados del grupo disjunto de nodos distinto a enfermedades
G_lista_var = pd.DataFrame(list(zip(nodos_var, degree_var)), columns=['node', 'degree'])
G_plot_var = G_lista_var.groupby('degree').count()
ax1.scatter(G_plot_var.index, G_plot_var['node'], marker='o', color='#79C4FF', s=10)
ax1.set_yscale('log')
ax1.set_xscale('log')
ax1.set_xlabel('Grado', fontsize=10)
ax1.set_ylabel('Nº nodos', fontsize=10)
ax1.set_title('Distribución de grados de ' + r'$\mathbf{' + nombre_var + '}$' + ' en\n' + r'$\mathbf{' + " red" + '}$' + " "+ r'$\mathbf{' + "bipartita" + '}$'+ " " + r'$\mathbf{' + nombre_graf + '}$', fontsize=12)
# =================================================================================
def degree_proj(graf, nombre_graf, ax):
"""
Esta función calcula y representa la distribución de grados de las enfermedades
en una red proyectada.
Datos de entrada:
1. graf: Red bipartita
2. nombre_graf: Nombre de la red
3. ax: Variable empleada para la representación organizada de la distribución en un subplot
"""
degrees_dict = dict(graf.degree()) # diccionario con los grados de los nodos del grafo
nodos = list(degrees_dict.keys()) # lista con los nodos de la red (claves del diccionario anterior)
degrees = list(degrees_dict.values()) # lista con los grados de los nodos de la red (valores del diccionario anterior)
# Represento la distribución de grados
G_lista = pd.DataFrame(list(zip(nodos, degrees)), columns=['node', 'degree'])
G_plot = G_lista.groupby('degree').count()
ax.scatter(G_plot.index, G_plot['node'], marker='o', color='#79C4FF', s=10)
ax.set_yscale('log')
ax.set_xscale('log')
ax.set_xlabel('Grado', fontsize=10)
ax.set_ylabel('Nº nodos', fontsize=10)
ax.set_title('Distribución de grados de ' + r'$\mathbf{' + "enfermedades" + '}$'+ ' en\n' + r'$\mathbf{' + " red "+ '}$'+ " "+ r'$\mathbf{' + "proyectada" + '}$' + " " + r'$\mathbf{' + nombre_graf + '}$', fontsize=12)
# =================================================================================
def average_spl(matriz_spl, nombre_graf, nombre_var, ax, bipartita = True):
"""
Esta función realiza una distribución de los Average SPL d los nodos de un grafo.
Datos de entrada:
1. matriz_spl: Matriz con la información sobre los SPLs entre todas las parejas de nodos
2. nombre_graf: Nombre de la red
3. nombre_var: Nombre del tipo de nodos representado
4. ax: Variable empleada para la representación organizada de la distribución en un subplot
5. Bipartita: dependiendo de si es igualue o False, añade el título correspondiente a una red bipartita o una proyectada, respectivamente.
"""
average_spl_por_nodo = matriz_spl.mean(axis=0) #Calculo el Average_SPL de cada nodo (media de cada columna de la matriz de SPLs)
df_average_spl = pd.DataFrame({'Nodo': matriz_spl.index, 'AverageSPL': average_spl_por_nodo.values}) #creo un DataFrame con los resultados
# Represento la distribución de los Average Shortest Path Lengths
ax.hist(df_average_spl['AverageSPL'], bins=20, color='#79C4FF', edgecolor='black')
ax.set_xlabel('Average Shortest Path Lengths', style='italic', fontsize=12)
ax.set_ylabel('Nº nodos', fontsize=12)
if bipartita == True:
ax.set_title('Distribución de Average SPLs de ' + r'$\mathbf{' + nombre_var + '}$'+ ' en\n' + r'$\mathbf{' + " red "+ '}$'+ " "+ r'$\mathbf{' + "bipartita" + '}$' + " " + r'$\mathbf{' + nombre_graf + '}$', fontsize=12)
else:
ax.set_title('Distribución de Average SPLs de ' + r'$\mathbf{' + "enfermedades" + '}$'+ ' en\n' + r'$\mathbf{' + " red "+ '}$'+ " "+ r'$\mathbf{' + "proyectada" + '}$' + " " + r'$\mathbf{' + nombre_graf + '}$', fontsize=12)
# =================================================================================
def centrality_b_bip(graf, archivo, nombre_graf, nombre_var, ax, ax1):
"""
Esta función calcula y representa la distribución de centralidad de intermediación
de dos grupos disjuntos de nodos en una red bipartita, siendo uno de esos grupos
el correspondiente a enfermedades
Datos de entrada:
1. graf: Red bipartita
2. archivo: Archivo con los datos sobre los enlaces entre los nodos de la red
3. nombre_graf: Nombre de la red
4. nombre_var: Nombre del grupo disjunto de nodos distinto a enfermedades
5. ax: Variable empleada para la representación organizada de la primera distribución en un subplot
6. ax1: Variable empleada para la representación organizada de la segunda distribución en un subplot
"""
#Calculo la centralidad de intermediación de todos los nodos del grafo
bc = nx.betweenness_centrality(graf, k=None, normalized=True, weight=None, endpoints=False, seed=None)
nodos_enf = set(archivo.iloc[:, 0]) #selecciono el set de nodos enfermedades en el archivo (que se encuentran en la primera columna)
nodos_var = set(archivo.iloc[:, 1]) #selecciono el set de nodos del grupo variable en el archivo (que se encuentran en la segunda columna)
#Filtro la centralidad de intermediación para ambos grupos de nodos
bc_enf = {clave: bc[clave] for clave in nodos_enf if clave in bc}
bc_var = {clave: bc[clave] for clave in nodos_var if clave in bc}
#Creo DataFrames para la centralidad de intermediación de ambos grupos de nodos
df_bc_enf = pd.DataFrame({'Nodo': list(bc_enf.keys()), 'Centralidad de intermediación': list(bc_enf.values())})
df_bc_var = pd.DataFrame({'Nodo': list(bc_var.keys()), 'Centralidad de intermediación': list(bc_var.values())})
#Represento la centralidad de intermediación de las enfermedades
ax.hist(df_bc_enf['Centralidad de intermediación'], bins=20, color='#79C4FF', edgecolor='black')
ax.set_xlabel('Centralidad de intermediación', style='italic', fontsize=10)
ax.set_ylabel('Nº nodos', fontsize=10)
ax.set_title('Distribución de centralidad de intermediación de ' + r'$\mathbf{' + "enfermedades" + '}$' +' en\n' + r'$\mathbf{' + "red" + '}$' + " " + r'$\mathbf{' + "bipartita" + '}$'+ " "+ r'$\mathbf{' + nombre_graf + '}$' , fontsize=10)
#Represento la centralidad de intermediación del grupo disjunto de nodos distinto a enfermedades
ax1.hist(df_bc_var['Centralidad de intermediación'], bins=20, color='#79C4FF', edgecolor='black')
ax1.set_xlabel('Centralidad de intermediación', style='italic', fontsize=10)
ax1.set_ylabel('Nº nodos', fontsize=10)
ax1.set_title('Distribución de centralidad de intermediación de ' + r'$\mathbf{' + nombre_var + '}$' + ' en\n' + r'$\mathbf{' + " red" + '}$' + " "+ r'$\mathbf{' + "bipartita" + '}$'+ " " + r'$\mathbf{' + nombre_graf + '}$', fontsize=10)
# =================================================================================
def centrality_b_proj(graf, nombre_graf, ax):
"""
Esta función calcula y representa la distribución de centralidad de intermediación
de enfermedades en una red proyectada.
Datos de entrada:
1. graf: Red bipartita
2. nombre_graf: Nombre de la red
3. ax: Variable empleada para la representación organizada de la distribución en un subplot
"""
#Calculo la centralidad de intermediación de todos los nodos del grafo
bc= nx.betweenness_centrality(graf, k=None, normalized=True, weight=None, endpoints=False, seed=None)
#Creo un DataFrame para la centralidad de intermediación de las enfermedades
df_bc = pd.DataFrame({'Nodo': list(bc.keys()), 'Centralidad de intermediación': list(bc.values())})
#Represento la centralidad de intermediación de las enfermedades
ax.hist(df_bc['Centralidad de intermediación'], bins=20, color='#79C4FF', edgecolor='black')
ax.set_xlabel('Centralidad de intermediación',style='italic', fontsize=10)
ax.set_ylabel('Nº nodos', fontsize=10)
ax.set_title('Distribución de centralidad de intermediación de ' + r'$\mathbf{' + "enfermedades" + '}$'+ ' en\n' + r'$\mathbf{' + " red "+ '}$'+ " "+ r'$\mathbf{' + "proyectada" + '}$' + " " + r'$\mathbf{' + nombre_graf + '}$', fontsize=10)
# =================================================================================
def centrality_c_bip(graf, archivo, nombre_graf, nombre_var, ax, ax1):
"""
Esta función calcula y representa la distribución de centralidad de cercanía
de dos grupos disjuntos de nodos en una red bipartita, siendo uno de esos grupos
el correspondiente a enfermedades
Datos de entrada:
1. graf: Red bipartita
2. archivo: Archivo con los datos sobre los enlaces entre los nodos de la red
3. nombre_graf: Nombre de la red
4. nombre_var: Nombre del grupo disjunto de nodos distinto a enfermedades
5. ax: Variable empleada para la representación organizada de la primera distribución en un subplot
6. ax1: Variable empleada para la representación organizada de la segunda distribución en un subplot
"""
#Calculo la centralidad de intermediación de todos los nodos del grafo
cc = nx.closeness_centrality(graf, u=None, distance=None, wf_improved=True)
nodos_enf = set(archivo.iloc[:, 0]) #selecciono el set de nodos enfermedades en el archivo (que se encuentran en la primera columna)
nodos_var = set(archivo.iloc[:, 1]) #selecciono el set de nodos del grupo variable en el archivo (que se encuentran en la segunda columna)
#Filtro la centralidad de cercanía para ambos grupos de nodos
cc_enf = {clave: cc[clave] for clave in nodos_enf if clave in cc}
cc_var = {clave: cc[clave] for clave in nodos_var if clave in cc}
#Creo DataFrames para la centralidad de cercanía de ambos grupos de nodos
df_cc_enf = pd.DataFrame({'Nodo': list(cc_enf.keys()), 'Centralidad de cercanía': list(cc_enf.values())})
df_cc_var = pd.DataFrame({'Nodo': list(cc_var.keys()), 'Centralidad de cercanía': list(cc_var.values())})
#Represento la centralidad de intermediación de las enfermedades
ax.hist(df_cc_enf['Centralidad de cercanía'], bins=20, color='#79C4FF', edgecolor='black')
ax.set_xlabel('Centralidad de cercanía', style='italic', fontsize=10)
ax.set_ylabel('Nº nodos', fontsize=10)
ax.set_title('Distribución de centralidad de cercanía de ' + r'$\mathbf{' + "enfermedades" + '}$' +' en\n' + r'$\mathbf{' + "red" + '}$' + " " + r'$\mathbf{' + "bipartita" + '}$'+ " "+ r'$\mathbf{' + nombre_graf + '}$' , fontsize=10)
#Represento la centralidad de cercanía del grupo disjunto de nodos distinto a enfermedades
ax1.hist(df_cc_var['Centralidad de cercanía'], bins=20, color='#79C4FF', edgecolor='black')
ax1.set_xlabel('Centralidad de cercanía', style='italic', fontsize=10)
ax1.set_ylabel('Nº nodos', fontsize=10)
ax1.set_title('Distribución de centralidad de cercanía de ' + r'$\mathbf{' + nombre_var + '}$' + ' en\n' + r'$\mathbf{' + " red" + '}$' + " "+ r'$\mathbf{' + "bipartita" + '}$'+ " " + r'$\mathbf{' + nombre_graf + '}$', fontsize=10)
# =================================================================================
def centrality_c_proj(graf, nombre_graf,ax):
"""
Esta función calcula y representa la distribución de centralidad de cercanía
de enfermedades en una red proyectada.
Datos de entrada:
1. graf: Red bipartita
2. nombre_graf: Nombre de la red
3. ax: Variable empleada para la representación organizada de la distribución en un subplot
"""
#Calculo la centralidad de cercanía de todos los nodos del grafo
cc= nx.closeness_centrality(graf, u=None, distance=None, wf_improved=True)
#Creo un DataFrame para la centralidad de cercanía de las enfermedades
df_cc = pd.DataFrame({'Nodo': list(cc.keys()), 'Centralidad de cercanía': list(cc.values())})
#Represento la centralidad de cercanía de alas enfermedades
ax.hist(df_cc['Centralidad de cercanía'], bins=20, color='#79C4FF', edgecolor='black')
ax.set_xlabel('Centralidad de cercanía',style='italic', fontsize=10)
ax.set_ylabel('Nº nodos', fontsize=10)
ax.set_title('Distribución de centralidad de cercanía de ' + r'$\mathbf{' + "enfermedades" + '}$'+ ' en\n' + r'$\mathbf{' + " red "+ '}$'+ " "+ r'$\mathbf{' + "proyectada" + '}$' + " " + r'$\mathbf{' + nombre_graf + '}$', fontsize=10)
# =================================================================================
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment