Aquí está el conjunto de datos de ejemplo

id         firstname    lastname      email               update date
A1         wendy         smith         ws@mail.com        2018-01-02
A1         wendy         smith         smith@mail.com     2019-02-03 
A2         harry         lynn          lynn@mail.com      2016-04-03
A2         harry                       harylynn@mail.com  2019-03-12
A3         tinna         dickey        tinna@mail.com     2016-04-03
A3         tinna         dickey        tinna@mail.com     2013-06-12
A4         Tom           Lee           Tom@mail.com       2012-06-12
A5         Ella                        Ella@mail.com      2019-07-12
A6         Ben           Lang          Ben@mail.com       2019-03-12

He ordenado el conjunto de datos por id y update date, quiero fusionar las filas con el mismo id, si una fila con valor vacío, complete la otra con el mismo {{X3} }, si es confuso, use el último. Para las filas sin duplicado id, deje la celda vacía como está.

La salida debe ser:

id         firstname    lastname      email               update date
A1         wendy         smith         smith@mail.com     2019-02-03 
A2         harry         lynn          harylynn@mail.com  2019-03-12
A3         tinna         dickey        tinna@mail.com     2019-03-12
A4         Tom           Lee           Tom@mail.com       2012-06-12
A5         Ella                        Ella@mail.com      2019-07-12
A6         Ben           Lang          Ben@mail.com       2019-03-12

Mi intento estaba usando ffill() para fusionar filas con vacío y mantener el último duplicado, pero el resultado parece afectar a otras celdas que deberían tener valores vacíos (como el apellido en A5 debería estar vacío).

df=df.ffill().drop_duplicates('id',keep='last')
3
user2748930 3 oct. 2019 a las 14:40

4 respuestas

La mejor respuesta

Uso

  • DataFrame.groupby - Agrupe DataFrame o Series usando un mapeador o por una Serie de columnas.
  • {{X0} }: calcula los últimos valores de grupo.
  • DataFrame.replace - Reemplace los valores dados en to_replace con valor.

Ej.

df = df.replace('',np.nan, regex=True)
df1 = df.groupby('id',as_index=False,sort=False).last()
print(df1)

   id firstname lastname              email  updatedate
0  A1     wendy    smith     smith@mail.com  2019-02-03
1  A2     harry     lynn  harylynn@mail.com  2019-03-12
2  A3     tinna   dickey     tinna@mail.com  2013-06-12
3  A4       Tom      Lee       Tom@mail.com  2012-06-12
4  A5      Ella      NaN      Ella@mail.com  2019-07-12
5  A6       Ben     Lang       Ben@mail.com  2019-03-12
1
bharatk 3 oct. 2019 a las 12:35

Prueba esto:

df.groupby('id').ffill().drop_duplicates('id', keep='last')

Salida:

   id firstname lastname              email  update date
1  A1     wendy    smith     smith@mail.com  2019-02-03 
3  A2     harry     lynn  harylynn@mail.com   2019-03-12
5  A3     tinna   dickey     tinna@mail.com   2013-06-12
6  A4       Tom      Lee       Tom@mail.com   2012-06-12
7  A5      Ella      NaN      Ella@mail.com   2019-07-12
8  A6       Ben     Lang       Ben@mail.com   2019-03-12
1
Divya Dass 3 oct. 2019 a las 12:16

Utilice GroupBy.ffill para reenviar el relleno para el mismo grupo. Luego use drop_duplicates :

df['lastname'] = df.groupby('id')['lastname'].ffill()
df = df.drop_duplicates('id', keep='last')

O en una línea (pero menos legible en mi opinión), usando assign:

df.assign(lastname=df.groupby('id')['lastname'].ffill()).drop_duplicates('id', keep='last')

Salida

   id firstname lastname              email update date
1  A1     wendy    smith     smith@mail.com  2019-02-03
3  A2     harry     lynn  harylynn@mail.com  2019-03-12
5  A3     tinna   dickey     tinna@mail.com  2013-06-12
6  A4       Tom      Lee       Tom@mail.com  2012-06-12
7  A5      Ella      NaN      Ella@mail.com  2019-07-12
8  A6       Ben     Lang       Ben@mail.com  2019-03-12
2
Erfan 3 oct. 2019 a las 12:05

Use una combinación de groupby, apply y iloc:

df.groupby('id', as_index=False).apply(lambda x: x.fillna(method='ffill').iloc[0])

   id firstname lastname              email  update date
0  A1     wendy    smith     smith@mail.com  2019-02-03
1  A2     harry     lynn  harylynn@mail.com  2019-03-12
2  A3     tinna   dickey     tinna@mail.com  2019-03-12
3  A4       Tom      Lee       Tom@mail.com  2019-06-12
4  A5      Ella      NaN      Ella@mail.com  2019-07-12
5  A6       Ben     Lang       Ben@mail.com  2019-03-12
  • groupby agrupa el marco de datos por identificadores únicos
  • fillna llena todos los valores NaN con la fila con valores no NaN
  • iloc[-1] te lleva a la fila con los últimos datos
0
adrianp 3 oct. 2019 a las 12:20
58218387