Понимание на месте = Истина


104

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

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

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

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


13
Да, inplace=Trueвозвращает None inplace=Falseвозвращает копию объекта с выполненной операцией. В документации довольно ясно сказано, есть ли что-то, что сбивает с толку с какой-то конкретной частью? СпециальноIf True, do operation inplace and return None.
EdChum

Я создаю подкласс объекта DataFrame, и с помощью такой операции, как слияние, кажется невозможным сделать это на месте ... self = self.merge(new_df, how='left', on='column2' Я не уверен, что можно переназначить себя
Аран Фрил

1
Вы правы, что DataFrame.merge не имеет inplaceаргументов. Он возвращает DataFrame, поэтому нет проблем с переназначением.
JAV

Может ли кто-нибудь еще выделить преимущества его использования с точки зрения потребления ресурсов?
markroxor 03

2
@markroxor Их действительно не так много. В некоторых случаях inplaceдействие может быть немного быстрее, поскольку на самом деле вам не нужно возвращать копию результата. Но это все. Есть гораздо больше причин не использовать его.
cs95

Ответы:


96

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

df.an_operation(inplace=True)

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

df = df.an_operation(inplace=False) 

Прав ли я, думая, что inplaceэто вариант только для методов, которые изменяют существующие данные, но не для методов, которые «изменяют» данные. Например, я могу .set_index (inplace = True), поскольку это применяет значения к существующему индексу, но не могу .reindex (inplace = True), потому что это может создать дополнительные строки в DataFrame, которых не было в предыдущем массиве. ?
ac24

4
Метод .dropna()принимает inplace=Trueи определенно может изменить фрейм данных, так что нет.
jorijnsmit

3
Здесь нужно быть осторожным. @ ac24 на самом деле более-менее правильно. Хотя dropnaвозвращает фрейм данных другой формы, он на самом деле не изменяет базовые данные - он просто возвращает маску над ним (когда inplace=False), что может привести к ужасному SettingWithCopyWarning. Только когда больше нет ссылок на старый массив значений, панды изменят форму в соответствии с маской. Лучшее практическое правило: inplaceдоступно, когда операция не требует выделения нового резервного массива значений.
BallpointBen

46

Я использую это

# 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

5
Привет @ Nabin! Это слишком ясно для всех, кто работает над Pandas и Numpy :-)
Vetrivel PS

44

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

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

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

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

Распространенное заблуждение, что использование 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 for set_axisбыл недавно изменен таким образом, что inplaceзначение по умолчанию было переключено с True на False. См. GH27600 . Отличные разработчики!


Конечно inplace=True, не работает с цепочкой и т. Д., Но это очевидно, если вы понимаете, что он делает концептуально. Лично я считаю, что это немного чище, чтобы избежать присваивания. Вы бы тоже предпочли удалить list.sortи т. Д. Из стандартной библиотеки?
Chris_Rands

4
Я не думаю, что это справедливое сравнение. Есть очевидные преимущества использования list.sort по сравнению с сортировкой. То же самое и с другими функциями на месте. Здесь нет никакой реальной пользы, цепочка методов гораздо чаще встречается в пандах, и в любом случае есть планы отказаться от этого аргумента.
cs95

Я также считаю, что это немного чище, чтобы избежать присваивания: также, например, python также list.append()находится на месте, а pandas df.append - нет (и даже не поддерживает inplace), что меня бесконечно раздражает. Вот почему я хотел бы знать, просто чтобы понять, каковы реальные преимущества - каковы очевидные преимущества использования list.sort по сравнению с сортировкой, кроме избежания присваивания? В противном случае, я думаю, здесь есть реальная выгода - я могу избежать задания, когда я лично считаю его более читаемым.
sdbbs,

1
@sdbbs list.append()добавляется к существующему списку. df.appendделает копию ваших данных (неважно, есть ли у вас 5 строк или 5 миллионов), затем добавляет новую строку в вашу копию, а затем возвращает ее. Как вы думаете, что имеет больше смысла? Что касается df.append, ИЗБЕГАЙТЕ НАСКОЛЬКО ВОЗМОЖНО . Я не думаю, что это хороший пример аргументации inplace = True, я даже не думаю, что этой функции есть место в API.
cs95,

6

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параметра, если вы не работаете с огромными данными и не знаете о возможных проблемах в случае их использования.


2

Сохраните его в той же переменной

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

Сохраните его в отдельной переменной

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

Но вы всегда можете перезаписать переменную

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

К вашему сведению: по умолчанию inplace = False


1

При попытке внести изменения в фрейм данных 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}

0

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

df.drop_duplicates()

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

df.drop_duplicates(inplace  = True)

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

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


0

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()...

предоставление точного рабочего кода с правильным форматированием действительно поможет пользователям быстрее понять ваш ответ. Просим вас сделать то же самое. Я не эксперт по пандам, поэтому не могу переформатировать ваш ответ, но настоятельно рекомендую,
Ананд Вайдья

0

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

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

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

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

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

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


0

Если вы не используете 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 будет иметь расшифрованные значения.

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


0

Да, в 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')

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.