我正在尝试更改数据的精度,以使其间隔为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 + ...
答案 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
您在评论中呈现的结果没有什么奇怪的。 可能相应的源数据是:
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 )+相应的值之和。