Как мне объединить фрейм данных pandas с сохранением всех исходных данных?

#pandas #dataframe #aggregation

#pandas #фрейм данных #агрегация

Вопрос:

Моя цель — объединить фрейм данных pandas, группируя строки по идентификационному полю. Примечательно, что вместо того, чтобы просто собирать сводную статистику группы, я хочу сохранить всю информацию в фрейме данных в дополнение к сводной статистике, такой как среднее значение, std и т. Д. Я выполнил это преобразование с помощью большого количества итераций, но я ищу более чистый / более питонический подход. Примечательно, что на группу может приходиться более или менее 2 копий, но все группы всегда будут иметь одинаковое количество копий.

Пример: я бы хотел перевести приведенный ниже формат

 df = pd.DataFrame([
    ["group1", 4, 10],
    ["group1", 8, 20],
    ["group2", 6, 30],
    ["group2", 12, 40],
    ["group3", 1, 50],
    ["group3", 3, 60]], 
  columns=['group','timeA', 'timeB'])

print(df)

    group  timeA  timeB
0  group1      4     10
1  group1      8     20
2  group2      6     30
3  group2     12     40
4  group3      1     50
5  group3      3     60
 

в df следующего формата:

 target = pd.DataFrame([
    ["group1", 4, 8, 6, 10, 20, 15],
    ["group2", 6, 12, 9, 30, 45, 35],
    ["group3", 1, 3, 2, 50, 60, 55]
], columns = ["group", "timeA.1", "timeA.2", "timeA.mean", "timeB.1", "timeB.2", "timeB.mean"])

print(target)

    group  timeA.1  timeA.2  timeA.mean  timeB.1  timeB.2  timeB.mean
0  group1        4        8           6       10       20          15
1  group2        6       12           9       30       45          35
2  group3        1        3           2       50       60          55
 

Наконец, на самом деле не имеет значения, какие имена столбцов, это просто для того, чтобы сделать пример более понятным. Спасибо!

РЕДАКТИРОВАТЬ: как было предложено пользователем в комментариях, я безуспешно попробовал решение из связанных вопросов и ответов:

 df.insert(0, 'count', df.groupby('group').cumcount())
df.pivot(*df)

TypeError: pivot() takes from 1 to 4 positional arguments but 5 were given
 

Комментарии:

1. Попробуйте решение для вопросов и ответов 10 и 11 в ссылке dup.

2. Спасибо, что рассмотрели мой вопрос. К сожалению, ответ на вопрос / Ответ 10 11 не работает, потому что pivot принимает только до 4 позиционных аргументов.

3. Пожалуйста, обновите свой вопрос тем, что вы пробовали и что не удалось. Я открою вопрос.

4. Не очень понятно, какие преобразования вы хотите выполнить, но если вы хотите сохранить структуру, обычно groupby transform может работать достаточно хорошо pandas.pydata.org/pandas-docs/stable/user_guide/groupby.html

Ответ №1:

Попробуйте с pivot_table :

 out = (df.assign(col=df.groupby('group').cumcount() 1)
   .pivot_table(index='group', columns='col', 
                margins='mean', margins_name='mean')
   .drop('mean')
)
out.columns = [f'{x}.{y}' for x,y in out.columns]
 

Вывод:

         timeA.1  timeA.2  timeA.mean  timeB.1  timeB.2  timeB.mean
group                                                             
group1      4.0      8.0         6.0       10       20          15
group2      6.0     12.0         9.0       30       40          35
group3      1.0      3.0         2.0       50       60          55