Проверка, является ли фрейм данных копированием или просмотром в Pandas

Есть ли простой способ проверить, являются ли два фрейма данных разными копиями или представлениями одних и тех же базовых данных, которые не связаны с манипуляциями? Я пытаюсь понять, когда каждый из них генерируется, и с учетом того, насколько необычными кажутся правила, я бы хотел простой способ проверить.

Например, я думал, что "id(df.values)" будет стабильным во всех представлениях, но они, похоже, не являются:

# 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

Другие ответы, которые я искал, которые пытаются дать правила, но не кажутся последовательными, а также не отвечают на этот вопрос о том, как тестировать:

И конечно: - http://pandas.pydata.org/pandas-docs/stable/indexing.html

ОБНОВЛЕНИЕ: комментарии ниже, кажется, отвечают на вопрос - глядя на df.values.base атрибут, а не df.values Атрибут делает это, как и ссылка на df._is_copy атрибут (хотя последний, вероятно, очень плохая форма, так как это внутренний).

2 ответа

Решение

Ответы от HYRY и Marius в комментариях!

Можно проверить либо:

  • проверка эквивалентности values.base атрибут, а не values атрибут, как в:

    df.values.base is df2.values.base вместо df.values is df2.values,

  • или используя (по общему признанию) _is_view атрибут (df2._is_view является True).

Спасибо всем!

Я разработал этот пример с помощью pandas 1.0.1. Есть не только логическое значение_is_view атрибут, но также _is_copy который может быть None или ссылка на исходный DataFrame:

df = pd.DataFrame([[1,2,3,4],[5,6,7,8]], index = ['row1','row2'], 
        columns = ['a','b','c','d'])
df2 = df.iloc[0:2, :]
df3 = df.loc[df['a'] == 1, :]

# df is neither copy nor view
df._is_view, df._is_copy
Out[1]: (False, None)

# df2 is a view AND a copy
df2._is_view, df2._is_copy
Out[2]: (True, <weakref at 0x00000236635C2228; to 'DataFrame' at 0x00000236635DAA58>)

# df3 is not a view, but a copy
df3._is_view, df3._is_copy
Out[3]: (False, <weakref at 0x00000236635C2228; to 'DataFrame' at 0x00000236635DAA58>)

Таким образом, проверка этих двух атрибутов должна сказать вам не только о том, имеете ли вы дело с представлением или нет, но также и о том, есть ли у вас копия или "исходный" DataFrame.

См. Также эту ветку для обсуждения, объясняющего, почему вы не всегда можете предсказать, вернет ли ваш код представление или нет.

Вы могли бы проследить, сколько памяти использует ваша среда pandas / python, и, исходя из предположения, что копия будет использовать больше памяти, чем представление, сможете решить так или иначе.

Я полагаю, что есть библиотеки, которые будут представлять использование памяти в самой среде Python - например, Heapy/Guppy.

Должна быть метрика, которую вы можете применить, которая дает базовое представление об использовании памяти до создания проверяемого объекта, а затем еще одно изображение. Сравнение двух карт памяти (при условии, что больше ничего не было создано, и мы можем выделить изменения из-за нового объекта), должно дать представление о том, было ли создано представление или копия.

Нам необходимо получить представление о различных профилях памяти для каждого типа реализации, но некоторые эксперименты должны дать результаты.

Другие вопросы по тегам