Tengo dos df y quiero fusionarlos porque necesito uno df para el tablero. Mi problema es que mis datos no tienen una clave única y todos los puntos de datos se repiten. Por ejemplo, tengo df1 así:

Web       Obj
A         ObJA
A         ObjB
B         ObjA
B         ObjD
B         ObjA

Df2

Web       Lab        Cat
A         LabA       F
A         LabB       F
A         LabF       F
A         LabA       F
B         LabG       G
B         LabD       G

Quiero fusionar ambos pero no tengo clave ... Estaba pensando que puedo crear webs cada elemento 6 veces ya que los valores no excederán más de 6 ... y luego agregar los valores uno por uno ... la web extra value show "NaN" Entonces la salida se vería así

  Web        Lab        Cat            Obj
    A         LabA       F             ObJA
    A         LabB       F             ObjB
    A         LabF       F
    A         LabA       F
    A
    A
    B         LabG       G             ObjA
    B         LabD       G             ObjD
    B                                  ObjA
    B
    B
    B

¿O de cualquier otra forma ...?

-1
s_khan92 15 ene. 2021 a las 01:25

3 respuestas

La mejor respuesta

Puede crear una columna key y hacer merge de esa manera:

df2 = (df2.assign(key=df2['Web'] + (df2.groupby('Web').cumcount() + 1).astype(str))
          .merge(df1.assign(key=df1['Web'] + (df1.groupby('Web').cumcount() + 1).astype(str))
          .drop('Web', axis=1),
           on='key', how='outer'))
df2['Web']=df2['Web'].ffill()
df2
Out[1]: 
  Web   Lab  Cat key   Obj
0   A  LabA    F  A1  ObJA
1   A  LabB    F  A2  ObjB
2   A  LabF    F  A3   NaN
3   A  LabA    F  A4   NaN
4   B  LabG    G  B1  ObjA
5   B  LabD    G  B2  ObjD
6   B   NaN  NaN  B3  ObjA
1
David Erickson 14 ene. 2021 a las 22:41

Basado en el hecho de que aparentemente no hay lógica para unir las columnas "Lab" y "Obj", creo que no tiene sentido ponerlas en las mismas filas:

df = pd.concat([df1.merge(df2[['web','Cat']].drop_duplicates(), on = 'web'),
                df2]).reset_index(drop = True)
print(df)

   web   Obj Cat   Lab
0    A  ObJA   F   NaN
1    A  ObJB   F   NaN
2    B  ObJA   G   NaN
3    B  ObJD   G   NaN
4    B  ObJA   G   NaN
5    A   NaN   F  LabA
6    A   NaN   F  LabB
7    A   NaN   F  LabF
8    A   NaN   F  LabA
9    B   NaN   G  LabG
10   B   NaN   G  LabD
1
Python on Toast 14 ene. 2021 a las 22:48

Puede crear una nueva columna para facilitar la combinación:

df1["new"] = df1.groupby("Web").size().apply(range).explode().values
df2["new"] = df2.groupby("Web").size().apply(range).explode().values

df_final = df2.merge(df1, on = ["Web","new"], how = "outer")
#  Web   Lab  Cat  new   Obj
#0   A  LabA    F  0.0  ObJA
#1   A  LabB    F  1.0  ObjB
#2   A  LabF    F  2.0   NaN
#3   A  LabA    F  3.0   NaN
#4   B  LabG    G  0.0  ObjA
#5   B  LabD    G  1.0  ObjD
#6   B   NaN  NaN  2.0  ObjA

Opcionalmente, puede soltar la nueva columna y ordenar el marco de datos:

df_final.drop("new", axis = 1).sort_values(by = "Web")
1
Pablo C 14 ene. 2021 a las 23:03
65727795