Distancia euclidiana por pares con pandas que ignoran NaNs

Comienzo con un diccionario, que es la forma en que mis datos ya estaban formateados:

import pandas as pd dict2 = {'A': {'a':1.0, 'b':2.0, 'd':4.0}, 'B':{'a':2.0, 'c':2.0, 'd':5.0}, 'C':{'b':1.0,'c':2.0, 'd':4.0}} 

Luego lo convierto a un dataframe de pandas:

 df = pd.DataFrame(dict2) print(df) ABC a 1.0 2.0 NaN b 2.0 NaN 1.0 c NaN 2.0 2.0 d 4.0 5.0 4.0 

Por supuesto, puedo obtener la diferencia de una en una al hacer esto:

 df['A'] - df['B'] Out[643]: a -1.0 b NaN c NaN d -1.0 dtype: float64 

Descubrí cómo recorrer y calcular AA, AB, AC:

 for column in df: print(df['A'] - df[column]) a 0.0 b 0.0 c NaN d 0.0 Name: A, dtype: float64 a -1.0 b NaN c NaN d -1.0 dtype: float64 a NaN b 1.0 c NaN d 0.0 dtype: float64 

Lo que me gustaría hacer es recorrer las columnas para calcular | AB |, | AC |, y | BC | y almacenar los resultados en otro diccionario.

Quiero hacer esto para calcular la distancia euclidiana entre todas las combinaciones de columnas más adelante. Si hay una forma más fácil de hacerlo, también me gustaría verlo. Gracias.

Puede usar la transmisión numpy para calcular la distancia euclídea vectorizada (norma L2), ignorando los NaN utilizando np.nansum .

 i = df.values.T j = np.nansum((i - i[:, None]) ** 2, axis=2) ** .5 

Si quieres un DataFrame que represente una matriz de distancia, esto es lo que se vería así:

 df = (lambda v, c: pd.DataFrame(v, c, c))(j, df.columns) df ABC A 0.000000 1.414214 1.0 B 1.414214 0.000000 1.0 C 1.000000 1.000000 0.0 

df[i, j] representa la distancia entre las columnas i th y j th en el DataFrame original.

El siguiente code itera a través de columnas para calcular la diferencia.

 # Import libraries import pandas as pd import numpy as np # Create dataframe df = pd.DataFrame({'A': {'a':1.0, 'b':2.0, 'd':4.0}, 'B':{'a':2.0, 'c':2.0, 'd':5.0},'C':{'b':1.0,'c':2.0, 'd':4.0}}) df2 = pd.DataFrame() # Calculate difference clist = df.columns for i in range (0,len(clist)-1): for j in range (1,len(clist)): if (clist[i] != clist[j]): var = clist[i] + '-' + clist[j] df[var] = abs(df[clist[i]] - df[clist[j]]) # optional df2[var] = abs(df[clist[i]] - df[clist[j]]) # optional 

Salida en el mismo dataframe

 df.head() 

introduzca la descripción de la imagen aquí

Salida en un nuevo dataframe

 df2.head() 

introduzca la descripción de la imagen aquí