更改间隔长度(以熊猫为单位)

时间:2020-06-30 06:23:13

标签: python pandas

我正在尝试更改数据的精度,以使其间隔为100个长度。

我能够使用普通的python做到这一点,但我想知道是否有使用pandas的更优雅的解决方案(我仍在尝试学习)。

示例:

这是起始数据

start  end    result
600    796    0
796    798    3
798    799    11
799    898    23
898    930   25
930    932   22
932    933   14
933    950   2

行被合并在一起,因此数据间隔为100,并且值会相应更新

start  end    result
600    700    0
700    800    3 + 11 + (23 * 1/(898-799))
800    900    (23 * 98/(898-799)) + (25 * 2/(930-898))
900    1000   (25 * 30/(930-898)) + 22 + 14 + 2 + ...

获得最终结果

start  end    result
600    700    0
700    800    14.23
800    900    24.33
900    1000   61.44 + ...

1 个答案:

答案 0 :(得分:0)

import itertools开始,很快将需要它。

我的解决方案中需要大部分编码的部分是“翻译” 每个源行都按百个范围分成一系列“间隔”。

为此,请定义以下生成器函数:

def IntervGen(st, en, val):
    nxtSt = (st // 100 + 1) * 100
    totalSize = en - st
    origVal = val
    while st < en:
        if en <= nxtSt:      # "en" in the current hundred
            yield st, en, val
            return
        currSize = nxtSt - st
        currVal = origVal * currSize / totalSize
        yield st, nxtSt, currVal
        st = nxtSt
        nxtSt += 100
        val -= currVal

下一步是创建一个中间DataFrame,收集“间隔” 由 IntervGen 生成:

df2 = pd.DataFrame([ x for x in itertools.chain.from_iterable(
    [ IntervGen(row.start, row.end, row.result) for row in df.itertuples() ]) ],
    columns=['start', 'end', 'value'])

对于您的样本数据,结果为:

    start  end      value
0     600  700   0.000000
1     700  796   0.000000
2     796  798   3.000000
3     798  799  11.000000
4     799  800   0.232323
5     800  898  22.767677
6     898  900   1.562500
7     900  930  23.437500
8     930  932  22.000000
9     932  933  14.000000
10    933  950   2.000000

为便于尽快进行分组(按百个范围), 更改一些 start 列(向下舍入到满百):

df2.start = df2.start // 100 * 100

要生成最终结果,请运行:

res = df2.groupby('start').value.sum().rename('result').reset_index()
res.insert(1, 'end', res.start + 100)

结果(样本数据的 res DataFrame)为:

   start   end     result
0    600   700   0.000000
1    700   800  14.232323
2    800   900  24.330177
3    900  1000  61.437500

按照截至2020-06-30的评论进行编辑

您在评论中呈现的结果没有什么奇怪的。 可能相应的源数据是:

start  end    result
11400  11443  0
11443  11454  1
11461  11472  2

这些行中的每一行都已转换为单个输出间隔, 具有原始值,因为 start end 都在同一百之内。

还请注意,这是保存在 df2 中以及之后的“初始”结果 df2.start = df2.start // 100 * 100所有这些 start 值 将四舍五入为 11400

与其他带有 start 的值一起向下舍入为 11400 将被汇总并以11400 11500的形式放入最终结果中(如 start end )+相应的值之和。