【问题标题】:Pandas group by and sum, but create a new row when a certain amount is exceeded熊猫分组并求和,但在超过一定数量时创建一个新行
【发布时间】:2021-08-21 05:58:59
【问题描述】:

我目前有一个数据集,我试图根据一列对行进行分组,并对值为整数的列求和。

但是,问题是我想在总和达到某个阈值后创建一个新行

例如,在下面的数据框中,我试图根据公司名称对行进行分组并总结权重,但是,我不希望权重超过 100。

输入数据框:

Company Weight
a 30
b 45
a 27
a 40
b 57
a 57
b 32

输出数据框:

Company Weight
a 97
a 57
b 89
b 45

我尝试过使用 group by 和 sum,但是它无法检测我是否已达到最大数量。

有什么方法可以实现吗?

任何帮助将不胜感激!

【问题讨论】:

  • 为什么b 的输出不是[45, 89]?
  • 对不起!这只是我的数学哈哈,已编辑!
  • 我认为顺序或行也很重要。通过重新排序输入数据帧的行,您可以获得b 输出为[45, 89] 或[77, 57]。如果行的顺序不重要,您可以有多种解决方案。
  • 我认为理想情况下我希望每行尽可能接近 100,因此 45、89 是理想的!
  • a -> [99, 55], b -> [99, 35] 是一个可接受的解决方案吗?这将更容易实现。

标签: python pandas pandas-groupby


【解决方案1】:

我认为这里是必要的循环,所以为了提高性能是使用numba,修改solution from Divakar,由GroupBy.transform按组调用函数,然后聚合sum:

from numba import njit

@njit
def make_groups(x, target):
    result = np.empty(len(x),dtype=np.uint64)
    total = 0
    group = 0
    for i,x_i in enumerate(x):
        total += x_i
        if total >= target:
            group += 1
            total = 0
        result[i] = group
    return result

g = df.groupby("Company")["Weight"].transform(lambda x: make_groups(x.to_numpy(), 100))

df1 = (df.groupby(by=["Company", g])
        .sum()
        .reset_index(1, drop=True)
        .sort_values(['Company','Weight'], ascending=[True, False])
        .reset_index())
print (df1)
  Company  Weight
0       a      97
1       a      57
2       b      89
3       b      45

【讨论】:

  • 我做了类似的事情,但它与 OP 输出中的行顺序不匹配。如果允许您对行重新排序,您可以获得接近 100 的权重,这正是 OP 想要的。
  • @hilberts_drinking_problem - 谢谢,我可以排最后。
  • 非常感谢您!效果超级好!
  • @ChrisHo1341 - 超级棒!如果我的回答有帮助,请不要忘记accept。谢谢。
【解决方案2】:

嗯,这取决于,你目前在问一个 NP 问题,除非你不希望最佳体重在 100 以下,你可以做一些算法,

但没有一个是 o(n),这是 group by 和 sum 的作用,假设你用 iterrows() 进行迭代(尽量避免这种情况),你能在一次迭代中这样做吗?如果您不是在寻找最佳解决方案(每场比赛最接近 100 个),则可以选择。

对于每家公司,您都必须通过增加值对其进行排序。 每次总和达到 100 时,在边变量处使用迭代打开一个新行,并在最后替换原点

据我所知,没有 pandas / Numpy 标准解决方案。

【讨论】:

  • 这就是我现在正在尝试的!感谢您的建议!我主要希望在时间方面有一个更快的选择
  • 如果您没有内存问题,并且您知道最小权重为 10,这意味着每个总和的上限为 10 个总和,也许您可​​以做 10 个数组,每个数组少一个元素,总和使用 NumPy 作为解决方案之间的滚动,在大规模数据上,它可能更有效。但这只有在你有上限的情况下才会起作用。
猜你喜欢
  • 1970-01-01
  • 2021-12-30
  • 2020-11-20
  • 1970-01-01
  • 2020-12-19
  • 2018-06-13
  • 1970-01-01
  • 2017-09-17
相关资源
最近更新 更多