pandas 中的 groupby 会创建数据的副本还是只是一个视图?

问题描述 投票:0回答:4

pandas.DataFrame.groupby
是创建数据的副本还是仅创建视图?在(更可能的)不创建副本的情况下,额外的内存开销是多少?它如何根据原始数据帧特征(例如行数、列数、不同组数)进行扩展?

python pandas
4个回答
6
投票

pandas 中的 groupby 代码有点复杂,因此很难从第一原理中找出答案。快速测试表明内存使用量随着数据的增长而增长,并且更多的组=更多的内存,但它似乎没有制作完整的副本或任何东西:

In [7]: df = pd.DataFrame(np.random.random((1000,5))) In [8]: def ret_df(df): ...: return df In [9]: def ret_gb_df(df): ...: return df, df.groupby(0).mean() In [10]: %memit ret_df(df) peak memory: 75.91 MiB, increment: 0.00 MiB In [11]: %memit ret_gb_df(df) peak memory: 75.96 MiB, increment: 0.05 MiB In [12]: df = pd.DataFrame(np.random.random((100000,5))) In [13]: %memit ret_df(df) peak memory: 79.76 MiB, increment: -0.02 MiB In [14]: %memit ret_gb_df(df) peak memory: 94.88 MiB, increment: 15.12 MiB In [15]: df = pd.DataFrame(np.random.random((1000000,5))) In [16]: %memit ret_df(df) peak memory: 113.98 MiB, increment: 0.01 MiB In [17]: %memit ret_gb_df(df) peak memory: 263.14 MiB, increment: 149.16 MiB In [18]: df = pd.DataFrame(np.random.choice([0,1,2,3], (1000000, 5))) In [19]: %memit ret_df(df) peak memory: 95.34 MiB, increment: 0.00 MiB In [20]: %memit ret_gb_df(df) peak memory: 166.91 MiB, increment: 71.56 MiB
    

6
投票
自从有人要求我帮助他们解决这个问题以来,我对此做了更多的研究,并且自从编写了接受的答案以来,pandas 源代码已经进行了一些修改。

根据我从源代码中可以看出:

Groupby 返回 Grouper 对象上的组(即 Grouper.groups),这是

“groupby 指令的规范”。

好吧,那这是什么意思?

“石斑鱼最终是索引映射。”

我一直认为这意味着 groupby 正在创建一个新对象。它不是原始数据帧的完整副本,因为您正在执行选择和聚合。所以从这个意义上来说,它更像是一种转变。

如果你对视图的定义是这样的

这样:“视图只不过是存储在数据库中的带有关联名称的 SQL 语句。视图实际上是预定义 SQL 形式的表的组合query”,那么我想知道您真正要问的是每次在同一数据帧上执行相同分组时是否必须重新应用 groupby 操作?

如果你问的是这个,我会说答案是否定的,它不像视图,只要存储分组操作的结果即可。分组数据帧或系列的输出对象是(新)数据帧或系列。


6
投票
我知道最初的问题是关于内存使用情况的,但是对于提出这个问题的人来说,寻找对组块的修改是否会影响原始数据帧,

pandas groupby 用户指南说:

组块应该被视为不可变的,对组块的更改可能会产生意外的结果。


0
投票
我对这个主题做了一些实验,并根据上面报告的先前分析提出了我需要理解的观察结果。我有一个 DF,其中包含名为 A、B 和 C 的三列。我的目标是查看

groupby

 是否存储 DF 的副本。我的测试代码片段如下:

# Make Df with columns A, B, C. grp = df.groupby(by=['A', 'B']) del df print(grp.transform(lambda x: x)) # The above outputs the whole DF.
上面的代码片段似乎表明

grp

包含DF,因为原始DF已被删除,而
grp
仍然可以产生它。这个结论是真的吗?

可能是

grp

 维护了一个指向 DF 的指针,并且在 
del
 操作之后,引用计数不会变为零,因此数据会挂在内存中供 
grp
 使用。这是真的吗?

提前感谢您的澄清。

© www.soinside.com 2019 - 2024. All rights reserved.