Я работаю с кадром данных pandas результатов команды:

    Team Home/Away  Home_Score   Away_Score
0   ABC   Home          2            3
1   ABC   Home          1            2
2   ABC   Away          1            3
3   ABC   Away          0            1

Я хочу создать новый столбец под названием «Результат», который возвращает победу, поражение или ничью на основе приведенных выше результатов и от того, играла ли рассматриваемая команда дома или на выезде. Я пытаюсь использовать функцию where() из numpy внутри функции, но она не применяет часть numpy, а только первую часть, которая проверяет, находится ли команда дома или в гостях. Ниже приведена моя функция и оператор лямбда:


def result(x):    
    for score in df['Home/Away']:
        
        #Home Wins
        if x == 'Home' and np.where(df['Home_Score'] > df['Away_Score']):
            return 'Win'
        
        #Home Losses
        elif x == 'Home' and np.where(df['Home_Score'] < df['Away_Score']):
            return 'Loss'

        #Away Wins
        elif x == 'Away' and np.where(df['Home_Score'] < df['Away_Score']):
            return 'Win'
        
        #Away Losses
        elif x == 'Away' and np.where(df['Home_Score'] > df['Away_Score']):
            return 'Loss'
        
        #Draws
        elif np.where(df['Home_Score'] == df['Away_Score']):
            return 'Draw'
        
df['Result'] = df.apply(lambda x: result(x['Home/Away']), axis=1)

Я не уверен, как заставить его также читать столбцы Home_Score и Away_Score и применять функцию np.where - я думал, что этого должно быть достаточно, чтобы добавить их в операторы if, но это не работает. Например, приведенный выше код возвращает Win, Win, Win, Win, когда мой ожидаемый результат для Result — Loss, Loss, Win, Win. Любая помощь будет оценена по достоинству.

0
seevans38 20 Сен 2022 в 22:02

2 ответа

Лучший ответ

Лично я бы использовал np.select(), что дает вам немного больше контроля и удобочитаемости.

condition_list = [
    (df['Home/Away'] == 'Home') & (df['Home_Score'] > df['Away_Score']),
    (df['Home/Away'] == 'Home') & (df['Home_Score'] < df['Away_Score']),
    (df['Home/Away'] == 'Away') & (df['Home_Score'] < df['Away_Score']),
    (df['Home/Away'] == 'Away') & (df['Home_Score'] > df['Away_Score']),
]

choice_list = [
    'Win',
    'Lose',
    'Win',
    'Lose'
]

df['Results'] = np.select(condition_list, choice_list, 'Draw')
df
3
ArchAngelPwn 20 Сен 2022 в 22:11
1
select это хорошо, но вы много раз бесполезно пересчитываете одно и то же, что неэффективно. Смотрите мой ответ для улучшенных подходов;)
 – 
mozway
20 Сен 2022 в 23:26
Я увижу вас и буду использовать ваш путь в будущем!
 – 
ArchAngelPwn
21 Сен 2022 в 00:08

Более простым подходом может быть:

  • вычислить знак разности баллов
  • умножить на -1, если нет дома
  • если -1 -> проигрыш, если 0 -> ничья, если 1 -> выигрыш
df['Result'] = (
 np.sign(df['Home_Score'].sub(df['Away_Score']))
   .mul(df['Home/Away'].map({'Home': 1, 'Away': -1}))
   .map({1: 'Win', 0: 'Draw', -1: 'Loss'})
 )

В качестве альтернативы, если вы хотите использовать numpy.select, вы можете упростить логику до двух условий:

  • если очки равны -> ничья
  • если логическое значение Home_Score>Away_Score равно логическому значению Home/Away == Home -> Win
    • Home and Home_Score>Away_Score -> Win
    • не дома и не дома_счет>Гостевой_счет -> также победа
  • иначе потеря
c1 = df['Home_Score'].eq(df['Away_Score'])
c2 = df['Home/Away'].eq('Home')
c3 = df['Home_Score'].gt(df['Away_Score'])
df['Result'] = np.select([c1, c2==c3], ['Draw', 'Win'], 'Loss')

Выход:

  Team Home/Away  Home_Score  Away_Score Result
0  ABC      Home           2           3   Loss
1  ABC      Home           1           2   Loss
2  ABC      Away           1           3    Win
3  ABC      Away           0           1    Win

Другой пример, чтобы показать все возможности:

  Team Home/Away  Home_Score  Away_Score Result
0  ABC      Home           2           3   Loss
1  ABC      Home           5           2    Win
2  ABC      Away           1           3    Win
3  ABC      Away           2           1   Loss
4  ABC      Home           2           2   Draw
5  ABC      Away           1           1   Draw
2
mozway 20 Сен 2022 в 23:34