pandas 链接和“inplace”参数的使用

pandas chaining and the use of "inplace" parameter

提问人:mpag 提问时间:6/13/2023 最后编辑:mpag 更新时间:6/14/2023 访问量:138

问:

对于 python 中的 pandas DataFrames,多个成员方法都有一个参数,据称该参数允许您不创建对象的副本,而是直接修改原始对象*。inplace

[*编辑补充:然而,事实证明情况并非如此,正如@juanpa.arrivillaga所指出的那样。 DOES 复制数据,并且仅更新与修改后的对象关联的指针,因此与手动重新分配给原始对象的名称相比,几乎没有什么优势。inplace=True

我在网上看到的使用示例不包括使用链接的示例。相关 SO 线程中的此评论可能是为什么我在任何地方都看不到此类示例的答案:inplace=True

您不能就地进行方法链和操作。就地操作返回 None 并断开链

但是,如果你在链的最后一个条目中放置一个,“就地链接”会起作用吗?[编辑添加:否]或者这是否等同于尝试更改在链中较早链接中创建的副本,因为它不再是您的原始对象,因此在链语句完成后会“丢失”?[编辑后补充:是;请在此处查看答案inplace=True]

使用大型数据对象似乎排除了链接的概念,而无法就地进行链接,至少在保持低内存开销和高计算速度的愿望方面是这样。是否有 pandas 的替代实现,或者例如,python 中可用的 R 的 data.table 的等效实现可能适合我的需求?或者我唯一的选择是不链接(并快速计算)或链接但制作数据的冗余副本,至少是暂时的?

Python pandas 方法 就地

评论

0赞 Michael Butscher 6/14/2023
如果链中倒数第二个条目返回一个副本,而最后一个条目就地修改了它,但没有返回它,则该副本将丢失。
0赞 juanpa.arrivillaga 6/14/2023
“或者这是否等同于尝试更改在链中较早链接中创建的副本,因为它不再是您的原始对象,因此在链语句完成后会”丢失“?” 是的,是的,这就是会发生什么。你试过了吗?
1赞 juanpa.arrivillaga 6/14/2023
另请注意,通常不会帮助您实际节省内存。请参阅核心贡献者的此声明。关键字参数在 Pandas v2 中被弃用(取而代之的是,将有新的 COW 改进inplace)
1赞 juanpa.arrivillaga 6/14/2023
坦率地说,放弃整个 pandas 项目对我来说似乎很奇怪,因为你不能使用方法链。这本质上是句法糖。
0赞 mpag 6/14/2023
@juanpa.arrivillaga,你提到inplace实际上并没有像名字所暗示的那样(在没有复制或指针魔法的情况下改变一个对象),这让我陷入了一个受欢迎的兔子洞。由于使用就地似乎没有任何优势,而且链接的优势有限,我可能会回到“普通”熊猫。我希望,在未来,有人能用 python 开发一个直观、快速的大数据库。我将用关于就地的注释来编辑我的帖子。

答:

1赞 Stu Sztukowski 6/14/2023 #1

让我们试试吧。

import pandas as pd
import numpy as np

df = pd.DataFrame({'value' : [2, 2, 1, 1, 3, 4, 5, np.NaN]})

df.sort_values('value').drop_duplicates().dropna(inplace=True)

期望:

   value
2    1.0
0    2.0
4    3.0
5    4.0
6    5.0

结果:

   value
0    2.0
1    2.0
2    1.0
3    1.0
4    3.0
5    4.0
6    5.0
7    NaN

答:不,在链的末尾不会修改原始数据帧。inplace=True

评论

0赞 chepner 6/14/2023
使用比使用更相关。 根本就不被调用,这就是不被修改的原因。drop_duplicatesinplace=Truedropnadf.dropnadf
1赞 juanpa.arrivillaga 6/14/2023
@chepner对不起,我不明白,为什么从来不打电话?dropna
1赞 chepner 6/14/2023
dropna被召唤,但不开启;它被调用 返回的任何内容。(我正在区分绑定方法和未绑定方法。dfdf.sort_values('value').drop_duplicates
0赞 chepner 6/14/2023
更清楚地说,链接只是避免临时变量的一种方式。链式形式等同于 ,只是在链式版本中不保留对 的引用。t1 = df.sort_values('values'); t2 = t1.drop_duplicates(); t2.dropna(inplace=True)t2
1赞 Michael Butscher 6/14/2023 #2

如果你真的想要它,你可以创建一个包装器,如下所示(未经测试):

class Wrap():
    def __init__(self, df):
        self.df = df
    
    def __getattr__(self, name):
        m = getattr(self.df, name)
        def f(*args, **kwargs):
            m(*args, **kwargs, inplace=True)
            return self
        
        return f

# Usage:

Wrap(df).func1(*params1).func2(*params2)

评论

1赞 jsbueno 6/14/2023
数据帧肯定是模式复杂的对象,而不是这个朴素的包装器可以遵守的。例如,它不会转发任何运算符。__getitem__
0赞 Michael Butscher 6/14/2023
@jsbueno 它只是为了展示如果一个人真的真的想要它,如何做到这一点。
0赞 mpag 6/14/2023
@MichaelButscher感谢您的包装器建议。我以为有办法,但不知道怎么离开我的头顶。感谢您花时间解释这种方法。但是,实施这一策略超出了我目前希望做的事情的范围。