web-dev-qa-db-fra.com

Vérifier si le cadre de données est copié ou visualisé dans les pandas

Existe-t-il un moyen simple de vérifier si deux trames de données sont des copies ou des vues différentes des mêmes données sous-jacentes sans aucune manipulation? J'essaie de comprendre quand chacune d'elles est générée, et étant donné à quel point les règles semblent si idiosyncratiques, j'aimerais un moyen facile de tester. 

Par exemple, je pensais que "id (df.values)" serait stable dans les vues, mais cela ne semble pas être:

# Make two data frames that are views of same data.
df = pd.DataFrame([[1,2,3,4],[5,6,7,8]], index = ['row1','row2'], 
       columns = ['a','b','c','d'])
df2 = df.iloc[0:2,:]

# Demonstrate they are views:
df.iloc[0,0] = 99
df2.iloc[0,0]
Out[70]: 99

# Now try and compare the id on values attribute
# Different despite being views! 

id(df.values)
Out[71]: 4753564496

id(df2.values)
Out[72]: 4753603728

# And we can of course compare df and df2
df is df2
Out[73]: False

Autres réponses J'ai cherché qui essaye de donner des règles, mais ne semble pas cohérent, et ne répond pas non plus à cette question de la façon de tester:

Et bien sûr: - http://pandas.pydata.org/pandas-docs/stable/indexing.html#returning-a-view-versus-a-copy

UPDATE: Les commentaires ci-dessous semblent répondre à la question. Il suffit de regarder l'attribut df.values.base plutôt que l'attribut df.values, de même qu'une référence à l'attribut df._is_copy (bien que ce dernier soit probablement très mauvais, car il s'agit d'une forme interne. ).

26
nick_eu

Réponses de HYRY et Marius dans les commentaires! 

On peut vérifier soit par:

  • tester l'équivalence de l'attribut values.base plutôt que de l'attribut values, comme dans:

    df.values.base is df2.values.base au lieu de df.values is df2.values.

  • ou en utilisant l'attribut (certes interne) _is_view (df2._is_view est True).

Merci tout le monde!

16
nick_eu

Vous pouvez suivre la mémoire consommée par votre environnement pandas/python et, en supposant qu'une copie utilisera plus de mémoire qu'une vue, vous pourrez décider d'une manière ou d'une autre. 

Je crois qu'il existe des bibliothèques qui présenteront l'utilisation de la mémoire dans l'environnement Python lui-même - par exemple. Heapy/Guppy.

Vous devez appliquer une métrique qui prend une image de base de l'utilisation de la mémoire avant de créer l'objet soumis à l'inspection, puis une autre image par la suite. La comparaison des deux cartes mémoire (en supposant que rien d'autre n'a été créé et que nous pouvons isoler le changement dû au nouvel objet) devrait permettre de déterminer si une vue ou une copie a été produite.

Nous aurions besoin de nous faire une idée des différents profils de mémoire de chaque type d'implémentation, mais certaines expériences devraient donner des résultats. 

0
Thomas Kimber