首页 > 解决方案 > Pandas 多维数据计算

问题描述

我有两个数据框存储在 nfl 比赛中进攻和防守球员的跟踪数据。我的目标是计算在比赛过程中进攻球员和最近的防守球员之间的最大距离。

举个简单的例子,我做了一些数据,其中只有三名进攻球员和两名防守球员。这是数据:

Defense
    GameTime  PlayId  PlayerId  x-coord  y-coord
0          1       1       117     20.2     20.0
1          2       1       117     21.0     19.1
2          3       1       117     21.3     18.3
3          4       1       117     22.0     17.5
4          5       1       117     22.5     17.2
5          6       1       117     23.0     16.9
6          7       1       117     23.6     16.7
7          8       2       117     25.1     34.1
8          9       2       117     25.9     34.2
9         10       2       117     24.1     34.5
10        11       2       117     22.7     34.2
11        12       2       117     21.5     34.5
12        13       2       117     21.1     37.3
13        14       3       117     21.2     44.3
14        15       3       117     20.4     44.6
15        16       3       117     21.9     42.7
16        17       3       117     21.1     41.9
17        18       3       117     20.1     41.7
18        19       3       117     20.1     41.3
19         1       1       555     40.1     17.0
20         2       1       555     40.7     18.3
21         3       1       555     41.0     19.6
22         4       1       555     41.5     18.4
23         5       1       555     42.6     18.4
24         6       1       555     43.8     18.0
25         7       1       555     44.2     15.8
26         8       2       555     41.2     37.1
27         9       2       555     42.3     36.5
28        10       2       555     45.6     36.3
29        11       2       555     47.9     35.6
30        12       2       555     47.4     31.3
31        13       2       555     46.8     31.5
32        14       3       555     47.3     40.3
33        15       3       555     47.2     40.6
34        16       3       555     44.5     40.8
35        17       3       555     46.5     41.0
36        18       3       555     47.6     41.4
37        19       3       555     47.6     41.5


Offense 
    GameTime  PlayId  PlayerId  x-coord  y-coord
0          1       1       751     30.2     15.0
1          2       1       751     31.0     15.1
2          3       1       751     31.3     15.3
3          4       1       751     32.0     15.5
4          5       1       751     31.5     15.7
5          6       1       751     33.0     15.9
6          7       1       751     32.6     15.7
7          8       2       751     51.1     30.1
8          9       2       751     51.9     30.2
9         10       2       751     51.1     30.5
10        11       2       751     49.7     30.6
11        12       2       751     49.5     30.9
12        13       2       751     49.1     31.3
13        14       3       751     12.2     40.3
14        15       3       751     12.4     40.5
15        16       3       751     12.9     40.7
16        17       3       751     13.1     40.9
17        18       3       751     13.1     41.1
18        19       3       751     13.1     41.3
19         1       1       419     41.3     15.0
20         2       1       419     41.7     15.3
21         3       1       419     41.8     15.4
22         4       1       419     42.9     15.6
23         5       1       419     42.6     15.6
24         6       1       419     44.8     16.0
25         7       1       419     45.2     15.8
26         8       2       419     62.2     30.1
27         9       2       419     63.3     30.5
28        10       2       419     62.6     31.0
29        11       2       419     63.9     30.6
30        12       2       419     67.4     31.3
31        13       2       419     66.8     31.5
32        14       3       419     30.3     40.3
33        15       3       419     30.2     40.6
34        16       3       419     30.5     40.8
35        17       3       419     30.5     41.0
36        18       3       419     31.6     41.4
37        19       3       419     31.6     41.5
38         1       1       989     10.1     15.0
39         2       1       989     10.2     15.5
40         3       1       989     10.4     15.4
41         4       1       989     10.5     15.8
42         5       1       989     10.6     15.9
43         6       1       989     10.1     15.5
44         7       1       989     10.9     15.3
45         8       2       989     25.8     30.1
46         9       2       989     25.2     30.1
47        10       2       989     21.8     30.2
48        11       2       989     25.8     30.2
49        12       2       989     25.6     30.5
50        13       2       989     25.5     31.0
51        14       3       989     50.3     40.3
52        15       3       989     50.3     40.2
53        16       3       989     50.2     40.4
54        17       3       989     50.1     40.8
55        18       3       989     50.6     41.2
56        19       3       989     51.4     41.6

数据本质上是多维的,GameTime、PlayId 和 PlayerId 作为自变量,x-coord 和 y-coord 作为因变量。在比赛过程中,如何计算与最近防守者的最大距离?

我的猜测是我必须为每个进攻球员创建包含与每个防守球员的距离的列,但我不知道如何命名这些列并且能够解释未知数量的防守/进攻球员(完整数据集包含成千上万的玩家)。

标签: python-3.xpandasdataframe

解决方案


这是一个可能的解决方案,我认为有一种方法可以提高效率:

假设您有一个名为 offence_df 的数据框和一个名为 defence_df 的数据框:

在合并的数据框中,您将得到问题的答案,基本上它将创建以下数据框:

from scipy.spatial import distance 
merged_dataframe = pd.merge(offense_df,defense_df,on=['GameTime','PlayId'],suffixes=('_off','_def'))
    GameTime    PlayId  PlayerId_off    x-coord_off y-coord_off PlayerId_def    x-coord_def y-coord_def
0   1   1   751 30.2    15.0    117 20.2    20.0
1   1   1   751 30.2    15.0    555 40.1    17.0
2   1   1   419 41.3    15.0    117 20.2    20.0
3   1   1   419 41.3    15.0    555 40.1    17.0
4   1   1   989 10.1    15.0    117 20.2    20.0

接下来的两行在这里为坐标创建一个唯一列,基本上它将为进攻方(coord_off)和防守方创建一个包含元组(x,y)的列(coord_def),这将简化距离的计算.

merged_dataframe['coord_off'] = merged_dataframe.apply(lambda x: (x['x-coord_off'], x['y-coord_off']),axis=1)
merged_dataframe['coord_def'] = merged_dataframe.apply(lambda x: (x['x-coord_def'], x['y-coord_def']),axis=1)

我们计算给定 GameTime,PlayId 到所有防守者的距离。

merged_dataframe['distance_to_def'] = merged_dataframe.apply(lambda x: distance.euclidean(x['coord_off'],x['coord_def']),axis=1)

对于每个 PlayerId、GameTime、PlayId,我们都会计算到最近防守者的距离。

smallest_dist = merged_dataframe.groupby(['GameTime','PlayId','PlayerId_off'])['distance_to_def'].min()

最后,我们为每个 PlayerId 取最大距离(这些最小距离中的)。

smallest_dist.groupby('PlayerId_off').max()

推荐阅读