Отслеживание командного рекорда по игре в df

Хотите добавить столбец, в котором будет отслеживаться запись каждой команды по игре. У меня есть столбец сезона, в котором помечены каждый сезон и сезон публикации за последние несколько лет.

array(['2012-13', '2013-14', '2014-15', '2015 Post', '2015-16',
       '2016 Post', '2016-17', '2017 Post', '2013 Post', '2014 Post'], dtype=object) 

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

                 Date             Visitor  V_PTS                  Home  H_PTS  \
0 2012-10-30 19:00:00  Washington Wizards     84   Cleveland Cavaliers     94   
1 2012-10-30 19:30:00    Dallas Mavericks     99    Los Angeles Lakers     91   
2 2012-10-30 20:00:00      Boston Celtics    107            Miami Heat    120   
3 2012-10-31 19:00:00    Dallas Mavericks     94             Utah Jazz    113   
4 2012-10-31 19:00:00   San Antonio Spurs     99  New Orleans Pelicans     95   

   Attendance                    Arena                 Location  Capacity  \
0       20562      Quicken Loans Arena          Cleveland, Ohio     20562   
1       18997           Staples Center  Los Angeles, California     18997   
2       20296  American Airlines Arena           Miami, Florida     19600   
3       17634  Vivint Smart Home Arena     Salt Lake City, Utah     18303   
4       15358     Smoothie King Center   New Orleans, Louisiana     16867   

  Yr Arena Opened   Season  H_Wins  H_Losses  V_Wins  V_Losses  
0            1994  2012-13       0         0       0         0  
1            1992  2012-13       0         0       0         0  
2            1999  2012-13       0         0       0         0  
3            1991  2012-13       0         0       0         0  
4            1999  2012-13       0         0       0         0 

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

nba['Wins'] = np.where(nba['H_PTS']>nba['V_PTS'], 1, 0)
nba['Losses'] = np.where(nba['H_PTS']<nba['V_PTS'], 1, 0)

Есть ли способ заставить его добавлять себя на основе столбца в той же метке сезона?

Не могли бы вы пояснить, как должны выглядеть выходные данные для ваших образцов данных? Вы хотите, чтобы это было только для приглашенных команд или для домашних команд?

ASGM 02.05.2018 03:37

Оба. Например, первые игры всех команд будут 0-0. В следующей игре, в которой появится Кливленд, я бы хотел показать, что они 1: 0, а если они выиграют эту игру, то 2: 0 в следующей игре и так далее. Также убедитесь, что при смене сезона он снова сбрасывается до 0-0.

stretchy 02.05.2018 03:45

Спасибо - я все еще не понимаю, как должен выглядеть результат. Похоже, вам нужны не только общие выигрыши и проигрыши, но и текущий счет. Можете ли вы добавить желаемый результат в сам пост?

ASGM 02.05.2018 03:47

Хорошо, обновил. Да, мне нужна промежуточная сумма, а не просто общая сумма. По сути, эта строка всегда будет показывать только их запись на дату начала игры, если это имеет смысл.

stretchy 02.05.2018 04:05

Думаю, теперь я понимаю. В будущем попробуйте построить ожидаемый результат так, чтобы он (1) отличался от ввода и (2) действительно показывал желаемое поведение - прямо сейчас он является частью входного фрейма данных, и ни одно из желаемых вами суммирующих действий не выполняется. там.

ASGM 02.05.2018 04:07

Потрясающие. Я ценю вашу помощь и отзывы.

stretchy 02.05.2018 04:15

Рад помочь, напишу ответ сейчас (подсказка: используйте groupby() и cumsum())

ASGM 02.05.2018 04:24

Это займет немного больше времени, чем я ожидал, но ответ будет завтра. Извините за задержку.

ASGM 02.05.2018 05:23

Спасибо за помощь, я очень признателен! Это заставляет меня чувствовать себя немного лучше, потому что я застрял на этом сам, ха-ха

stretchy 02.05.2018 05:26
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
9
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это оказывается сложнее, чем кажется. Определенно есть способы упростить решение, которое я нашел, но я собираюсь изложить его шаг за шагом, чтобы было понятно, что происходит.

Но сначала стоит спросить, почему это сложно. Это похоже на простую проблему groupby(), используя .cumsum() для суммирования выигрышей и проигрышей. И если бы вы просто хотели получить результаты для команд гостей, это было бы. Но ваша проблема в том, что вы хотите выиграть на команды, период, независимо от того, в гостях они или дома.

Для этого я предлагаю разбить проблему на несколько этапов (всегда полезно, если у вас есть проблемный код).

Главный ответ

Сначала разделите свои данные на два фрейма данных, один для команд посещения, а другой - для домашних команд:

vdf = nba.set_index(['Season', 'Date', 'Visitor'])
vdf['win'] = np.where(vdf['H_PTS'] < vdf['V_PTS'], 1, 0)
vdf.index.names = ['Season', 'Date', 'Team']

hdf = nba.set_index(['Season', 'Date', 'Home'])
hdf['win'] = np.where(hdf['H_PTS'] > hdf['V_PTS'], 1, 0)
hdf.index.names = ['Season', 'Date', 'Team']

После разделения мы делаем две вещи для каждого фрейма данных. Во-первых, мы создаем столбец win, используя np.where() (кстати, отлично питонический. Я бы сказал, просто используйте логическое значение, но это не очень хорошо работает с .cumsum()). Во-вторых, мы переименовываем индекс, поэтому вместо посетителей и домашних команд мы говорим только о командах. Это важно, потому что теперь мы собираемся снова объединить эти фреймы данных в один:

df = pd.concat([vdf, hdf])
df['loss'] = 1 - df.win
df = df.sort_index(level=['Date'])
gr = df.groupby(level=['Season', 'Team'])

Мы можем рассчитать loss для команды как простую инверсию win. Затем мы сортируем по Date - поскольку ни одна команда не может играть в две игры одновременно, это должно быть нормально. Затем мы сгруппируем по Season и Team, так как это группа, по которой вы хотите подсчитывать результаты.

Теперь довольно просто суммировать выигрыши и проигрыши:

df['wins'] = gr.win.apply(lambda g: g.shift().cumsum().fillna(0))
df['losses'] = gr.loss.apply(lambda g: g.shift().cumsum().fillna(0))

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

Но теперь у нас возникла проблема: команды хозяев и посетителей находятся в разных рядах! Чтобы исправить это, мы снова разделили их на отдельные фреймы данных и переименовали столбцы, чтобы было понятно, о посетителях мы говорим или о домашних записях.

vdf = df.dropna(subset=['Home'])[['wins', 'losses']].rename(columns=lambda c: 'V_' + c)
hdf = df.dropna(subset=['Visitor'])[['wins', 'losses']].rename(columns=lambda c: 'H_' + c)

Последний реальный шаг - это объединение обратно в основной фрейм данных на основе названий команд Visitor и Home.

nba = nba.merge(vdf.astype(int), left_on=['Season', 'Date', 'Visitor'], right_index=True)
nba = nba.merge(hdf.astype(int), left_on=['Season', 'Date', 'Home'], right_index=True)

Наконец, мы можем (при желании) создать формат W-L, о котором вы упоминаете в комментариях:

nba['V_winloss'] = nba['V_wins'].astype(str) + '-' + nba['V_losses'].astype(str)
nba['H_winloss'] = nba['H_wins'].astype(str) + '-' + nba['H_losses'].astype(str)

Сделанный! Дальнейшее ее упрощение (что определенно можно сделать) оставлено читателю в качестве упражнения.


Весь код в одном месте:

vdf = nba.set_index(['Season', 'Date', 'Visitor'])
vdf['win'] = np.where(vdf['H_PTS'] < vdf['V_PTS'], 1, 0)
vdf.index.names = ['Season', 'Date', 'Team']

hdf = nba.set_index(['Season', 'Date', 'Home'])
hdf['win'] = np.where(hdf['H_PTS'] > hdf['V_PTS'], 1, 0)
hdf.index.names = ['Season', 'Date', 'Team']

df = pd.concat([vdf, hdf])
df['loss'] = 1 - df.win
df['location'] = np.where(pd.notnull(df['Home']), 'h', 'v')
df = df.sort_index(level=['Date'])
gr = df.groupby(level=['Season', 'Team'])

df['wins'] = gr.win.apply(lambda g: g.shift().cumsum().fillna(0))
df['losses'] = gr.loss.apply(lambda g: g.shift().cumsum().fillna(0))

vdf = df.dropna(subset=['Home'])[['wins', 'losses']].rename(columns=lambda c: 'V_' + c)
hdf = df.dropna(subset=['Visitor'])[['wins', 'losses']].rename(columns=lambda c: 'H_' + c)

nba = nba.merge(vdf.astype(int), left_on=['Season', 'Date', 'Visitor'], right_index=True)
nba = nba.merge(hdf.astype(int), left_on=['Season', 'Date', 'Home'], right_index=True)

nba['V_winloss'] = nba['V_wins'].astype(str) + '-' + nba['V_losses'].astype(str)
nba['H_winloss'] = nba['H_wins'].astype(str) + '-' + nba['H_losses'].astype(str)

Пример (и несколько советов)

Всякий раз, когда у вас возникает вопрос, попробуйте создать как образец желаемого ввода, так и желаемого результата, отформатированный таким образом, чтобы респонденты могли скопировать и вставить его прямо в свой код. Этот образец должен продемонстрировать ключевые требования для вашей задачи. В вашем случае это, вероятно, будет включать команду, которая играет как дома, так и на выезде, а также несколько сезонов. Это полезное упражнение еще до того, как вы зададите вопрос - создание тестового стенда с базовыми кейсами позволяет легко проверить, работает ли код, который вы пишете, как задумано.

Я сделал образец фрейма данных, который включает эти функции. Обратите внимание, что я удалил столбцы, которые не имеют значения для рассматриваемой проблемы.

>>> nba

   Season  Date Visitor Home  V_PTS  H_PTS
0       1     1       A    E      1      2
1       1     2       B    E      1      0
2       1     3       C    E      1      2
3       1     4       D    E      1      0
4       1     5       E    A      1      2
5       1     6       E    B      1      0
6       1     7       E    C      1      2
7       1     8       E    D      1      0
8       2     9       A    E      1      2

После того, как вы подсчитаете выигрыши и проигрыши (df['losses'] = ...), вы должны проверить, правильно ли накапливаются результаты команд:

>>> print df[['wins', 'losses']].sort_index(level=['Team', 'Date']).astype(int)

                  wins  losses
Season Date Team
1      1    A        0       0
       5    A        0       1
2      9    A        0       0
1      2    B        0       0
       6    B        1       0
       3    C        0       0
       7    C        0       1
       4    D        0       0
       8    D        1       0
       1    E        0       0
       2    E        1       0
       3    E        1       1
       4    E        2       1
       5    E        2       2
       6    E        2       3
       7    E        3       3
       8    E        3       4
2      9    E        0       0

Тогда к концу вы получите вот что:

   Season  Date Visitor Home  V_PTS  H_PTS  V_wins  V_losses  H_wins  \
0       1     1       A    E      1      2       0         0       0
1       1     2       B    E      1      0       0         0       1
2       1     3       C    E      1      2       0         0       1
3       1     4       D    E      1      0       0         0       2
4       1     5       E    A      1      2       2         2       0
5       1     6       E    B      1      0       2         3       1
6       1     7       E    C      1      2       3         3       0
7       1     8       E    D      1      0       3         4       1
8       2     9       A    E      1      2       0         0       0

   H_losses V_winloss H_winloss
0         0       0-0       0-0
1         0       0-0       1-0
2         1       0-0       1-1
3         1       0-0       2-1
4         1       2-2       0-1
5         0       2-3       1-0
6         1       3-3       0-1
7         0       3-4       1-0
8         0       0-0       0-0

Вы можете просмотреть его, чтобы убедиться, что он соответствует вашему желанию.

Удивительный!! Не думаю, что я бы вообще туда попал без тебя. Отличное описание и пошаговое руководство по процессу. Я обязательно перечитаю несколько раз, чтобы лучше понять концепции. Также цените ваши отзывы для будущих публикаций. Большое вам спасибо еще раз !!

stretchy 02.05.2018 08:31

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

ASGM 02.05.2018 09:50

Другие вопросы по теме