Ogh*_*hli 1 python dataframe pandas
在操作数据帧时,在 Pandas 函数中使用就地参数可能是很常见的。
Inplace
是在不同函数中使用的参数。一些函数中使用 inplace 作为属性,例如set_index(), dropna(), fillna(), reset_index(), drop(), replace()
等等。该属性的默认值为False
,它返回对象的副本。
我想详细了解什么时候在 pandas 函数中使用是好的做法inplace
,什么时候也不应该这样做,以及原因。您能否在示例中进行演示以供参考,因为这个问题在使用 pandas 函数时很常见。
例如:
df.drop(columns=[your_columns], inplace=True)
在这种情况下,建议使用 inplace 和 drop 。另外,如果某些变量喜欢list
依赖于数据框。就地更改它会影响依赖于它的其他变量的结果。另一个问题是在 pandas 数据帧上使用就地阻止方法链接。
我会举一些例子,但更好的方式是从风格来看待它。
首先,对于任何生产代码或可以以任意并行方式运行的代码,您不想更改任何内容。
函数式编程和面向对象编程之间存在一个主要的哲学差异: 函数式编程没有副作用。这意味着什么?这意味着如果我有一个函数或方法,让我们举df.drop()
一个具体的例子,那么drop
以纯函数的方式使用只会返回一个结果,它不会做任何其他事情。
让我们制作一个数据框:
>>> df = pd.DataFrame({"name": ["Alice", "Bob", "Candi"],
"job": ["CFO", "Accountant", "Developer"],
"department": ["Executive", "Accounting", "Product"]})
>>> df
name job department
0 Alice CFO Executive
1 Bob Accountant Accounting
2 Candi Developer Product
Run Code Online (Sandbox Code Playgroud)
inplace=False
)现在,如果我drop
以功能方式调用,所发生的只是返回一个带有缺失列的新数据帧:
>>> df.drop(columns = "job", inplace=False)
name department
0 Alice Executive
1 Bob Accounting
2 Candi Product
Run Code Online (Sandbox Code Playgroud)
请注意,我正在返回结果,即数据帧。明确地说,我可以这样做:
>>> new_df = df.drop(columns="job", inplace=False)
>>> new_df
name department
0 Alice Executive
1 Bob Accounting
2 Candi Product
Run Code Online (Sandbox Code Playgroud)
请注意,new_df
已分配给该方法的返回结果drop
。
inplace=True
)>>> df.drop(columns="job", inplace=True)
>>>
Run Code Online (Sandbox Code Playgroud)
请注意,没有返回任何内容!这个方法的返回值实际上是None
。
但确实发生了一些事情:
>>> df
name department
0 Alice Executive
1 Bob Accounting
2 Candi Product
Run Code Online (Sandbox Code Playgroud)
如果我请求数据框,我们可以看到它df
实际上已更改,因此该job
列丢失了。但这完全是一个副作用,而不是回报。
为了证明没有返回任何内容,让我们再试一次(使用不同的列,原因如下所述)并将该方法的结果分配inplace
给一个新变量:
>>> not_much = df.drop(columns="name", inplace=True)
>>> type(not_much)
<class 'NoneType'>
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,变量not_much
是 of NoneType
,这意味着None
已返回。
多年来,软件工程发生了变化,并行活动现在变得更加普遍。如果您在 Spark 上运行大数据作业,或者即使您在单台笔记本电脑上运行 pandas,您也可以将任务配置为在多个进程上异步运行多线程(如 Map-Reduce 作业等)。
由于这种并行操作,您通常不知道首先会发生什么,然后会发生什么。您需要尽可能多的操作,要么不更改状态,要么以原子方式更改状态。
现在让我们重新审视一下df.drop
,重复多次。想象一下,您有一项受网络限制的大数据作业(通常是这种情况),您只需要求 10 台机器执行相同的任务,然后您接受最先返回答案的机器的答案。这是处理网络不一致的常见方法。
Inplace
:>>> df
name job department
0 Alice CFO Executive
1 Bob Accountant Accounting
2 Candi Developer Product
>>> df.drop(columns="job", inplace=True)
>>> df.drop(columns="job", inplace=True)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
raise KeyError(f"{list(labels[mask])} not found in axis")
KeyError: "['job'] not found in axis"
>>>
Run Code Online (Sandbox Code Playgroud)
我刚刚运行了两次相同的工作,并得到了不同的答案,其中一个导致了错误。这对于并行作业运行来说并不好。
Inplace
:>>> new_df = df.drop(columns="job", inplace=False)
>>> new_df
name department
0 Alice Executive
1 Bob Accounting
2 Candi Product
>>> new_df = df.drop(columns="job", inplace=False)
>>> new_df
name department
0 Alice Executive
1 Bob Accounting
2 Candi Product
Run Code Online (Sandbox Code Playgroud)
无论上面的代码运行多少次,new_df
都将始终等于相同的事情。
我永远不会使用它inplace=True
,除非它是在一次性 Jupyter 笔记本、家庭作业或远离生产环境的其他东西中。
我开始谈论“函数式与面向对象”。这就是它的框架,但我不喜欢这种比较,因为它引发了激烈的争论,而面向对象不一定有副作用。
只是函数式不能有副作用,而面向对象常常有副作用。
我更喜欢说“副作用与无副作用”。这个选择很简单:只要有可能,就始终防止副作用,但要认识到这并不总是可能的(尽管Haskel 是这么建议的)。
归档时间: |
|
查看次数: |
733 次 |
最近记录: |