2014-11-12 3 views
20

Esiste un modo semplice per verificare se due frame di dati sono copie o viste diverse degli stessi dati sottostanti che non implicano manipolazioni? Sto cercando di ottenere una presa quando ognuno viene generato, e visto quanto siano idiosincratiche le regole, mi piacerebbe un modo semplice per testare.Verifica se la cornice dati è copia o visualizza in Panda

Per esempio, ho pensato "ID (df.values)" sarebbero stabili attraverso punti di vista, ma non sembrano essere:

# 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 

altre risposte che ho guardato up che cercano di dare regole, ma non sembrano coerenti, e anche non rispondere a questa domanda di come prova:

E naturalmente: - http://pandas.pydata.org/pandas-docs/stable/indexing.html#returning-a-view-versus-a-copy

UPDATE: Commenti qui sotto sembrano rispondere alla domanda - guardando l'attributo df.values.base piuttosto che L'attributo df.values lo fa, così come un riferimento allo df._is_copy attributo (anche se quest'ultimo è probabilmente una forma molto cattiva dato che è un interno).

+1

Hmmm, 'df2._is_view' restituisce' Vero', ma dato che è contrassegnato come privato/interno, potrebbe esserci un modo migliore per farlo. – Marius

+1

Per il tuo caso, puoi usare: 'df2.values.base è df.values.base' – HYRY

+0

In generale facendo' 'df.values'' creerai una copia, a meno che non sia un singolo dtype (come dal costo computazionale) . Perché ti importa se è una visione e cosa stai cercando di fare? – Jeff

risposta

12

Le risposte di HYRY e Marius nei commenti!

Si può controllare mediante:

  • test di equivalenza dell'attributo values.base anziché l'attributo values, come in:

    df.values.base is df2.values.base anziché df.values is df2.values.

  • o utilizzando l'attributo (ammettatamente interno) _is_view (df2._is_view è True).

Grazie a tutti!

+1

Cosa succede se la relazione è nidificata? Funziona ancora correttamente? Cioè, se DF1 è forse una vista forse una copia di DF2; e DF2 forse una vista forse una copia di DF3? – max

+0

Che ne dite di 'id's'? –

0

È possibile rintracciare la memoria utilizzata dall'ambiente pandas/python e, supponendo che una copia utilizzerà più memoria di una vista, sarà in grado di decidere in un modo o nell'altro.

Credo ci siano librerie là fuori che presenteranno l'utilizzo della memoria all'interno dell'ambiente stesso di Python - ad es. Heapy/Guppy.

Ci dovrebbe essere una metrica che è possibile applicare che riprende un'immagine di base dell'uso della memoria prima di creare l'oggetto da ispezionare, quindi un'altra immagine in seguito. Il confronto tra le due mappe di memoria (supponendo che nient'altro sia stato creato e possiamo isolare il cambiamento sia dovuto al nuovo oggetto) dovrebbe fornire un'idea di se una vista o una copia è stata prodotta.

Avremmo bisogno di avere un'idea dei diversi profili di memoria di ciascun tipo di implementazione, ma alcuni esperimenti dovrebbero produrre risultati.