Панды - это на месте = Правда считается вредным или нет?

Это обсуждалось ранее, но с противоречивыми ответами:

Что мне интересно, так это:

  • Почему inplace = False поведение по умолчанию?
  • Когда это хорошо изменить? (ну, мне разрешено это изменить, так что я думаю, что есть причина).
  • Это проблема безопасности? то есть, может ли операция потерпеть неудачу / плохо себя вести из-за inplace = True?
  • Могу ли я знать заранее, если определенный inplace = True операция "реально" будет проводиться на месте?

Мой вывод так далеко:

  • Многие операции Панд имеют inplace параметр, всегда по умолчанию FalseЭто означает, что исходный DataFrame не тронут, и операция возвращает новый DF.
  • При настройке inplace = Trueоперация может работать с исходным DF, но она все равно может работать с копией за кулисами и просто переназначить ссылку после завершения.

плюсы inplace = False:

  • Разрешает цепной / функциональный синтаксис: df.dropna().rename().sum()... это приятно, и дает возможность для ленивой оценки или более эффективного повторного заказа (хотя я не думаю, что Панда делает это).
  • Когда используешь inplace = True на объекте, который потенциально является срезом / представлением нижележащего DF, Pandas должен сделать SettingWithCopy проверить, что дорого. inplace = False избегает этого
  • Последовательное и предсказуемое поведение за кадром.

плюсы inplace = True:

  • Может быть как быстрее, так и меньше занимать память (первая ссылка показывает reset_index() работает в два раза быстрее и использует половину пиковой памяти!).

Таким образом, оставляя в стороне проблему копирования-просмотра, кажется более производительным всегда использовать inplace = True, если специально не написание цепного заявления. Но это не по умолчанию Панды, так что мне не хватает?

1 ответ

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

Да. Не просто вредно. Довольно вредно. В этом выпуске GitHub предлагаетсяinplaceАргумент будет устаревшим для api-wide в ближайшем будущем. Вкратце, здесь все не так сinplace аргумент:

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

Производительность.
Распространенное заблуждение, что использованиеinplace=Trueприведет к более эффективному или оптимизированному коду. В целом нет, там нет преимущества производительности в использовании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()

Непреднамеренные ловушки
Еще одно предостережение, о котором следует помнить, - это призыв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

Что может вызвать неожиданное поведение.

Если inplace по умолчанию, тогда DataFrame будет мутирован для всех имен, которые в данный момент ссылаются на него.

Простой пример, скажем, у меня есть df:

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

Теперь очень важно, чтобы DataFrame сохранил этот порядок строк - скажем, это из источника данных, где порядок вставки является ключевым, например.

Однако теперь мне нужно выполнить некоторые операции, требующие другого порядка сортировки:

def f(frame):
    df = frame.sort_values('a')
    # if we did frame.sort_values('a', inplace=True) here without
    # making it explicit - our caller is going to wonder what happened
    # do something
    return df

Это нормально - мой оригинал df остается такой же. Однако если inplace=True были по умолчанию, то мой оригинал df теперь будет отсортирован как побочный эффект f() в котором я должен был бы доверять вызывающему, чтобы помнить, что он не делает что-то на месте, которое я не ожидаю, вместо того, чтобы преднамеренно делать что-то на месте... Так что лучше, чтобы все, что может мутировать объект на месте, делало это явно в хотя бы сделай более очевидным, что случилось и почему.

Даже с основными встроенными в Python мутаблями вы можете наблюдать это:

data = [3, 2, 1]

def f(lst):
    lst.sort()
    # I meant lst = sorted(lst)
    for item in lst:
        print(item)

f(data)

for item in data:
    print(item)

# huh!? What happened to my data - why's it not 3, 2, 1?     
Другие вопросы по тегам