diff --git a/kloppy/domain/models/event.py b/kloppy/domain/models/event.py index 4f81bad87..c31b305ae 100644 --- a/kloppy/domain/models/event.py +++ b/kloppy/domain/models/event.py @@ -1085,10 +1085,14 @@ def _update_formations_and_positions(self): replacement_player_position = event.player.positions.last( default=PositionType.Unknown ) - event.replacement_player.set_position( - event.time, - replacement_player_position, - ) + if ( + event.replacement_player.positions.last(default=None) + is None + ): + event.replacement_player.set_position( + event.time, + replacement_player_position, + ) event.player.set_position(event.time, None) elif isinstance(event, FormationChangeEvent): diff --git a/kloppy/infra/serializers/event/statsperform/deserializer.py b/kloppy/infra/serializers/event/statsperform/deserializer.py index e7f0dc3f0..9dfac2350 100644 --- a/kloppy/infra/serializers/event/statsperform/deserializer.py +++ b/kloppy/infra/serializers/event/statsperform/deserializer.py @@ -387,6 +387,9 @@ def _parse_formation_change(raw_event: OptaEvent, team: Team) -> Dict: player_positions = {} for player_id, position_id in zip(player_ids, position_ids): player = team.get_player_by_id(player_id) + if player is None: + continue + position = positions_mapping[int(position_id)] player_positions[player] = position diff --git a/kloppy/tests/files/opta_f24.xml b/kloppy/tests/files/opta_f24.xml index 47c46c0b4..53270b19b 100644 --- a/kloppy/tests/files/opta_f24.xml +++ b/kloppy/tests/files/opta_f24.xml @@ -114,6 +114,21 @@ + + + + + + + + + + + + + + + @@ -332,6 +347,14 @@ + + + + + + + + diff --git a/kloppy/tests/test_adapter.py b/kloppy/tests/test_adapter.py index 6b9dd997c..571eb0af5 100644 --- a/kloppy/tests/test_adapter.py +++ b/kloppy/tests/test_adapter.py @@ -67,4 +67,4 @@ def list_directory( # Asserts borrowed from `test_opta.py` assert dataset.metadata.provider == Provider.OPTA assert dataset.dataset_type == DatasetType.EVENT - assert len(dataset.events) == 39 + assert len(dataset.events) == 41