pandas.DataFrame.groupby
是创建数据的副本还是仅创建视图?在(更可能的)不创建副本的情况下,额外的内存开销是多少?它如何根据原始数据帧特征(例如行数、列数、不同组数)进行扩展?
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
根据我从源代码中可以看出:
Groupby 返回 Grouper 对象上的组(即 Grouper.groups),这是 好吧,那这是什么意思?
我一直认为这意味着 groupby 正在创建一个新对象。它不是原始数据帧的完整副本,因为您正在执行选择和聚合。所以从这个意义上来说,它更像是一种转变。
如果你对视图的定义是这样的如果你问的是这个,我会说答案是否定的,它不像视图,只要存储分组操作的结果即可。分组数据帧或系列的输出对象是(新)数据帧或系列。
pandas groupby 用户指南说:
组块应该被视为不可变的,对组块的更改可能会产生意外的结果。
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
使用。这是真的吗?提前感谢您的澄清。