【问题标题】:Pandas: remove old DataFrame from memory after groupby熊猫:分组后从内存中删除旧的DataFrame
【发布时间】:2018-11-26 17:02:59
【问题描述】:
  value  Group  something
0     a    1          1
1     b    1          2
2     c    1          4
3     c    2          9
4     b    2         10
5     x    2          5
6     d    2          3
7     e    3          5
8     d    2         10
9     a    3          5

我想选择每个组的最后 3 行(来自上面的 df),如下所示,但使用 Inplace 执行操作。我想确保在分配后只将新的 df 对象保留在内存中。什么是一种有效的方法?

df = df.groupby('Group').tail(3)

结果应如下所示:

  value  Group  something
0     a    1          1
1     b    1          2
2     c    1          4
5     x    2          5
6     d    2          3
7     e    3          5
8     d    2         10
9     a    3          5

N.B:- 这个问题与Keeping the last N duplicates in pandas 有关

【问题讨论】:

  • 为什么不想用你用的作为例子(df = df.groupby('Group').tail(3))?您不能进行就地分组,因为分组的数据框是一个完全不同的对象。
  • 当你覆盖它时只有新的..
  • @gibbz00 也适用于当前的公式。一旦不再有活动引用,Python 的垃圾回收器就会处理旧的垃圾回收器。
  • @gibbz00 给输出 df 一个新名称 (df_grouped = df.groupby('Group').tail(3)) 意味着 df 仍然引用旧数据框,而 df_grouped 引用新数据框。现在它们都将存储在内存中。
  • 如果您不想覆盖,最好分配新的列名,例如df['new_col'] = df.groupby('Group').tail(3)

标签: python pandas


【解决方案1】:

df = df.groupby('Group').tail(3) 已经是一种有效的方法。因为您正在覆盖 df 变量,Python 将负责释放旧数据帧的内存,而您只能访问新数据帧。

【讨论】:

    【解决方案2】:

    太难猜你想要什么了。

    注意:在可用的情况下使用 Pandas inplace 参数是 NO 保证不会在内存中创建新的 DataFrame。事实上,它很可能会在内存中创建一个新的DataFrame,并在后台替换旧的。

    from collections import defaultdict
    
    def f(s):
      c = defaultdict(int)
      for i, x in zip(s.index[::-1], s.values[::-1]):
        c[x] += 1
        if c[x] > 3:
          yield i
    
    df.drop([*f(df.Group)], inplace=True)
    df
    
      value  Group  something
    0     a      1          1
    1     b      1          2
    2     c      1          4
    5     x      2          5
    6     d      2          3
    7     e      3          5
    8     d      2         10
    9     a      3          5
    

    【讨论】:

    • 我在想像这样的解决方案,因为 drop 有一个 Inplace 参数。但是,我不知道df = df.groupby('Group').tail(3) 已经确保旧的df 一旦被覆盖就会从内存中释放。
    • 是的,如果你不关心被消耗然后释放的临时内存,那么你绝对应该使用df.groupby('Group').tail(3)。你没有提到性能,所以我认为这不是问题。
    • [*f(df.Group)] 中的星号(*)在做什么?
    • * 在这种情况下是解包可交互的参数。 [*f(df.Group)] 是这样做的好方法list(f(df.Group))
    【解决方案3】:

    您的答案已经在 Post 中,但是正如之前在 cmets 中所说,您正在覆盖现有的 df ,因此为避免分配新的列名,如下所示:

    df['new_col'] = df.groupby('Group').tail(3)
    

    但是,出于好奇,如果您不关心 groupby 并且只查找 df 的最后 N 行,您可以像下面这样:

    df[-2:]   #  last 2 rows
    

    【讨论】:

      猜你喜欢
      • 2018-07-04
      • 2015-10-19
      • 1970-01-01
      • 1970-01-01
      • 2020-03-03
      • 2017-05-24
      • 2015-05-08
      • 2013-03-24
      相关资源
      最近更新 更多