![](/img/trans.png)
[英]In pandas: Interpolate between two rows such that the sum of interpolated values is equal to the second row
[英]In pandas: Interpolate between two rows such that the sum of interpolated values + second row = old value of the second row
我发现很难阐明这个问题,但它与这个问题类似。
例如,假设我有一个这样的表:
标签 | 价值 |
---|---|
一种 | 1个 |
乙 | 2个 |
C | 楠 |
丁 | 楠 |
乙 | 楠 |
F | 12 |
它需要看起来像这样:
标签 | 价值 |
---|---|
一种 | 1个 |
乙 | 2个 |
C | 3个 |
丁 | 3个 |
乙 | 3个 |
F | 3个 |
使用下一个可用值 (12) 并将其除以 Nan 值的数量 + 1 (12/4) = 3,并将 Nan 值和用于插值 (12) 的原始值替换为 3。它与之前的类似问题,但也修改了用于插值的原始值。
test = pd.DataFrame({'Label': ['A', 'B', 'C', 'D', 'E', 'F','G','H','I'],
'Value': [1, 2, None, None, None, 12,None,None,4]})
test['break'] = np.where(test['Value'].notnull(),1,0)
test['group'] = test['break'].shift().fillna(0).cumsum()
test['Value2'] = test.groupby('group').Value.apply(lambda x: x.fillna( x.max() / len(x)))
for row in range(0,test.shape[0]):
if test['break'].iloc[row] == 0 and test['break'].iloc[row+1] == 1:
test.at[row+1, 'Value2'] = test['Value2'].iloc[row]
df.interpolate() 无法做到这一点,这是我目前所拥有的。 它完成了工作,但不是很优雅
也许是这样的?
test = pd.DataFrame({'Label': ['A', 'B', 'C', 'D', 'E', 'F','G','H','I'],
'Value': [1, 2, None, None, None, 12,None,None,4]})
tr = test.assign(
g=(~test['Value'].isna())[::-1].cumsum()
).groupby('g')['Value'].transform
df = test.assign(Value=tr('last') / tr('size'))
>>> df
Label Value
0 A 1.000000
1 B 2.000000
2 C 3.000000
3 D 3.000000
4 E 3.000000
5 F 3.000000
6 G 1.333333
7 H 1.333333
8 I 1.333333
使用.assign(g=...)
我们创建以非 NaN 值结尾并以零个或多个 NaN 开头的值组:
>>> test.assign(
... g=(~test['Value'].isna())[::-1].cumsum()
... )
Label Value g
0 A 1.0 4
1 B 2.0 3
2 C NaN 2
3 D NaN 2
4 E NaN 2
5 F 12.0 2
6 G NaN 1
7 H NaN 1
8 I 4.0 1
然后,我们使用.groupby('g')['Values'].transform
两次:获取last()
值,并将其除以组的size()
。
与Pierre D的非常好的答案一样徒劳,您也可以使用以下解决方案来一次性分组:
test['Value'] = ((test.assign(id = (~test['Value'].isna()).cumsum().mask(test['Value'].isna())
.bfill()))
.groupby('id').transform(lambda x: x.bfill() / len(x)))
Label Value
0 A 1.000000
1 B 2.000000
2 C 3.000000
3 D 3.000000
4 E 3.000000
5 F 3.000000
6 G 1.333333
7 H 1.333333
8 I 1.333333
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.