new groupby functions example create column agg python pandas group-by pycharm pandas-groupby

example - python pandas groupby apply functions



Interacción de Python entre filas y columnas en marco de datos (3)

Tengo un marco de datos:

df = pd.DataFrame({ ''exam'': [ ''French'', ''English'', ''German'', ''Russian'', ''Russian'', ''German'', ''German'', ''French'', ''English'', ''French'' ], ''student'' : [''john'', ''ted'', ''jason'', ''marc'', ''peter'', ''bob'', ''robert'', ''david'', ''nik'', ''kevin'' ] }) print (df) exam student 0 French john 1 English ted 2 German jason 3 Russian marc 4 Russian peter 5 German bob 6 German robert 7 French david 8 English nik 9 French kevin

¿Alguien sabe cómo crear un nuevo marco de datos que contenga dos columnas "estudiante" y "examen compartido de estudiante con".

Debería obtener algo como:

student shared_exam_with 0 john david 1 john kevin 2 ted nik 3 jason bob 4 jason robert 5 marc peter 6 peter marc 7 bob jason 8 bob robert 9 robert jason 10 robert bob 11 david john 12 david kevin 13 nik ted 14 kevin john 15 kevin david

Por ejemplo: John tomó francés ... ¡y David y Kevin también!

¿Algunas ideas? ¡Gracias de antemano!


Este sería un proceso de un paso en SQL, pero aquí son dos: (1) fusionar el DataFrame (en el examen) consigo mismo, y (2) deshacerse de las filas donde el estudiante == student_shared (ya que un estudiante no comparte con ellos mismos)

df2 = pd.merge( df, df, how=''outer'', on=''exam'', suffixes=['''', ''_shared_with'']).drop(''exam'', axis=1) df2 = df2.loc[df2.student != df2.student_shared_with] student student_shared_with 1 john david 2 john kevin 3 david john 5 david kevin 6 kevin john 7 kevin david 10 ted nik 11 nik ted 14 jason bob 15 jason robert 16 bob jason 18 bob robert 19 robert jason 20 robert bob 23 marc peter 24 peter marc


Una forma sería:

cross = pd.crosstab(df[''student''], df[''exam'']) res = cross.dot(cross.T) res.where(np.triu(res, k=1).astype(''bool'')).stack() Out: student student bob jason 1.0 robert 1.0 david john 1.0 kevin 1.0 jason robert 1.0 john kevin 1.0 marc peter 1.0 nik ted 1.0 dtype: float64

El producto punto genera una matriz binaria para las ocurrencias co. Para no repetir los mismos pares, los filtro con where y stack. El índice de la serie resultante son los estudiantes que tienen el mismo examen.


auto merge

df.merge( df, on=''exam'', suffixes=['''', ''_shared_with''] ).query(''student != student_shared_with'') exam student student_shared_with 1 French john david 2 French john kevin 3 French david john 5 French david kevin 6 French kevin john 7 French kevin david 10 English ted nik 11 English nik ted 14 German jason bob 15 German jason robert 16 German bob jason 18 German bob robert 19 German robert jason 20 German robert bob 23 Russian marc peter 24 Russian peter marc

auto join

d1 = df.set_index(''exam'') d1.join( d1, rsuffix=''_shared_with'' ).query(''student != student_shared_with'') student student_shared_with exam English ted nik English nik ted French john david French john kevin French david john French david kevin French kevin john French kevin david German jason bob German jason robert German bob jason German bob robert German robert jason German robert bob Russian marc peter Russian peter marc

itertools.permutations + groupby

from itertools import permutations as perm cols = [''student'', ''student_shared_with''] df.groupby(''exam'').student.apply( lambda x: pd.DataFrame(list(perm(x, 2)), columns=cols) ).reset_index(drop=True) student student_shared_with 0 ted nik 1 nik ted 2 john david 3 john kevin 4 david john 5 david kevin 6 kevin john 7 kevin david 8 jason bob 9 jason robert 10 bob jason 11 bob robert 12 robert jason 13 robert bob 14 marc peter 15 peter marc