之前已经讨论过,但答案相互矛盾:
我想知道的是:
inplace = False
是默认行为? inplace = True
?inplace = True
操作是否真的会#34;是否就地进行?inplace
参数,始终默认为False
,这意味着原始DataFrame不受影响,并且操作返回一个新的DF。inplace = True
时,操作可能可以在原始DF上运行,但它可能仍然可以在幕后复制,只需在完成后重新分配参考。inplace = False
的优点:df.dropna().rename().sum()...
这很好,并提供了懒惰评估或更有效的重新排序的机会(虽然我不认为Pandas正在这样做)。inplace = True
时,Pandas必须进行SettingWithCopy
检查,这是很昂贵的。 inplace = False
避免这种情况。 inplace = True
的优点:reset_index()
运行速度提高一倍,使用峰值内存的一半!)。因此,将copy-vs-view问题放在一边,除非专门编写链式语句,否则总是使用inplace = True
似乎更有效。但那不是默认的熊猫选择,所以我错过了什么?
答案 0 :(得分:17)
在熊猫中,inplace = True是否被认为有害?
是的。不仅有害。 相当有害。 This GitHub issue建议在不久的某个时候在API范围内弃用inplace
参数。简而言之,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
这可能导致意外行为。
答案 1 :(得分:6)
如果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()
的副作用,我必须信任调用者才能记住不做某事我没想到而不是故意做某事 ...所以最好能够改变一个对象的任何东西显式< / em>至少让事情变得更加明显和原因。
即使使用基本的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?