Перебирайте строки и применяйте функцию на основе условий в существующих столбцах данных - PullRequest
1 голос
/ 17 февраля 2020

У меня есть следующий скрипт:

df = pd.DataFrame()
df["Stake"]=[0.25,0.15,0.26,0.30,0.10,0.40,0.32,0.11,0.20,0.25]
df["Odds"]=[2.5,4.0,1.75,2.2,1.85,3.2,1.5,1.2,2.15,1.65]
df["Ftr"]=["H","D","A","H","H","A","D","H","H","A"]
df["Ind"]=[1,2,2,1,3,3,3,1,2,2]

, что приводит к:

    Stake   Odds    Ftr Ind
0   0.25    2.50    H   1
1   0.15    4.00    D   2
2   0.26    1.75    A   2
3   0.30    2.20    H   1
4   0.10    1.85    H   3
5   0.40    3.20    A   3
6   0.32    1.50    D   3
7   0.11    1.20    H   1
8   0.20    2.15    H   2
9   0.25    1.65    A   2

Я хочу создать два дополнительных столбца: «Начальный баланс» и «Конечный баланс». «Старт» Баланс »в индексе 0 равен 1000.« Конечный баланс »всегда равен:

"Start Balance" - "Stake" * "Start Balance" + "Stake" x "Start Balance" x "Odds" if column "Ftr" = "H".

или

"Start Balance" - "Stake" * "Start Balance" if column "Ftr" different than "H".

Тогда следующий индекс« Стартовый баланс »становится предыдущий индекс "Конечный баланс". Например, «Конечный баланс» в индексе 0 становится «Начальным балансом» в индексе 1.

Чтобы усложнить задачу, «Начальный баланс» должен соответствовать еще одному условию. Если столбец «Ind» отличается от 1, например 2, тогда «Начальный баланс» для обеих строк (индексы 1 и 2) равен «Конечному балансу» в индексе 0. Аналогично, где «Ind» равен 3, тогда все индексы (4,5,6) должно иметь «Начальный баланс», равный «Конечному балансу» в индексе 3. Ожидаемый результат:

    Stake   Odds    Ftr Ind Start Balance   End Balance
0   0.25    2.5      H   1     1000.0          1375.0
1   0.15     4       D   2     1375.0          1168.8
2   0.26    1.75     A   2     1375.0          1017.5
3   0.3     2.2      H   1     1017.5          1383.8
4   0.1     1.85     H   3     1383.8          1501.4
5   0.4     3.2      A   3     1383.8           830.3
6   0.32    1.5      D   3     1383.8           941.0
7   0.11    1.2      H   1      941.0           961.7
8   0.2     2.15     H   2      961.7          1182.9
9   0.25    1.65     A   2      961.7           721.3

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

1 Ответ

1 голос
/ 17 февраля 2020

Я не могу придумать, как векторизованная функция делает то, что вам нужно, поэтому for l oop - единственное решение, которое я могу придумать:

# A temp dataframe to keep track of the End Balance by Ind
# It's empty to start
tmp = pd.DataFrame(columns=['index', 'End Balance']).rename_axis('ind')

for index, row in df.iterrows():
    stake, odds, ind = row['Stake'], row['Odds'], row['Ind']

    if index == 0:
        start_balance = 1000
    elif row['Ind'] == 1:
        start_balance = df.loc[index - 1, 'End Balance']
    else:
        start_balance = tmp.query('ind != @ind').sort_values('index')['End Balance'].iloc[-1]

    end_balance = start_balance * (1 - stake + stake * odds) if row['Ftr'] == 'H' else start_balance * (1 - stake)

    # Keep track of when the current Ind last occurs
    tmp.loc[ind, ['index', 'End Balance']] = [index, end_balance]

    df.loc[index, 'Start Balance'] = start_balance
    df.loc[index, 'End Balance'] = end_balance

Результат:

   Stake  Odds Ftr  Ind  Start Balance  End Balance
0   0.25  2.50   H    1    1000.000000  1375.000000
1   0.15  4.00   D    2    1375.000000  1168.750000
2   0.26  1.75   A    2    1375.000000  1017.500000
3   0.30  2.20   H    1    1017.500000  1383.800000
4   0.10  1.85   H    3    1383.800000  1501.423000
5   0.40  3.20   A    3    1383.800000   830.280000
6   0.32  1.50   D    3    1383.800000   940.984000
7   0.11  1.20   H    1     940.984000   961.685648
8   0.20  2.15   H    2     961.685648  1182.873347
9   0.25  1.65   A    2     961.685648   721.264236
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...