Я играл с этим, но я не могу даже заставить простейшее дело работать, поэтому я собираюсь попросить помощи.
У меня большой фрейм данных, и я пытаюсь добавить в него четыре новых столбца. Значения для каждого столбца зависят от данных в строке согласно операторам if ниже.
Вот что я набросал до сих пор:
import pandas as pd
d = {'Signal': [0,1,1,0],
'Win': [False,True,False,False],
'Odds': [1.1, 1.2, 1.3, 1.4],
'Helper': [True,False,False,False],
'before': ['','','',''],
'stake':['','','',''],
'result':['','','',''],
'after':['','','','']
}
df = pd.DataFrame(d)
def function(df, start, stake_size):
'''
takes in three arguments: a dataframe, a start number as int and
stake_size as int
the function fills up before, stake, result, after columns row by row
using the IF statements below
'''
#if df['Helper']:
# df['before'] = start
#else:
# df['before'] = df['after'].shift(1)
df['before'] = start #This is so I can replicate the example
if df['Signal'] == 0:
df['stake'] = 0
df['result'] = 0
elif df['Signal'] == 1:
df['stake'] = df['before'] * (stake_size/100)
if (df['Signal'] == 1 & df['Win'] == True):
df['result'] = (df['stake'] * df['odds']) - df['stake']
else:
df['result'] = df['stake'] * -1
df['after'] = df['before'] + df['result']
return df
df.apply(function, args=(100,5), axis=1)
Достаточно сказать, что это никуда меня не приведет.
Я привык использовать .apply(function, axis=1)
для создания столбцов, но это не сработает в этом случае, так как для того, чтобы вычислять раньше, мне нужно вычислять после в той же строке. То есть. каждая строка должна быть заполнена последовательно. Вот почему я попытался подойти к этому как к функции, которая получает строку и вычисляет значения для четырех новых столбцов.
Буду признателен за любую помощь или подобные примеры, чтобы расклеить здесь. Благодарю.
РЕДАКТИРОВАТЬ: Я воспользовался советом от HakunaMaData и добавил столбец Helper к df, чтобы убедиться, что я применю первое выражение if, как я и предполагал. Сначала я думал, что .shift
будет работать здесь, но это не сработает, потому что я не могу сместить весь фрейм данных при применении вдоль строки, верно?
Есть ли другой способ, которым я могу подойти к этому?
Предполагаемый результат, который я ищу:
answer = {'Signal': [0,1,1,0],
'Win': [False,True,False,False],
'Odds': [1.1, 1.2, 1.3, 1.4],
'Helper': [True,False,False,False],
'before': [100,100,101,94.95],
'stake':[0,5,5,0],
'result':[0,1,-5,0],
'after':[100,101,95.95,95.95]
}
Здесь есть несколько вопросов:
До, Ставка, После, Результат и т.д. Должны быть числовыми типами, а не строками. Так что меняй их - вот так:
d = {'Signal': [0,1,1,0],
'Win': [False,True,False,False],
'Odds': [1.1, 1.2, 1.3, 1.4],
'before': [0]*4,
'stake':[0]*4,
'result':[0]*4,
'after':[0]*4
}
Теперь остальная часть кода обычно работает:
df = pd.DataFrame(d)
def function(df, start, stake_size):
'''
takes in three arguments: a dataframe, a start number as int and
stake_size as int
the function fills up before, stake, result, after columns row by row
using the IF statements below
'''
global after #Create a global variable to track the value in the previous row
if df.name == 0:
df['before'] = start
else:
df['before'] = after
if df['Signal'] == 0:
df['stake'] = 0
df['result'] = 0
elif df['Signal'] == 1:
df['stake'] = df['before'] * (stake_size/100)
if (df['Signal'] == 1 & df['Win'] == True):
df['result'] = (df['stake'] * df['odds']) - df['stake']
else:
df['result'] = df['stake'] * -1
df['after'] = df['before'] + df['result']
after = df['after'] #assign the value to the global variable at the end
return df
Наконец, используйте ось строки, а не ось столбца:
df.apply(function, args=(100,5), axis=1)
Вот вывод:
сначала вам нужно изменить свою функцию, вы будете применять строку за строкой, используя: df.apply(lambda x: function(x,100,5), axis=1)
Тогда ваша подпись функции будет:
def function(row,start,stake_size):
# Your conditions...
return row
Осторожно! В этом случае вы манипулируете не кадром данных с помощью apply()
а строкой, поэтому вам придется адаптировать свой код в функции.
Надеюсь это поможет !