【问题标题】:Plot the Percent of time played together绘制一起玩的时间百分比
【发布时间】:2018-05-21 02:30:06
【问题描述】:

我希望有人能给我一个想法或解决我在下面遇到的问题的方法。我一直在试图弄清楚如何根据start timeend timeperiod(或我没有提到的任何其他统计数据)找到一个玩家与另一个玩家一起玩的百分比。我可以在数据透视表中对每个玩家的duration 求和,以查看玩家的完整冰期但对于我的生活,我似乎无法弄清楚另一个。无论是需要在 R、Excel 还是 python 脚本中,我已经用尽了我的想法。我知道这不是一个直截了当的脚本问题,但我想不出一个更好的地方来提出这个问题。我可以在示例 1 中清楚地看到 Suter 和 Dumba 在我提供的小 sn-p 数据中一起玩了两次。但是将其绘制在图表上或仅找到百分比是我寻求任何想法的地方。以下是我如何访问 OnIce 数据的 2 个示例。

示例 1. 在阶段/游戏结束时,我可以获得之前的 Line Shift 数据。玩家的姓氏将在整个 df 中出现多次。

    LastName  StartTime  EndTime  Duration ShiftNumber Period
    Foligno      0:00       0:40    0:40           1    1
    Suter        0:00       0:40    0:40           1    1
    Staal        0:00       0:40    0:40           1    1
    Niederreiter 0:00       0:40    0:40           1    1
    Dubnyk       0:00       20:00   20:00          1    1
    Dumba        0:00       0:40    0:40           1    1
    Zucker       0:40       1:26    0:46           1    1
    Koivu        0:40       1:34    0:54           1    1
    Murphy       0:40       1:26    0:46           1    1
    Brodin       0:40       1:26    0:46           1    1
    Granlund     0:40       1:39    0:59           1    1
    Reilly       1:26       2:09    0:43           1    1
    Winnik       1:26       2:18    0:52           1    1
    Coyle        1:34       2:16    0:42           1    1
    Stewart      1:39       2:13    0:34           1    1
    Dumba        2:09       2:39    0:30           2    1
    Suter        2:09       2:39    0:30           2    1

示例 2。我可以每隔几秒运行一次脚本,同时将玩家 ID 的 OnIce 保存到 csv。

HomePlayerId HomeDuration
8475744        94
8471702        74
8477944        69
8475163        74
8474651        623
8477043        74
HomePlayerId HomeDuration
8475744        111
8471702        91
8477944        86
8475163        91
8474651        640
8477043        91

【问题讨论】:

  • 能否让您的示例可重现,好吗?

标签: python r python-3.x


【解决方案1】:

下面的纯 Python 代码计算每对玩家的总重叠时间。核心思想是给定 player1 的 (start1, end1) 间隔和 player2 的 (start2, end2) ,那么这两个间隔的重叠是

overlap = min(end1, end2) - max(start1, start2)

如果 overlap

from itertools import combinations, product

#LastName   StartTime  EndTime  Duration ShiftNumber Period
data = '''\
Foligno       0:00      0:40    0:40           1    1
Suter         0:00      0:40    0:40           1    1
Staal         0:00      0:40    0:40           1    1
Niederreiter  0:00      0:40    0:40           1    1
Dubnyk        0:00      20:00   20:00          1    1
Dumba         0:00      0:40    0:40           1    1
Zucker        0:40      1:26    0:46           1    1
Koivu         0:40      1:34    0:54           1    1
Murphy        0:40      1:26    0:46           1    1
Brodin        0:40      1:26    0:46           1    1
Granlund      0:40      1:39    0:59           1    1
Reilly        1:26      2:09    0:43           1    1
Winnik        1:26      2:18    0:52           1    1
Coyle         1:34      2:16    0:42           1    1
Stewart       1:39      2:13    0:34           1    1
Dumba         2:09      2:39    0:30           2    1
Suter         2:09      2:39    0:30           2    1
'''.splitlines()

def to_secs(ms):
    ''' Convert a mm:ss string to seconds '''
    m, s = map(int, ms.split(':'))
    return 60 * m + s

# Store a list of (start, end) times for each player
players = {}
for row in data:
    name, start, end = row.split(None, 3)[:3]
    times = to_secs(start), to_secs(end)
    players.setdefault(name, []).append(times)

for t in players.items():
    print(t)
print()

# Determine the amount of overlapping time for each pair of players
for p1, p2 in combinations(sorted(players), 2):
    total = 0
    # Check each pair of times for this pair of players
    for t1, t2 in product(players[p1], players[p2]):
        # Compute the overlap in this pair of times and
        # add it to the total for this pair of players
        start, end = zip(t1, t2)
        total += max(0, min(end) - max(start))
    if total:
        print(p1, p2, total)

输出

('Foligno', [(0, 40)])
('Suter', [(0, 40), (129, 159)])
('Staal', [(0, 40)])
('Niederreiter', [(0, 40)])
('Dubnyk', [(0, 1200)])
('Dumba', [(0, 40), (129, 159)])
('Zucker', [(40, 86)])
('Koivu', [(40, 94)])
('Murphy', [(40, 86)])
('Brodin', [(40, 86)])
('Granlund', [(40, 99)])
('Reilly', [(86, 129)])
('Winnik', [(86, 138)])
('Coyle', [(94, 136)])
('Stewart', [(99, 133)])

Brodin Dubnyk 46
Brodin Granlund 46
Brodin Koivu 46
Brodin Murphy 46
Brodin Zucker 46
Coyle Dubnyk 42
Coyle Dumba 7
Coyle Granlund 5
Coyle Reilly 35
Coyle Stewart 34
Coyle Suter 7
Coyle Winnik 42
Dubnyk Dumba 70
Dubnyk Foligno 40
Dubnyk Granlund 59
Dubnyk Koivu 54
Dubnyk Murphy 46
Dubnyk Niederreiter 40
Dubnyk Reilly 43
Dubnyk Staal 40
Dubnyk Stewart 34
Dubnyk Suter 70
Dubnyk Winnik 52
Dubnyk Zucker 46
Dumba Foligno 40
Dumba Niederreiter 40
Dumba Staal 40
Dumba Stewart 4
Dumba Suter 70
Dumba Winnik 9
Foligno Niederreiter 40
Foligno Staal 40
Foligno Suter 40
Granlund Koivu 54
Granlund Murphy 46
Granlund Reilly 13
Granlund Winnik 13
Granlund Zucker 46
Koivu Murphy 46
Koivu Reilly 8
Koivu Winnik 8
Koivu Zucker 46
Murphy Zucker 46
Niederreiter Staal 40
Niederreiter Suter 40
Reilly Stewart 30
Reilly Winnik 43
Staal Suter 40
Stewart Suter 4
Stewart Winnik 34
Suter Winnik 9

【讨论】:

  • 哇,这是一个了不起的开始,感谢您花时间写这篇文章。对你的问题,如果我想一次计算超过 2 名球员,比如 6,因为通常同时有 5 名滑手和 1 名守门员 OnIce,我会在组合中添加更多吗?和 p1,p2,p3,p4,p5,p6 一样吗?
  • @MichaelTJohnson 从理论上讲,我们可以修改我的代码来处理这个问题,但它会变得相当慢,因为有 很多 种 6 种方式的组合需要通过。但我想如果程序可以识别守门员,我们可以提高效率,这样它就只创建包含 1 个守门员的组合。但是,是的,基本原则仍然有效:对于给定的一组玩家,我们从他们的结束时间的最小值中减去他们开始时间的最大值。
  • 如果我更新数据以获取我们可以写入的位置?我添加了位置。
  • @MichaelTJohnson 最好写一个新问题,并将其链接回这个问题。在得到一个或多个相关答案后更改问题是不好的。
  • 对不起,我会这样做的!谢谢楼主
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多