Как объединить строки в кадре данных попарно, применяя некоторую функцию

avatar
Eugene Zinder
1 июля 2021 в 16:11
93
1
0

У меня есть фрейм данных, в котором хранятся ключи в виде идентификатора и некоторые числовые значения в Val1/Val2:

ID    Val1    Val2
id0     10      20
id0     11      19
id1      5       5
id1      1       1
id1      2       4

Я хотел бы просмотреть этот кадр данных и объединить строки попарно, получая средние значения Val1/Val2 для строк с одинаковым идентификатором. Суффикс должен быть добавлен к идентификатору новой строки в зависимости от того, какая это пара чисел.

Вот результирующий кадр данных:

ID      Val1    Val2
id0_1   10.5    19.5
id1_1   3       3
id1_2   1.5     2.5

В этом примере осталось только 3 строки. (id0, 10, 20) усредняется с (id0,11,19) и объединяется в одну строку.

(id1,5,5) усредняется с (id1,1,1,) и (id1,1,1) усредняется с (id1,2,4) для формирования 2 оставшихся строк.

Я могу придумать итеративный подход к этому, но это будет очень медленно. Как я мог сделать это правильным способом pythonic/pandas?

Код:

df = pd.DataFrame(columns=['ID', 'Val1', 'Val2'], data=[['id0', 10, 20], ['id0', 11, 19], ['id1', 5, 5], ['id1', 1, 1], ['id1', 2, 4]])
Источник
ifly6
1 июля 2021 в 16:14
1

Вы хотите получить среднее значение для следующей строки в группе по идентификатору?

Umar.H
1 июля 2021 в 16:15
1

можешь объяснить логику, если нет пары?

Eugene Zinder
1 июля 2021 в 16:25
0

@Umar.H всегда найдется хотя бы пара

Eugene Zinder
1 июля 2021 в 16:27
0

@ifly6 нет, он должен работать со старыми данными, которые были там раньше. так что не принимайте среднее значение против того, что уже усреднено

Ответы (1)

avatar
Corralien
1 июля 2021 в 16:20
1

Вы можете использовать df.rolling после группировки по ID:

out = df.groupby('ID').rolling(2).mean() \
        .dropna(how='all').reset_index(level=1, drop=True)

out.index += '_' + out.groupby(level=0).cumcount().add(1).astype(str)
>>> out
       Val1  Val2
id0_1  10.5  19.5
id1_1   3.0   3.0
id1_2   1.5   2.5
Eugene Zinder
1 июля 2021 в 16:26
0

это решение не обрабатывает добавление «_x», которое должно иметь место. так что id0_1, id1_1, id1_2

Corralien
1 июля 2021 в 16:42
0

@ЮджинЗиндер. Я исправил свой ответ.

Eugene Zinder
1 июля 2021 в 18:55
0

я добавил еще один столбец «Val3», к которому я хочу применить ту же логику среднего значения. при запуске вашего фрагмента столбец «Val3» не включается. Вы можете объяснить, какую часть кода нужно отредактировать?

Corralien
1 июля 2021 в 19:24
0

Вы не должны ничего изменять. df.groupby получает все столбцы. Если вы хотите выбрать определенные столбцы, выполните df.groupby('ID')[['Val1', 'Val3']].rolling(...

Eugene Zinder
1 июля 2021 в 19:32
0

Спасибо! хотя вы сказали, что df.groupby получает все столбцы, для меня это исключало Val3. Я просто указал вручную [['Val1','Val2', 'Val3']]

Corralien
1 июля 2021 в 19:45
1

Это действительно странно, так быть не должно. Фрейм данных out принимает все столбцы без исключения.