【问题标题】:Python: using groupby and apply to rebulid dataframePython:使用 groupby 并申请重建数据框
【发布时间】:2022-01-06 16:33:24
【问题描述】:

我想将我的数据框从 df1 重新构建到 df2:

df1 像这样:

id counts days
1 2 4
1 3 4
1 4 4
2 56 8
2 37 9
2 10 7
2 10 4

df2 像这样:

id countsList daysList
1 '2,3,4' '4,4,4'
2 '56,37,10,10' '8,9,7,4'

df2 中的 countsList 和 daysList 是一个字符串。

我有大约100万行df1,如果我使用foriter会很慢。

所以我想使用 groupby 并申请来实现它。你有什么解决方案或有效的方法来覆盖它。

我的电脑信息:

CPU:至强 6226R 2.9Ghz 32 核
内存:16G
蟒蛇:3.9.7

【问题讨论】:

  • 这仍然会很慢,因为这些字符串聚合并不是特别高效。因此,与计算组均值之类的东西相反,','.joining 字符串的运行时间会随着组的数量而变差。即使它被 .groupby.agg 伪装,你也会在组上使用一些慢速 python 循环

标签: python pandas dataframe pandas-groupby


【解决方案1】:

您可以使用agg(然后重命名列)

np.random.seed(123)
n = 1_000_000
df = pd.DataFrame({
    "id":  np.random.randint(100_000, size = n),
    "counts": np.random.randint(10, size = n),
    "days": np.random.randint(10, size = n)
})

df2 = df.groupby('id').agg(lambda x: ','.join(map(str, x)))\
         .add_suffix('List').reset_index()

#   id      countsList      daysList
#0  15725   7,5,6,3,7,0     7,9,5,8,0,1
#1  28030   7,6,5,1,9,6,5   5,0,8,4,8,6,0

这并不是“那么”慢 - %%timeit 用于 100 万行和 100k 组:

639 ms ± 16.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

编辑:此处提出的解决方案:How to group dataframe rows into list in pandas groupby 有点快:

id, counts, days = df.values[df.values[:, 0].argsort()].T
u_ids, index = np.unique(id, True)
counts = np.split(counts, index[1:])
days = np.split(days, index[1:])
df2 = pd.DataFrame({'id':u_ids, 'counts':counts, 'days':days})

但不是超级快:

313 ms ± 6.55 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-13
    • 2022-01-14
    • 2020-06-05
    • 1970-01-01
    • 2018-06-25
    • 1970-01-01
    • 2019-11-08
    • 1970-01-01
    相关资源
    最近更新 更多