Панды groupBy пользовательские функции - PullRequest
0 голосов
/ 02 ноября 2018

У меня есть следующие данные, сгруппированные по идентификатору:

import pandas as pd
df_data = pd.DataFrame(data={'id': [1, 1, 1, 1, 1, 2, 2, 2, 2, 2], 
                             'period': [1, 2, 3, 4, 5, 1, 2, 3, 4, 5],
                             'feature': [1, 5, 3, 4, 8, 10, 13, 12, 15, 19]})

df_weights = pd.DataFrame(data={'id': [1, 2], 
                                'w1': [0.3, 0.25], 
                                'w2': [0.15, 0.20]})
lags = [1, 2]

Мне нужно добавить новую функцию в df_data для каждого идентификатора:

def transform_feature(df, lags, feature, feature_new, weights):

    df.loc[:, feature_new] = df[feature]

    for i, lag in enumerate(lags):

        df.loc[:, feature_new] = df.loc[:, feature_new] - df[feature].shift(lag) * weights[i]

    return df

Я могу сделать это для одного идентификатора следующим образом:

id_tmp = 1
df_data_tmp = df_data[df_data['id'] == id_tmp]
weights = df_weights[['w1', 'w2']][df_weights['id'] == id_tmp].values.tolist()[0]
df_data_subset = transform_feature(df_data_tmp, lags, 'feature', 'feature_new', weights)

Как я могу выполнить эту операцию для всех идентификаторов (для всех df_data)?

Редактировать - ожидаемый результат:

import numpy as np
df_data = pd.DataFrame(data={'id': [1, 1, 1, 1, 1, 2, 2, 2, 2, 2], 
                             'period': [1, 2, 3, 4, 5, 1, 2, 3, 4, 5], 
                             'feature': [1, 5, 3, 4, 8, 10, 13, 12, 15, 19],
                             'feature_new': [np.nan, np.nan, 1.35, 2.35, 6.35, np.nan, np.nan, 6.75, 9.40, 12.85]})

1 Ответ

0 голосов
/ 02 ноября 2018

IIUC, вы можете хитро использовать лямбду.

def transform_feature(df, lags, feature, feature_new, df_weight):
    weights = df_weights[['w1', 'w2']][df_weights['id'] == df.id.unique()[0]].values.tolist()[0]
    df[feature_new] = df[feature]
    for i, lag in enumerate(lags):
        df[feature_new] = df[feature_new] - df[feature].shift(lag) * weights[i]
    return df
df_data.groupby("id").apply(lambda x: transform_feature(x,lags,'feature','features_new',df_weights))
# Output
feature id  period  features_new
0   1   1   1   NaN
1   5   1   2   NaN
2   3   1   3   1.35
3   4   1   4   2.35
4   8   1   5   6.35
5   10  2   1   NaN
6   13  2   2   NaN
7   12  2   3   6.75
8   15  2   4   9.40
9   19  2   5   12.85

это потому, что Groupby.apply не имеет аргументов параметров, поэтому, когда вы хотите добавить параметр в вашу функцию применения, вы можете использовать лямбду. но если вы используете df.apply, вы можете просто использовать

df.apply(your_func, args=(,))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...