2014-11-12 37 views
20

Czy istnieje prosty sposób sprawdzenia, czy dwie ramki danych są różnymi kopiami lub widokami tych samych podstawowych danych, które nie wymagają manipulacji? Próbuję się opanować, kiedy każdy jest generowany, i biorąc pod uwagę, jak dziwaczne wydają się te reguły, chciałbym w łatwy sposób przetestować.Sprawdzanie, czy ramka danych jest kopiowana lub wyświetlana w Pandach

Na przykład, pomyślałem „ID (df.values)” będzie stabilny w poprzek poglądów, ale nie wydają się być:

# 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 

Inne odpowiedzi Przyjrzeliśmy się, że staram się dać zasady, ale nie wydaje się spójna, a także nie odpowiedzieć na to pytanie, w jaki sposób badania:

I oczywiście: - http://pandas.pydata.org/pandas-docs/stable/indexing.html#returning-a-view-versus-a-copy

UPDATE: poniżej Komentarze wydają się odpowiedzieć na pytanie - Patrząc na atrybucie df.values.base zamiast Atrybut ten ma atrybut df.values, podobnie jak odniesienie do df._is_copy atrybut (choć ten drugi jest prawdopodobnie bardzo złą formą, ponieważ jest wewnętrzna).

+1

Hmmm, 'df2._is_view' zwraca' True', ale biorąc pod uwagę, że jest oznaczony jako prywatny/wewnętrzny, może istnieć lepszy sposób na zrobienie tego. – Marius

+1

Dla twojej sprawy, możesz użyć: 'df2.values.base to df.values.base' – HYRY

+0

Ogólnie rzecz biorąc,' df.values'' utworzy kopię, chyba że jest to pojedynczy typ dtype (jak z powodu kosztownego obliczeniowo) . Dlaczego obchodzi Cię, czy jest to widok i co tak naprawdę próbujesz zrobić? – Jeff

Odpowiedz

12

Odpowiedzi od HYRY i Mariusa w komentarzach!

Można sprawdzić poprzez:

  • badań równoważności atrybutu values.base zamiast atrybutu values, jak w:

    df.values.base is df2.values.base zamiast df.values is df2.values.

  • lub użycie (wprawdzie wewnętrznie) atrybutu _is_view (df2._is_view jest True).

Dziękuję wszystkim!

+1

Co zrobić, jeśli relacja jest zagnieżdżona? Czy to nadal działa poprawnie? Oznacza to, że jeśli DF1 jest może widokiem, może to kopia DF2; i DF2 może widok może być kopią DF3? – max

+0

Co z 'id's'? –

0

Możesz prześledzić pamięć, z której korzysta twoje środowisko pand/pyton, a przy założeniu, że kopia będzie wykorzystywać więcej pamięci niż widok, możesz zdecydować w ten czy inny sposób.

Sądzę, że istnieją biblioteki, które będą przedstawiać wykorzystanie pamięci w samym środowisku Pythona - np. Heapy/Guppy.

Powinna istnieć metryka, którą można zastosować, która pobiera podstawowy obraz zużycia pamięci przed utworzeniem obiektu pod kontrolą, a następnie kolejny obraz. Porównanie dwóch map pamięci (zakładając, że nic innego nie zostało stworzone i możemy wyizolować zmianę wynika z nowego obiektu) powinno dać wyobrażenie, czy utworzono widok lub kopię.

Musimy mieć wyobrażenie o różnych profilach pamięci każdego typu implementacji, ale niektóre eksperymenty powinny przynieść rezultaty.

Powiązane problemy