【问题标题】:pandas groupby performance熊猫 groupby 表演
【发布时间】:2018-09-18 21:51:32
【问题描述】:

我在有大量内存 (190GB) 的工作站上运行。 我们需要groupby 在具有数百万条记录的数据集上[通常具有 2 个 ID 列、1 个类型 ID 列、1 个日期列和 3-5 个分类列](在 10-30 M 之间),同时生成聚合列表列。
我们的问题是性能非常慢。在R 中运行相同的代码不到一个小时。

当前的测试数据集只有 770 万条记录。数据如下所示:

ID1         ID2         typeid    date_      cat1    cat2   cat3
12554876563 1435465465  09238423  2013-04-2  cat11   cat21  cat31
12554876563 1435465465  984375    2012-11-12 cat12   cat21  cat33
125543213   12554876563 01248423  2012-04-2  cat11   cat23  cat31
5436236563  125543213   09275423  2017-04-2  cat13   cat24  cat32

groupby 如下所示:

def agg_col(var):
    li = ';'.join([str(i) for i in set(var.dropna())])
    return li

    df = ( df.groupby(['ID1','ID2']).agg(lambda x: agg_col(x))
             .assign(weight=df.groupby(['ID1','ID2']).size())

我们也尝试使用dask as suggested in this post,但仍然遇到问题,aggregate-agg 进程需要一个多小时。

任何建议将不胜感激。

【问题讨论】:

  • 你有没有分析过?我会假设理解中的str 一直在占用。
  • 如果我需要生成带有; 分隔符的列表,我有哪些选择?也许在运行groupby之前对所有列上的str进行矢量化
  • 你能在这个问题中添加一部分数据吗?可能是来自几个不同组的 4 或 5 行。
  • 我添加了一个示例
  • 也许pandas.pydata.org/pandas-docs/stable/generated/… 可以帮忙?我想知道为什么你想要这样的表示。

标签: pandas numpy pandas-groupby dask


【解决方案1】:

将“类别”系列更改为“int”确实提高了性能,但仍然不够好。
我们的解决方案是将其转储到 sqlite -> groupby -> 并重新加载。
以下数据集在不到 5 分钟后完成。

con = sqlite3.connect('/path/to/tempdb.db')
df.to_sql('data', con, if_exists='replace')
sql_index = 'create index id12_idx on data(ID1, ID2)'
con.execute(sql_index)
sql_gp = 'SELECT ID1, ID2, GROUP_CONCAT(DISTINCT typeid), GROUP_CONCAT(DISTINCT date_), GROUP_CONCAT(DISTINCT cat1), GROUP_CONCAT(DISTINCT cat2), GROUP_CONCAT(DISTINCT cat3) from data GROUP BY ID1, ID2')
df = pd.read_sql_query(sql_gp, con)

【讨论】:

【解决方案2】:

你能试试这个吗:

当我怀疑您可以通过在 agg 方法中使用列表来摆脱一个时,我认为您正在做两个 groupby。另外,我认为我们可以摆脱列表理解,并使用 uniquejoin

df.groupby(['ID1','ID2']).agg([lambda x: ';'.join(x.dropna().unique()),'size'])

之后您可以使用 .rename(columns={'<lambda>':'agg_col','size':'weight'}) 重命名您的列

【讨论】:

  • agg 的参数可以是一个将列名映射到函数的字典,对吧?
  • @mdurant 字典重命名被删除了几个版本。我认为在 0.19 左右。
  • 哦,很不幸。似乎是一个很好的紧凑方式来表达这个过程。
  • 顺便说一句 - 我尝试了上面的代码,它已经运行了一个多小时。
  • @JosephBerry 好的......也许我们需要看看每个 numpy 的使用情况。你应该用 numpy 作为标签来编辑这个问题。
猜你喜欢
  • 2023-03-16
  • 2019-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-25
  • 1970-01-01
  • 2018-05-16
  • 2021-06-16
相关资源
最近更新 更多