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.
Надеюсь это поможет.:)