如何基于列的相等部分将图块分配给pandas数据框?

时间:2019-06-18 16:13:17

标签: python pandas dataframe

我已经按某一列对大约一百万行数据框进行了排序。我想根据另一列的相等总和为每个观察值分配组,但是我不确定如何执行此操作。

以下示例:

import pandas as pd
value1 = [25,27,20,22,28,20]
value2 = [.34,.43,.54,.43,.5,.7]

df = pd.DataFrame({'value1':value1,'value2':value2})

df.sort_values('value1', ascending = False)

df['wanted_result'] = [1,1,1,2,2,2]

像本示例一样,我想对我的列(示例列value1)求和,并分配组以使它们的求和值尽可能接近等于value1。有内置功能吗?

2 个答案:

答案 0 :(得分:2)

贪婪循环

使用Numba的JIT加快速度。

from numba import njit

@njit
def partition(c, n):
    delta = c[-1] / n
    group = 1
    indices = [group]
    total = delta

    for left, right in zip(c, c[1:]):
        left_diff = total - left
        right_diff = total - right
        if right > total and abs(total - right) > abs(total - left):
            group += 1
            total += delta
        indices.append(group)

    return indices

df.assign(result=partition(df.value1.to_numpy().cumsum(), n=2))

   value1  value2  result
4      28    0.50       1
1      27    0.43       1
0      25    0.34       1
3      22    0.43       2
2      20    0.54       2
5      20    0.70       2

这是的最佳选择。这是一种贪婪的启发式方法。它遍历列表,找到我们进入下一组的位置。在那一点上,它决定将当前点包含在当前组中还是下一个组中是否更好。

这应该表现得很好,除非在值之间存在巨大差异且较大的值接近末尾的情况下。这是因为该算法贪婪,只查看当前知道的内容,而不会一次

但是就像我说的那样,它应该足够好了。

答案 1 :(得分:1)

我认为,这是一种最优化问题(非线性) 而且 Pandas 绝对不是解决该问题的好方法。

解决问题的基本思路如下:

  1. 定义:

    • n -元素数量,
    • groupNo -划分为的组数。
  2. 从生成初始解决方案开始,例如连续 每个 bin 中的 n / groupNo 元素组。

  3. 定义目标函数,例如之间的差异平方和 每个组的总和和所有元素/ groupNo的总和。

  4. 执行一次迭代:

    • 对于来自不同容器的每对元素 a b , 如果这些元素已移动,则计算新的目标函数值 到另一个垃圾箱,
    • 选择对目标函数有更大改进的对 并执行移动(将 a 从其当前容器移动到其中 b 所在的容器, 反之亦然)。
  5. 如果找不到这样的对,那么我们得到最终结果。

也许有人会提出更好的解决方案,但至少此解决方案是 一些概念开始。