дублировать только первую строку для каждого значения в столбце

#python #pandas #duplicates #row

#python #pandas #дублирует #строка

Вопрос:

У меня есть следующий фрейм данных:

 fake = pd.DataFrame({"group" : ["A","A","A","B","B","B","B","B","C","C"], 
                     "num" : ['1','2','3','4','5','6','7','8','9','10']})

>>> A   num
0   A   1
1   A   2
2   A   3
3   B   4
4   B   5
5   B   6
6   B   7
7   B   8
8   C   9
9   C   10
  

Я хотел бы, чтобы для каждой группы копировалась только первая строка, чтобы получить что-то вроде этого:

 >>> A   num
0   A   1
1   A   2
2   A   3
  **A   1**
3   B   4
4   B   5
5   B   6
6   B   7
7   B   8
  **B   4**
8   C   9
9   C   10
  **C   9**
  

Когда звездочки — это новые строки, которые я хотел бы иметь (копия только первой)

как я могу сделать что-то подобное? Я думал, что нужен какой-то условный дубликат, но не знал, как это сделать.

Ответ №1:

Используйте DataFrame.groupby для столбца group и агрегируйте с помощью, first затем используйте pd.concat для объединения его с исходным фреймом данных и, наконец sort_values :

 df = pd.concat([df, df.groupby('group', as_index=False).first()])
              .sort_values('group', ignore_index=True)
  

Результат:

    group num
0      A   1
1      A   2
2      A   3
3      A   1
4      B   4
5      B   5
6      B   6
7      B   7
8      B   8
9      B   4
10     C   9
11     C  10
12     C   9
  

Ответ №2:

Одна из идей заключается в использовании лямбда-функции с DataFrame.append :

 df = fake.groupby('group').apply(lambda x: x.append(x.iloc[0])).reset_index(drop=True)
print (df)
   group num
0      A   1
1      A   2
2      A   3
3      A   1
4      B   4
5      B   5
6      B   6
7      B   7
8      B   8
9      B   4
10     C   9
11     C  10
12     C   9
  

Или вы можете использовать DataFrame.drop_duplicates для первых строк изменение индекса по последним дубликатам, добавление к оригиналу по DataFrame.append и последняя сортировка значений индекса для правильных позиций:

 idx = fake.drop_duplicates('group', keep='last').index
df = (fake.append(fake.drop_duplicates('group')
                      .set_index(idx))
          .sort_index(kind='mergesort')
          .reset_index(drop=True))
print (df)
   group num
0      A   1
1      A   2
2      A   3
3      A   1
4      B   4
5      B   5
6      B   6
7      B   7
8      B   8
9      B   4
10     C   9
11     C  10
12     C   9