HOWTO · Python

Copier un tableau 2D en Python

Cet article montre comment faire une copie d'un tableau 2D en Python

Sur cette page

Pour copier des données 2D en Python, choisissez l’opération selon leur type et le partage souhaité : utilisez copy() de NumPy pour obtenir des données de tableau indépendantes, copy.deepcopy() pour copier une liste imbriquée dont les listes internes doivent elles aussi être indépendantes, ou une copie superficielle si vous souhaitez partager les objets internes. Un view() NumPy est un objet tableau distinct qui partage ses données sous-jacentes avec l’original.

Un tableau 2D organise les valeurs en lignes et en colonnes. Dans une liste de listes Python, chaque liste interne représente une ligne ; deux indices permettent de sélectionner d’abord une ligne, puis un élément de cette ligne, comme dans data[row_index][column_index].

Créer une copie de tableaux 2D avec la méthode NumPy copy()

Pour un ndarray NumPy, appelez sa méthode copy() afin de créer un tableau qui possède ses propres données. Cet exemple modifie une valeur dans la copie, puis examine les deux tableaux :

import numpy as np

original = np.array([[23, 34, 45], [24, 45, 78]])
copied = original.copy()
copied[0, 2] = 65

print("Copy:", copied.tolist())
print("Original:", original.tolist())
Copy: [[23, 34, 65], [24, 45, 78]]
Original: [[23, 34, 45], [24, 45, 78]]

L’affectation modifie copied ; le tableau d’origine conserve ses valeurs initiales. C’est le choix direct lorsque vous devez modifier indépendamment les données numériques d’un tableau. Les tableaux NumPy peuvent aussi contenir des objets Python : la copie d’un tableau de type object copie son tampon de données, mais ne copie pas récursivement les objets Python qu’il contient.

Dans la sortie, les libellés « Copy: » et « Original: » restent en anglais : ils désignent respectivement le tableau copié et le tableau d’origine.

Créer une copie d’un tableau 2D avec la fonction copy.deepcopy()

Pour une liste imbriquée en Python, copy.deepcopy() copie récursivement les listes et leur contenu. C’est utile lorsqu’une liste interne peut être modifiée après la copie :

import copy

original = [["red", "blue"], ["green", "gold"]]
copied = copy.deepcopy(original)
copied[0].append("white")

print("Copy:", copied)
print("Original:", original)
Copy: [['red', 'blue', 'white'], ['green', 'gold']]
Original: [['red', 'blue'], ['green', 'gold']]

La nouvelle liste externe et ses listes internes sont distinctes de celles d’origine ; ajouter un élément à une liste interne de copied ne modifie donc pas original. deepcopy() est utile pour les données imbriquées modifiables. Pour de grands objets ou des objets personnalisés, demandez-vous s’il est approprié de copier récursivement chaque objet référencé.

Créer une copie superficielle d’un tableau 2D en Python

Une copie superficielle crée un nouveau conteneur externe tout en conservant les références aux objets internes d’origine. Pour une liste imbriquée, copy.copy() et la méthode list.copy() appliquée à la liste externe ont ce comportement :

import copy

original = [["red", "blue"], ["green", "gold"]]
copied = copy.copy(original)
copied[0].append("white")

print("Copy:", copied)
print("Original:", original)
Copy: [['red', 'blue', 'white'], ['green', 'gold']]
Original: [['red', 'blue', 'white'], ['green', 'gold']]

Ici, les deux listes externes font référence à la même première liste interne ; l’ajout est donc visible dans les deux. Remplacer un élément de la liste externe copiée, par exemple avec copied[0] = ["black"], ne modifie que la référence de cette liste externe. Utilisez copy.deepcopy() si les listes internes doivent également être indépendantes.

view() de NumPy est une opération différente d’une copie superficielle d’une liste imbriquée en Python. Elle renvoie un objet ndarray distinct qui partage les données du tableau d’origine ; une affectation par l’intermédiaire de la vue modifie donc aussi les valeurs observées dans l’original. Pour obtenir des données NumPy indépendantes, utilisez plutôt ndarray.copy(). L’identité des objets et le partage des données sont deux questions distinctes : deux tableaux peuvent être des objets différents tout en donnant accès aux mêmes valeurs sous-jacentes.

import numpy as np

original = np.array([[24, 23, 25], [32, 43, 54]])
view = original.view()
view[0, 2] = 100

print("View:", view.tolist())
print("Original:", original.tolist())
View: [[24, 23, 100], [32, 43, 54]]
Original: [[24, 23, 100], [32, 43, 54]]