Какие правила использует Pandas для создания представления или копии?
Я запутался в правилах, которые использует Pandas, когда решает, что выборка из фрейма данных является копией оригинального фрейма данных или представлением оригинала.
Если у меня есть, например,
df = pd.DataFrame(np.random.randn(8,8), columns=list('ABCDEFGH'), index=range(1,9))
Я так понимаю, что query
возвращает копию, чтобы что-то вроде
foo = df.query('2 < index <= 5')
foo.loc[:,'E'] = 40
не будет влиять на исходный фрейм данных, df
. Я также понимаю, что скалярные или именованные срезы возвращают представление, так что присваивания им, такие как
df.iloc[3] = 70
или же
df.ix[1,'B':'E'] = 222
изменит df
. Но я заблудился, когда дело доходит до более сложных дел. Например,
df[df.C <= df.B] = 7654321
меняет df
, но
df[df.C <= df.B].ix[:,'B':'E']
не.
Есть ли простое правило, которое использует Панд, которое я просто скучаю? Что происходит в этих конкретных случаях; и, в частности, как я могу изменить все значения (или подмножество значений) в кадре данных, которые удовлетворяют конкретному запросу (как я пытаюсь сделать в последнем примере выше)?
Примечание: это не то же самое, что этот вопрос; и я прочитал документацию, но не просвещен ею. Я также прочитал "Связанные" вопросы по этой теме, но мне все еще не хватает простого правила, которое использует Pandas, и того, как бы я применил его, например, для изменения значений (или подмножества значений). в кадре данных, которые удовлетворяют конкретному запросу.
Ответы
Ответ 1
Вот правила последующего переопределения:
-
Все операции генерируют копию
-
Если inplace=True
, он будет изменен на месте; только некоторые операции поддерживают это
-
.loc/.iloc/.iat/.at
который устанавливает, например .loc/.iloc/.iat/.at
будет установлен на месте.
-
Индексатор, который получает объект с однотипным типом, почти всегда является представлением (в зависимости от разметки памяти это может быть и не потому, что это ненадежно). Это в основном для эффективности. (приведенный выше пример относится к .query
; он всегда будет возвращать копию, numexpr
по numexpr
)
-
Индексатор, который получает объект с несколькими типами шрифтов, всегда является копией.
Ваш пример chained indexing
df[df.C <= df.B].loc[:,'B':'E']
не гарантированно работать (и, таким образом, вы никогда не будете делать это).
Вместо этого сделайте:
df.loc[df.C <= df.B, 'B':'E']
как это быстрее и всегда будет работать
Цепная индексация - это две отдельные операции Python, и поэтому панды не могут надежно перехватить ее (вы часто получаете SettingWithCopyWarning
, но это также не определяется на 100%). Документы разработчика, которые вы указали, предлагают гораздо более полное объяснение.