Посчитайте появление каждого игрока по группам в Пандах - PullRequest
0 голосов
/ 07 мая 2018

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

df = pd.DataFrame({ 'Team' : ['A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C', 'C', 'C'],
                      'Player' : ['Joe', 'Mike', 'Steve', 'Henry', 'Steve', 'Joe', 'Mike', 'Joe', 'Steve', 'Dan', 'Henry']
                  })
df
Out[6]:
Player  Team
0   Joe     A
1   Mike    A
2   Steve   A
3   Henry   B
4   Steve   B
5   Joe     B
6   Mike    C
7   Joe     C
8   Steve   C
9   Dan     C
10  Henry   C

Вывод должен быть таким. П.С. Я делал это вручную, поэтому возможны ошибки.

Joe Mike 2
Joe Steve 3
Joe Henry 2
Joe Dan 1

Mike Joe 2
Mike Steve 2
Mike Dan 1
Mike Henry 1

Steve Joe 3
Steve Mike 2
Steve Henry 2
Steve Henry 1

Henry Steve 2
Henry Joe 2
Henry Mike 1
Henry Dan 1

Dan Steve 1 
Dan Mike 1
Dan Joe 1
Dan Henry 1

Объяснение : Джо появился во всех 3 командах, поэтому я просто считаю его пересечения с другими игроками между 3 командами, в которых он появляется. В то же время Дэн только в Команде C, и я принимаю во внимание только пересечения с другими игроками в Команде C.

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

gp = df.groupby('Player')['Team'].apply(lambda x: "%s" % ', '.join(x)).to_frame()

index = pd.MultiIndex.from_product([gp.index, gp.index], names = ["a", "b"])

new_df = pd.DataFrame(index = index).reset_index()

1 Ответ

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

Учитывая ваш входной DF:

df = pd.DataFrame({ 
    'Team' : ['A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C', 'C', 'C'],
    'Player' : ['Joe', 'Mike', 'Steve', 'Henry', 'Steve', 'Joe', 'Mike', 'Joe', 'Steve', 'Dan', 'Henry']
})

Вы можете объединить его против себя в столбце «Команда», чтобы получить перекрестное объединение, отфильтровать игроков с одинаковыми именами в обоих столбцах, а затем взять количество команд между парами, например:

new_df = (
    # Cartesian join dropping identical player pairs
    df.merge(df, on='Team')[lambda row: row.Player_x != row.Player_y]
    # Count unique number of overlaps and make column name a bit more usefu
    .groupby(['Player_x', 'Player_y']).Team.size().rename('shared_teams')
    # Optionally drop the index if not of use...
    .reset_index()
)

Это даст вам:

   Player_x Player_y  shared_teams
0       Dan    Henry             1
1       Dan      Joe             1
2       Dan     Mike             1
3       Dan    Steve             1
4     Henry      Dan             1
5     Henry      Joe             2
6     Henry     Mike             1
7     Henry    Steve             2
8       Joe      Dan             1
9       Joe    Henry             2
10      Joe     Mike             2
11      Joe    Steve             3
12     Mike      Dan             1
13     Mike    Henry             1
14     Mike      Joe             2
15     Mike    Steve             2
16    Steve      Dan             1
17    Steve    Henry             2
18    Steve      Joe             3
19    Steve     Mike             2

Примечание. Возможно, было бы эффективнее удалить дублированные имена после группировки, а не до этого.

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