熊猫中的 groupby 是创建数据的副本还是仅创建视图?



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

熊猫中的 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

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

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

Groupby 返回 Grouper 对象(即 Grouper.groups(上的组,它们是"groupby 指令的规范"。

好的,那是什么意思?

"石斑鱼最终是索引映射。

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

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

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

我知道最初的问题是关于内存使用情况的,但对于来这个问题寻找对组块的修改是否会影响原始数据帧的人来说,熊猫分组用户指南说:

组区块

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

最新更新