Группировка данных в pandas по строкам

#python #pandas #dataframe

#python #pandas #фрейм данных

Вопрос:

У меня есть данные с такой структурой:

 id   month   val   
1    0        4
2    0        4
3    0        5
1    1        3
2    1        7
3    1        9
1    2        12
2    2        1
3    2        5
1    3        10
2    3        4
3    3        7
...
  

Я хочу получить среднее значение для каждого идентификатора, сгруппированное по двум месяцам. Ожидаемый результат:

 id   two_months    val   
1       0          3.5
2       0          5.5
3       0          7
1       1          11
2       1          2.5
3       1          6
  

Какой самый простой способ сделать это с помощью Pandas?

Ответ №1:

Если месяцы являются последовательными целыми числами, начинающимися с 0 использования целочисленного деления на 2 :

 df = df.groupby(['id',df['month'] // 2])['val'].mean().sort_index(level=[1,0]).reset_index()
print (df)
   id  month   val
0   1      0   3.5
1   2      0   5.5
2   3      0   7.0
3   1      1  11.0
4   2      1   2.5
5   3      1   6.0
  

Возможное решение с преобразованием в datetimes:

 df.index = pd.to_datetime(df['month'].add(1), format='%m')
df = df.groupby(['id', pd.Grouper(freq='2MS')])['val'].mean().sort_index(level=[1,0]).reset_index()
print (df)
   id      month   val
0   1 1900-01-01   3.5
1   2 1900-01-01   5.5
2   3 1900-01-01   7.0
3   1 1900-03-01  11.0
4   2 1900-03-01   2.5
5   3 1900-03-01   6.0
  

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

1. очень похоже, но я думаю df.groupby(["id", (df.groupby("id")["month"].cumcount()) // 2])["val"].mean().sort_index(0,1) , что это тоже сработает

2. Это сработало, спасибо. У меня есть еще один вопрос. Что делать, если я хочу избавиться от столбца месяца и иметь уникальные идентификаторы. Поэтому вместо val я хочу иметь столбец val0 — для месяца 0, val1 — для месяца 1 и т.д.

3. @Atericralf — Как вы думаете df['month'] = pd.factorize(df['month'])[0] ?

4. @jezrael не совсем. Вместо повторяющихся идентификаторов (1,2, 3, 1, 2, 3) Я хочу добавить столбцы для val для каждого месяца. Таким образом, идентификатор 1 будет содержать столбцы: id, val0, val1 и значения 1, 3.5, 11

5. @Atericralf — Я понял, нужен поворот. Используйте df.groupby(['id',df['month'] // 2])['val'].mean().unstack(fill_value=0) , верно?