pandas combinations

Todas las combinaciones posibles de columnas en el marco de datos-pandas/python



combinations (4)

Estoy tratando de tomar un marco de datos y crear otro, con todas las combinaciones posibles de las columnas y la diferencia entre los valores correspondientes, es decir, en la columna AB de 11 ap debe ser (BA) = 0, etc.

por ejemplo, empezando por

Dt A B C D 11-apr 1 1 1 1 10-apr 2 3 1 2

¿Cómo obtengo un nuevo marco que se ve así:

He encontrado la publicación a continuación, pero no he podido transponer esto para trabajar en columnas.

Agregue todas las combinaciones de pares de fila de datos con pandas


Asegúrate de que tu índice sea Dt

df = df.set_index(''Dt'')

Usando numpy s np.tril_indices y slicing Vea a continuación para la explicación de np.triu_indices

v = df.values i, j = np.tril_indices(len(df.columns), -1)

Podemos crear un pd.MultiIndex para las columnas. Esto lo hace más generalizable para los nombres de columna que son más largos que un carácter.

pd.DataFrame( v[:, i] - v[:, j], df.index, [df.columns[j], df.columns[i]] ) A B A B C B C C D D D Dt 11-apr 0 0 0 0 0 0 10-apr 1 -1 -2 0 -1 1

Pero también podemos hacer

pd.DataFrame( v[:, i] - v[:, j], df.index, df.columns[j] + df.columns[i] ) AB AC BC AD BD CD Dt 11-apr 0 0 0 0 0 0 10-apr 1 -1 -2 0 -1 1

np.tril_indices explicado

Esta es una función numpy que devuelve dos matrices que, cuando se utilizan juntas, proporcionan las ubicaciones de un triángulo inferior de una matriz cuadrada. Esto es útil cuando se hacen manipulaciones de todas las combinaciones de cosas, ya que este triángulo inferior representa todas las combinaciones de un eje de una matriz con la otra.

Considere el marco de datos d para ilustración

d = pd.DataFrame(np.array(list(''abcdefghijklmnopqrstuvwxy'')).reshape(-1, 5)) d 0 1 2 3 4 0 a b c d e 1 f g h i j 2 k l m n o 3 p q r s t 4 u v w x y

Los índices triangulares, cuando se ven como pares de coordenadas, se ven así

i, j = np.tril_indices(5, -1) list(zip(i, j)) [(1, 0), (2, 0), (2, 1), (3, 0), (3, 1), (3, 2), (4, 0), (4, 1), (4, 2), (4, 3)]

Puedo manipular valores d s con i y j

d.values[i, j] = ''z'' d 0 1 2 3 4 0 a b c d e 1 z g h i j 2 z z m n o 3 z z z s t 4 z z z z y

Y puedes ver que se enfoca solo en ese triángulo inferior

prueba de tiempo ingenua


Puedes usar:

from itertools import combinations df = df.set_index(''Dt'') cc = list(combinations(df.columns,2)) df = pd.concat([df[c[1]].sub(df[c[0]]) for c in cc], axis=1, keys=cc) df.columns = df.columns.map(''''.join) print (df) AB AC AD BC BD CD Dt 11-apr 0 0 0 0 0 0 10-apr 1 -1 0 -2 -1 1


Itertools módulo Itertools debería ayudarlo a crear las combinaciones / permutaciones requeridas.

from itertools import combinations # Creating a new pd.DataFrame new_df = pd.DataFrame(index=df.index) # list of columns columns = df.columns # Create all combinations of length 2 . eg. AB, BC, etc. for combination in combinations(columns, 2): combination_string = "".join(combination) new_df[combination_string] = df[combination[1]]-df[combination[0]] print new_df AB AC AD BC BD CD Dt 11-apr 0 0 0 0 0 0 10-apr 1 -1 0 -2 -1 1


itertools.combinations lo ayudará a:

import itertools pd.DataFrame({''{}{}''.format(a, b): df[a] - df[b] for a, b in itertools.combinations(df.columns, 2)})

Lo que resulta en:

AB AC AD BC BD CD Dt 11-apr 0 0 0 0 0 0 10-apr -1 1 0 2 1 -1