Pandas transform: назначить результат каждому элементу группы - PullRequest
0 голосов
/ 13 апреля 2020

В настоящее время я использую pandas groupby и transform для вычисления smth для каждой группы (один раз), а затем присваиваю результат каждой строке группы. Если результат вычислений скалярный, его можно получить следующим образом:

df['some_col'] = df.groupby('id')['some_col'].transform(lambda x:process(x))

Проблема состоит в том, что результатом моих вычислений является vector , и pd пытается выполнить поэлементное присвоение вектор результата для группы (цитата из pandas документы ):

Функция преобразования должна: Возвращать результат того же размера, что и групповой фрагмент, или передаваемый в размер группового чанка (например, скаляр, grouped.transform (lambda x: x.iloc [-1])).

Я мог бы жестко закодировать внешнюю функцию, создав список размером с группу , который будет содержать копии результата (в настоящее время python 3.6, поэтому невозможно использовать присваивание внутри лямбды):

def return_group(x):
    result = process(x)
    return [result for item in x]

Но я думаю, что это можно решить как-то "умнее". Помните, что необходимо выполнять вычисления только один раз для каждой группы.

Можно ли заставить pd.transform работать с массивом, подобным лямбда-функции, как со скалярами (просто скопируйте его n -times)?

Буду благодарен за любые советы.

PS Я понимаю, что можно использовать комбинацию apply и join для решения первоначального требования, но решение с преобразованием имеет больше приоритет в моем случае.

1 Ответ

0 голосов
/ 13 апреля 2020

Иногда с трансформацией будет трудно работать. Если это не проблема, я бы предложил вам использовать groupby + a left pd.merge, как в этом примере:

import pandas as pd
df = pd.DataFrame({"id":[1,1,2,2,2],
                   "col":[1,2,3,4,5]})

# this return a list for every group
grp = df.groupby("id")["col"]\
        .apply(lambda x: list(x))\
        .reset_index(name="out")

#  Then you merge it to the original df
df = pd.merge(df, grp, how="left")

И print(df) возвращает

   id  col        out
0   1    1     [1, 2]
1   1    2     [1, 2]
2   2    3  [3, 4, 5]
3   2    4  [3, 4, 5]
4   2    5  [3, 4, 5]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...