Python Pandas - Понимание на месте =True

В pandas Библиотека много раз есть возможность изменить объект на месте, например, с помощью следующего оператора...

df.dropna(axis='index', how='all', inplace=True)

Мне любопытно, что возвращается, а также как обрабатывается объект, когда inplace=True прошло против когда inplace=False,

Все операции изменяются self когда inplace=True? И когда inplace=False это новый объект, созданный немедленно, такой как new_df = self а потом new_df возвращается?

3 ответа

Решение

Когда inplace=True данные переименованы на месте (ничего не возвращается), поэтому вы должны использовать:

df.an_operation(inplace=True)

когда inplace=False передается (это значение по умолчанию, поэтому не нужно), выполняет операцию и возвращает копию объекта, поэтому вы должны использовать:

df = df.an_operation(inplace=False) 

В пандах inplace = True считается вредным или нет?

TL; DR; Да да это.

  • inplace, вопреки тому, что следует из названия, часто не препятствует созданию копий и (почти) никогда не дает никаких преимуществ в производительности
  • inplace не работает с цепочкой методов
  • inplace - распространенная ошибка новичков, поэтому удаление этой опции упростит API

Я не советую устанавливать этот параметр, поскольку он не имеет большого смысла. См. Этот выпуск GitHub, в котором предлагаетсяinplace Аргумент устарел для api-wide.

Распространенное заблуждение, что использование inplace=Trueприведет к более эффективному или оптимизированному коду. На самом деле, нет абсолютно никаких преимуществ производительности в использованииinplace=True. Как версии на месте, так и версии вне места создают копию данных в любом случае, а версия на месте автоматически назначает копию обратно.

inplace=Trueэто распространенная ошибка новичков. Например, это может вызвать SettingWithCopyWarning:

df = pd.DataFrame({'a': [3, 2, 1], 'b': ['x', 'y', 'z']})

df2 = df[df['a'] > 1]
df2['b'].replace({'x': 'abc'}, inplace=True)
# SettingWithCopyWarning: 
# A value is trying to be set on a copy of a slice from a DataFrame

Вызов функции в столбце DataFrame с помощью inplace=True может работать или не работать. Это особенно верно, когда задействовано цепное индексирование.

Как будто описанных выше проблем недостаточно, inplace=Trueтакже препятствует связыванию методов. Сравните работу

result = df.some_function1().reset_index().some_function2()

В отличие от

temp = df.some_function1()
temp.reset_index(inplace=True)
result = temp.some_function2()

Первый обеспечивает лучшую организацию кода и удобочитаемость.


Еще одно подтверждающее утверждение заключается в том, что API для set_axis был недавно изменен таким образом, что inplaceзначение по умолчанию было изменено с True на False. См. GH27600. Отличные разработчики!

То, как я использую это

# Have to assign back to dataframe (because it is a new copy)
df = df.some_operation(inplace=False) 

Или же

# No need to assign back to dataframe (because it is on the same copy)
df.some_operation(inplace=True)

ЗАКЛЮЧЕНИЕ:

 if inplace is False
      Assign to a new variable;
 else
      No need to assign

В inplace параметр:

df.dropna(axis='index', how='all', inplace=True)

в Pandas и вообще означает:

1. Pandas создает копию исходных данных.

2.... выполняет на нем некоторые вычисления

3.... присваивает результаты исходным данным.

4.... удаляет копию.

Как вы можете прочитать в оставшейся части моего ответа ниже, у нас все еще может быть веская причина использовать этот параметр, т.е.inplace operations, но мы должны избегать этого, если можем, поскольку это создает больше проблем, например:

1. Ваш код будет труднее отлаживать (на самом деле SettingwithCopyWarning предупреждает вас об этой возможной проблеме)

2. Конфликт с цепочкой методов


Значит, есть даже случай, когда его еще стоит использовать?

Определенно да. Если мы используем pandas или какой-либо инструмент для обработки огромного набора данных, мы легко можем столкнуться с ситуацией, когда некоторые большие данные могут потреблять всю нашу память. Чтобы избежать этого нежелательного эффекта, мы можем использовать некоторые приемы, такие как объединение методов:

(
    wine.rename(columns={"color_intensity": "ci"})
    .assign(color_filter=lambda x: np.where((x.hue > 1) & (x.ci > 7), 1, 0))
    .query("alcohol > 14 and color_filter == 1")
    .sort_values("alcohol", ascending=False)
    .reset_index(drop=True)
    .loc[:, ["alcohol", "ci", "hue"]]
)

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

Или мы можем использовать inplaceПараметр (хотя и сложнее интерпретировать и отлаживать) потребление нашей памяти будет в 2 раза больше исходных данных, но потребление памяти после этой операции останется 1 исходными данными, что, если кто-то точно знает, что когда-либо работал с огромными наборами данных, может быть большим преимуществом.


Окончательный вывод:

Избегать использования inplace параметр, если вы не работаете с огромными данными и не знаете о возможных проблемах в случае его использования.

При попытке внести изменения в фрейм данных Pandas с помощью функции мы используем inplace=True, если мы хотим зафиксировать изменения в фреймворке данных. Следовательно, первая строка в следующем коде изменяет имя первого столбца в "df" на "Grades". Нам нужно вызвать базу данных, если мы хотим увидеть получившуюся базу данных.

df.rename(columns={0: 'Grades'}, inplace=True)
df

Мы используем inplace=False (это также значение по умолчанию), когда мы не хотим фиксировать изменения, а просто распечатываем полученную базу данных. Таким образом, фактически копия исходной базы данных с зафиксированными изменениями печатается без изменения исходной базы данных.

Для большей ясности следующие коды делают то же самое:

#Code 1
df.rename(columns={0: 'Grades'}, inplace=True)
#Code 2
df=df.rename(columns={0: 'Grades'}, inplace=False}

Я обычно использую с NumPy.

вы используете inplace=True, если вы не хотите сохранять обновленные данные в той же переменной

data["column1"].where(data["column1"]< 5, inplace=True)

это так же, как...

data["column1"] = data["column1"].where(data["column1"]< 5)

Да, в Pandas у нас много функций есть параметр inplace но по умолчанию он назначен False.

Итак, когда вы это сделаете df.dropna(axis='index', how='all', inplace=False) он думает, что вы не хотите менять оригинальный DataFrame, поэтому вместо этого он создает для вас новую копию с необходимыми изменениями.

Но когда вы меняете inplace параметр для True

Тогда это эквивалентно явному заявлению о том, что мне не нужна новая копия DataFrame вместо этого внесите изменения в данный DataFrame

Это заставляет интерпретатор Python не создавать новыйDataFrame

Но вы также можете избежать использования inplace параметр, переназначив результат исходному DataFrame

df = df.dropna(axis='index', how='all')

Насколько далеко мой опыт работы с пандами хотел бы ответить.

Аргумент inplace=True означает, что фрейм данных должен сделать изменения постоянными, например.

    df.dropna(axis='index', how='all', inplace=True)

изменяет тот же фрейм данных (поскольку эти панды находят записи NaN в индексе и удаляют их). Если мы попробуем

    df.dropna(axis='index', how='all')

pandas показывает фрейм данных с изменениями, которые мы вносим, ​​но не будет изменять исходный фрейм данных 'df'.

Если вы не используете inplace=True или используете inplace=False, вы в основном получаете копию.

Так например:

testdf.sort_values(inplace=True, by='volume', ascending=False)

изменит структуру с сортировкой данных в порядке убывания.

тогда:

testdf2 = testdf.sort_values( by='volume', ascending=True)

сделает копию testdf2. все значения будут одинаковыми, но сортировка будет обратной, и у вас будет независимый объект.

затем, учитывая другой столбец, скажите LongMA, и вы сделаете:

testdf2.LongMA = testdf2.LongMA -1

столбец LongMA в testdf будет иметь исходные значения, а testdf2 будет иметь расшифрованные значения.

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

inplace=Trueделает функцию нечистой. Он изменяет исходный фрейм данных и возвращает None. В этом случае вы разрываете цепочку DSL. Поскольку большинство функций фреймов данных возвращают новый фрейм данных, вы можете удобно использовать DSL. подобно

df.sort_values().rename().to_csv()

Вызов функции с inplace=Trueвозвращает None, и цепочка DSL разрывается. Например

df.sort_values(inplace=True).rename().to_csv()

бросит NoneType object has no attribute 'rename'

Что-то похожее на встроенную сортировку и сортировку python. lst.sort() возвращается None а также sorted(lst) возвращает новый список.

Как правило, не используйте inplace=Trueесли у вас нет особой причины для этого. Когда вам нужно написать код переназначения, напримерdf = df.sort_values(), попробуйте добавить вызов функции в цепочку DSL, например

df = pd.read_csv().sort_values()...

inplace=True используется в зависимости от того, хотите ли вы внести изменения в исходный df или нет.

df.drop_duplicates()

будет только просматривать отброшенные значения, но не вносить никаких изменений в df

df.drop_duplicates(inplace  = True)

сбросит значения и внесет изменения в df.

Надеюсь это поможет.:)

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