Skip to content

[STATSBOMB] Weird freeze frame player Ids #474

@UnravelSports

Description

@UnravelSports

Because of Issue #464 I figured I'd give it a try to convert StatsBomb 360 data into a TrackingDataset.

It does not seem to be super complicated, but I'm unable to convert this TrackingDataset to a dataframe.

Below is a minimal working example.

from kloppy import statsbomb
from kloppy.domain import Orientation, TrackingDataset

match_id = 3893829

statsbomb_dataset = statsbomb.load(
    event_data=f"https://raw.githubusercontent.com/statsbomb/open-data/master/data/events/{match_id}.json",
    lineup_data=f"https://raw.githubusercontent.com/statsbomb/open-data/master/data/lineups/{match_id}.json",
    three_sixty_data=f"https://raw.githubusercontent.com/statsbomb/open-data/master/data/three-sixty/{match_id}.json"
).transform(to_orientation=Orientation.STATIC_HOME_AWAY)

dataset = TrackingDataset.from_dataset(
    statsbomb_dataset.filter(
        lambda event: event.freeze_frame is not None
    ),
    lambda event: event.freeze_frame 
)

If we now run

dataset.to_df()

We get

File ~/kloppy/domain/models/common.py:1274, in Dataset.to_dict(self, orient, *columns, **named_columns)
   [1272](1272) items = defaultdict(lambda: [None] * c)
   [1273](1273) for i, record in enumerate(self.records):
-> [1274](1274)     item = transformer(record)
   [1275](1275)     for k, v in item.items():
   [1276](1276)         items[k][i] = v

File ~/kloppy/domain/services/transformers/data_record.py:76, in DataRecordToDictTransformer.__call__(self, data_record)
     [75](:75) def __call__(self, data_record: T) -> Dict[str, Any]:
---> [76](:76)     return self.converter(data_record)

File ~/kloppy/domain/services/transformers/attribute.py:283, in DefaultFrameTransformer.__call__(self, frame)
    [279](:279) for player, player_data in frame.players_data.items():
    [280](:280)     print(player, player_data)
    [281](:281)     row.update(
    [282](:282)         {
--> [283](:283)             f"{player.player_id}_x": player_data.coordinates.x
    [284](:284)             if player_data.coordinates
    [285](:285)             else None,
    [286](:286)             f"{player.player_id}_y": player_data.coordinates.y
    [287](:287)             if player_data.coordinates
    [288](:288)             else None,
    [289](:289)             f"{player.player_id}_d": player_data.distance,
    [290](:290)             f"{player.player_id}_s": player_data.speed,
    [291](:291)         }
    [292](:292)     )
    [294](:294)     if player_data.other_data:
    [295](:295)         for name, value in player_data.other_data.items():

AttributeError: 'NoneType' object has no attribute 'player_id'

This seems to happen because the Player Ids of the freeze frame players are not the same as the actual player Ids in the meta data. For example:

Player(player_id='T16803-Ef981129f-d390-4875-921c-e3c08203c2fd-3', ...),
Player(player_id='T16803-Ef981129f-d390-4875-921c-e3c08203c2fd-4', ...), 
Player(player_id='10272', ...),
Player(player_id='T16803-Ef981129f-d390-4875-921c-e3c08203c2fd-6', ...)

The only "correct" player_id is 10272 which I assume belongs to the player executing the event.

FWIW, I would love to support StatsBomb freeze frames in unravelsports, but not sure that’s doable this way.

We should probably create a to_df("rows") way to combat this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions