Вычисление пропорционального взвешенного значения в определенном сегменте - PullRequest
0 голосов
/ 25 сентября 2018

Я должен выполнить следующий (или похожий) расчет в моем коде много раз, и для его выполнения требуется много времени.Мне было интересно, можно ли сделать код более питоническим (сократить время выполнения).

Я рассчитываю весовой коэффициент «loan_size», пропорциональный всем другим кредитам, имеющим тот же месяц выдачи

loan_plans['weighting'] = loan_plans.loan_size / loan_plans.apply(lambda S: loan_plans.loc[(loan_plans.origination_month == S.origination_month) 'loan_size'].sum(), axis=1)

Ниже приводится пример данных с желаемым результатом:

loan_size   origination_month   weighting
1000        01-2018             0.25
2000        02-2018             0.2
3000        01-2018             0.75
8000        02-2018             0.8

1 Ответ

0 голосов
/ 25 сентября 2018

Обновление (за обновление OP):
В вашем подходе нет ничего плохого;вместо этого вы можете использовать groupby, чтобы получить origination_month суммы, а затем выполнить взвешивание:

loan_plans = loan_plans.reset_index().merge(
    loan_plans.groupby("origination_month").loan_size.sum().reset_index(), on="origination_month"
)
loan_plans["weighting"] = loan_plans.loan_size_x / loan_plans.loan_size_y
loan_plans.sort_values("index").set_index("index")

       loan_size_x origination_month  loan_size_y  weighting
index                                                       
0             1000           01-2018         4000       0.25
1             2000           02-2018        10000       0.20
2             3000           01-2018         4000       0.75
3             8000           02-2018        10000       0.80

Косметика:

(loan_plans
    .sort_values("index")
    .set_index("index")
    .rename(columns={"loan_size_x": "loan_size"})
    .drop("loan_size_y", 1))

       loan_size origination_month  weighting
index                                        
0           1000           01-2018       0.25
1           2000           02-2018       0.20
2           3000           01-2018       0.75
3           8000           02-2018       0.80

Предыдущий ответ
Вы можете использовать div и sum, нет необходимости в apply:

loan_plans.loan_size.div(
    loan_plans.loc[loan_plans.loan_number.eq(1), "loan_size"].sum()
)

Выход:

0     0.024714
1     0.053143
2     0.012143
3     0.010929
4     0.039643
           ...

Данные:

N = 100
data = {"loan_size": np.random.randint(100, 1000, size=N), 
        "loan_number": np.random.binomial(n=1, p=.3, size=N)}
loan_plans = pd.DataFrame(data)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...