#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