Отслеживание записи команды по игре в дф - PullRequest
0 голосов
/ 02 мая 2018

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

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

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

                 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)

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

1 Ответ

0 голосов
/ 02 мая 2018

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

Но сначала стоит уделить минутку, чтобы спросить, почему это сложно. Это выглядит как простая 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() (между прочим, совершенно pythonic. Я бы сказал, просто используйте логическое значение, но это не очень хорошо работает с .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(), а затем заполнить (теперь пустую) первую строку цифрой 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)

Последний реальный шаг - это слияние с основным фреймом данных на основе имен 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

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

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