繁体   English   中英

Pandas:如何在 groupby() 操作后有效地 diff()?

[英]Pandas: How to efficiently diff() after a groupby() operation?

我在 Pandas 中确实有一个大型数据集(大约 800 万行 x 25 列),我正在努力在数据子集上以高性能方式使用 diff() function。

这是我的数据集的样子:

                   prec   type
location_id hours             
135         78     12.0      A
            79     14.0      A
            80     14.3      A
            81     15.0      A
            82     15.0      A
            83     15.0      A
            84     15.5      A
  • 我在 [location_id, hours] 上有一个多索引。 我有大约 60k 个位置和每个位置 140 小时(构成 800 万行)。
  • 数据的 rest 是数字(浮点)或分类。 我这里只包含了 2 列,通常有 20 列左右。
  • 我愿意做的是为prec列上的每个位置应用 diff() function。 原始数据集堆积了prec数字; 通过应用 diff() 我将获得每小时适当的prec值。
  • 考虑到这些,我在 Pandas 中实现了以下算法:
# Filter the data first
df_filtered = df_data[df_data.type == "A"] # only work on locations with 'A' type
df_filtered = df_filtered.query('hours > 0 & hours <= 120') # only work on certain hours

# Apply the diff()
for location_id, data_of_location in df_filtered.groupby(level="location_id"):
    df_data.loc[data_of_location.index, "prec"] = data_of_location.prec.diff().replace(np.nan, 0.0)
del df_filtered

  • 这在功能上非常有效,但是性能和 memory 消耗是可怕的。 我的数据集大约需要 30 分钟,这目前是不可接受的。 for 循环的存在表明这可以得到更好的处理。
  • 有没有更好/更快的方法来实现这一点?
  • 此外,Python 脚本的整体 memory 消耗在此操作期间暴涨; 它增长了 300% 左右! df_data数据帧消耗的memory没有变化,但整个过程memory消耗上升。

来自@Quang Hoang 和@Ben 的输入。 T,我想出了一个非常快但仍然消耗大量 memory 的解决方案。

# Filter the data first
df_filtered = df_data[df_data.type == "A"] # only work on locations with 'A' type
df_filtered = df_filtered.query('hours > 0 & hours <= 120') # only work on certain hours

# Apply the diff()
df_diffed = df_data.groupby(level="location_id").prec.diff().replace(np.nan, 0.0)
df_data[df_diffed.index, "prec"] = df_diffed
del df_diffed
del df_filtered

我猜可以做两件事来改善 memory 的使用:

  • df_filtered似乎是数据的副本; 那应该会增加很多 memory。
  • df_diffed也是一个副本。

在计算这两个变量时,memory 的使用非常密集。 我不确定是否有任何in-place方式来执行此类操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM