Примените функцию к кадру данных Pandas строка за строкой (axis = 0), чтобы создать четыре новых столбца - PullRequest
0 голосов
/ 08 января 2019

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

У меня большой фрейм данных, и я пытаюсь добавить в него четыре новых столбца. Значения для каждого столбца зависят от данных в строке согласно операторам 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]
          }

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Здесь есть несколько вопросов:

До, Ставка, После, Результат и т. Д. Должны быть числовыми типами, а не строками. Так что меняй их - вот так:

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)

Вот вывод:

enter image description here

0 голосов
/ 08 января 2019

сначала вам нужно изменить свою функцию, вы будете применять строку за строкой, используя: df.apply(lambda x: function(x,100,5), axis=1)

Тогда подпись вашей функции будет:

def function(row,start,stake_size):
    # Your conditions...
    return row

Осторожно! В этом случае вы манипулируете не кадром данных с помощью apply(), а строкой, поэтому вам придется адаптировать свой код в функции.

Надеюсь, это поможет!

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