之前已经讨论过,但是答案有冲突:

  • in-place is good!
  • in-place is bad!

  • 我想知道的是:
  • 为什么inplace = False是默认行为?
  • 什么时候更改它好? (嗯,我可以更改它,所以我想这是有原因的)。
  • 这是安全问题吗?也就是说,操作是否会因inplace = True而失败/行为不当?
  • 我可以事先知道某个inplace = True操作是否会“真正”就地执行吗?

  • 到目前为止,我的看法是:
  • 许多Pandas操作都有一个inplace参数,始终默认为False,这意味着原始DataFrame未被修改,并且该操作返回一个新的DF。
  • 设置inplace = True时,操作可以在原始DF上使用,但仍可以在幕后使用副本,并且只需在完成后重新分配引用即可。
  • inplace = True的优点:
  • 既可以更快,也可以减少内存占用(第一个链接显示reset_index()运行速度快两倍,并且使用峰值内存的一半!)。
  • inplace = False 的优点:
  • 允许使用链式/函数语法:df.dropna().rename().sum()...很好,并提供了惰性评估或更有效的重新排序的机会(尽管我不认为Pandas会这样做)。
  • 在可能是底层DF切片/ View 的对象上使用inplace = True时,Pandas必须进行SettingWithCopy检查,这很昂贵。 inplace = False避免了这种情况。
  • 幕后行为一致且可预测。

  • 因此,撇开copy-vs-view问题,似乎总是使用inplace = True更具性能,除非专门编写链式语句。但这不是 Pandas 默认的选择,那么我想念的是什么?

    最佳答案


    是的。不仅有害。非常有害。 This GitHub issue建议在不久的将来某个时间在api范围内弃用inplace参数。简而言之,这是inplace参数的所有错误:

  • inplace与名称含义相反,通常不会阻止创建副本,并且(几乎)从不提供任何性能优势
  • inplace不适用于方法链接
  • 在DataFrame列上调用
  • 时,inplace可能导致可怕的SettingWithCopyWarning,有时可能无法就地更新


  • 上面的痛点都是初学者的常见陷阱,因此删除此选项将大大简化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
    
    这可能会导致意外行为。

    08-25 04:31