Python pandas中的groupby是创建数据副本还是仅创建视图?
Python pandas中的groupby是创建数据副本还是仅创建视图?,python,pandas,Python,Pandas,pandas.DataFrame.groupby是创建数据的副本还是仅创建一个视图?在(更可能的)不创建副本的情况下,额外的内存开销是什么,以及它如何与原始数据帧特征(例如行数、列数、不同组数)进行缩放?变得有点复杂,因此很难从第一原理中找到答案。快速测试使内存使用似乎随着数据的增长而增长,并且更多的组=更多的内存,但它似乎不会生成完整副本或任何内容: In [7]: df = pd.DataFrame(np.random.random((1000,5))) In [8]: def ret_d
pandas.DataFrame.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
自从有人让我帮他们解答这个问题以来,我对这个问题做了更多的研究,自从被接受的答案被写出来后,熊猫的源代码已经做了一些修改
根据我从源代码中可以看出:
Groupby返回Grouper对象上的组(即Grouper.groups),这些组是
好的,那是什么意思
我一直认为这意味着groupby正在创建一个新对象。它不是原始数据帧的完整副本,因为您正在执行选择和聚合。从这个意义上讲,这更像是一种转变
如果您对视图的定义如下:“视图只不过是存储在数据库中的SQL语句,并具有相关名称。视图实际上是预定义SQL查询形式的表的组成”,然后我想知道,您真正想问的是,每次在同一数据帧上执行相同的分组时,是否必须重新应用groupby操作
如果你问的是这个问题,我会说答案是否定的,它不像视图,只要你存储分组操作的结果。分组数据帧或系列的输出对象是(新)数据帧或系列。感谢您的详细分析!事实上,源代码有点复杂,%memit
magic命令被证明是一个有效的工具。一些备注:-在形状(1000,5)
的数据帧相对较小的情况下,内存开销似乎最小。然而,这种开销在数据帧大小方面以大致线性的方式以绝对值扩展,而数据帧本身的内存却与数据帧大小相反地以极其次线性的方式扩展:x1000数据帧只占用x1.5内存!我想知道为什么…结果,对于最大的数据帧,相对内存开销达到100%以上,这相当于复制。正如你最后的实验所证明的,组的数量似乎并没有真正产生影响;即使是在组数量大大减少的情况下,内存开销也大约为100%。感谢您提供有关groupby返回的对象确切类型的更多信息。我在问题中使用的术语“视图”不是SQL意义上的,而是遵循pandas/numpy术语,例如在讨论切片操作的效果时。请看这里: