这已在前面讨论过,但答案相互矛盾:
我想知道的是:
inplace = False默认行为?inplace = True?inplace = True操作是否"真正"就地进行?inplace参数,总是默认为False,意味着原始的DataFrame不受影响,并且操作返回一个新的DF.inplace = True,操作可能适用于原始DF,但它可能仍在幕后复制,只需在完成后重新分配参考.inplace = False:df.dropna().rename().sum()...这很好,并提供延迟评估或更有效的重新排序的机会(虽然我不认为Pandas正在这样做).inplace = True在可能是底层DF的切片/视图的对象上使用时,Pandas必须进行SettingWithCopy检查,这是昂贵的.inplace = False避免这种情况.inplace = True:reset_index()运行速度快两倍,并使用峰值内存的一半!).因此,inplace = True除了专门编写链式语句之外,将copy-vs-view问题放在一边,总是使用它似乎更高效.但这不是默认的熊猫选择,所以我错过了什么?
cs9*_*s95 50
在熊猫中, inplace = True 是否被认为有害?
是的。不仅有害。相当有害。这个 GitHub 问题提议inplace在不久的将来某个时候在 api-wide 范围内弃用该论点。简而言之,这里的inplace论点都是错误的:
inplace,与名称所暗示的相反,通常不会阻止创建副本,并且(几乎)从不提供任何性能优势inplace 不适用于方法链inplaceSettingWithCopyWarning在 DataFrame 列上调用时可能会导致可怕的情况,并且有时可能无法就地更新列以上痛点都是初学者常见的陷阱,去掉这个选项会大大简化API。
我们更深入地看一下上面的几点。
性能
一个常见的误解是使用inplace=True将导致更高效或优化的代码。在一般情况下,有没有性能优势使用inplace=True。方法的大多数就地和非就地版本无论如何都会创建数据的副本,就地版本会自动将副本分配回来。副本无法避免。
方法链
inplace=True也阻碍方法链接。对比工作
result = df.some_function1().reset_index().some_function2()
Run Code Online (Sandbox Code Playgroud)
与
temp = df.some_function1()
temp.reset_index(inplace=True)
result = temp.some_function2()
Run Code Online (Sandbox Code Playgroud)
意外陷阱
要记住的最后一个警告是,调用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
Run Code Online (Sandbox Code Playgroud)
这可能会导致意外行为。
如果inplace是默认值,那么DataFrame将针对当前引用它的所有名称进行变异.
一个简单的例子,说我有一个df:
df = pd.DataFrame({'a': [3, 2, 1], 'b': ['x', 'y', 'z']})
Run Code Online (Sandbox Code Playgroud)
现在,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
Run Code Online (Sandbox Code Playgroud)
那没关系 - 我的原版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?
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7444 次 |
| 最近记录: |