Усреднение каждых 10 строк одного столбца в фрейме данных, извлекая каждый десятый элемент из других?

#python #pandas #dataframe #pandas-groupby

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

Вопрос:

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

 df = pd.DataFrame({'depth': list(range(0, 21)),

                   'time': list(range(0, 21)),

                   'metric': random.choices(range(10), k=21)})
df
Out[65]: 
      depth  time  metric
0       0     0       2
1       1     1       3
2       2     2       8
3       3     3       0
4       4     4       8
5       5     5       9
6       6     6       5
7       7     7       1
8       8     8       6
9       9     9       6
10     10    10       7
11     11    11       2
12     12    12       7
13     13    13       0
14     14    14       6
15     15    15       0
16     16    16       5
17     17    17       6
18     18    18       9
19     19    19       6
20     20    20       8
 

Я хочу усреднить каждые десять строк столбца «метрика» (сохраняя первую строку как есть) и извлекая десятый элемент из столбцов глубины и времени. Например:

       depth  time  metric
0       0     0       2
10     10    10       5.3
20     20    20       4.9
 

Я знаю, что groupby обычно используется в таких ситуациях, но я не знаю, как настроить его, чтобы получить желаемый результат:

 df[['metric']].groupby(df.index //10).mean()
Out[66]: 
   metric
0     4.8
1     4.8
2     8.0
 

Ответ №1:

Ответ @BENY на правильном пути, но не совсем правильный. Должно быть:

 df.groupby((df.index 9)//10).agg({'depth':'last','time':'last','metric':'mean'})
 

Ответ №2:

Вы можете сделать rolling с reindex ffill

 df.rolling(10).mean().reindex(df.index[::10]).fillna(df)
 

     depth  time  metric
0     0.0   0.0     2.0
10    5.5   5.5     5.3
20   15.5  15.5     4.9
 

Или для сопоставления выходных данных по глубине и времени:

 out = (df.assign(metric=df['metric'].rolling(10).mean()
         .reindex(df.index[::10]).fillna(df['metric']))
         .dropna(subset=['metric']))

print(out)

    depth  time  metric
0       0     0     2.0
10     10    10     5.3
20     20    20     4.9
 

Ответ №3:

Давайте сделаем agg

 g = df.index.isin(df.index[::10]).cumsum()[::-1]
df.groupby(g).agg({'depth':'last','time':'last','metric':'mean'})
Out[263]: 
   depth  time  metric
1     20    20     4.9
2     10    10     5.3
3      0     0     2.0