Панды |объединить строки с одинаковым идентификатором - PullRequest
3 голосов
/ 03 октября 2019

Вот пример набора данных

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

Я отсортировал набор данных по id и update date, я хочу объединить строки с одинаковыми id, если одна строка с пустымзначение, заполните другой с тем же id, если это не соответствует, используйте последний. Для строк без дубликатов id оставьте пустую ячейку такой, какая она есть.

выходные данные должны быть:

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

моя попытка была использовать ffill() для объединения строк с пустыми и сохранения последнего дубликата, но результат, похоже, влияет на другие ячейки, которые должны иметь пустые значения(как фамилия в A5 должна быть пустой).

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

Ответы [ 4 ]

2 голосов
/ 03 октября 2019

Используйте GroupBy.ffill только для пересылки заполнения для той же группы. Затем используйте drop_duplicates:

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

Или в одной строке (но, на мой взгляд, менее читабельно), используя assign:

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

Выход

   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 голос
/ 03 октября 2019

Попробуйте это:

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

вывод:

   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 голос
/ 03 октября 2019

Использовать

  • DataFrame.groupby - Группировать фрейм данных или серии с использованием картографа или ряда столбцов.
  • .groupby.GroupBy.last - вычислить последние значения группы.
  • DataFrame.replace - заменить значения, указанные в to_replace, значением.

Пример.

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
0 голосов
/ 03 октября 2019

Используйте комбинацию groupby, apply и 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 группирует кадр данных по уникальным идентификаторам
  • fillnaзаполняет все значения NaN в строке значениями, отличными от NaN
  • iloc[-1] возвращает строку с последними данными
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...